@@ -70,10 +70,7 @@ public class Gala.WindowClone : ActorTarget, RootTarget {
7070 private Clutter . Clone ? clone = null ;
7171 private ShadowEffect ? shadow_effect = null ;
7272
73- private Clutter . Actor prev_parent = null ;
74- private int prev_index = - 1 ;
75- private float prev_x = 0.0f ;
76- private float prev_y = 0.0f ;
73+ private Clutter . Clone ? drag_handle = null ;
7774
7875 private ulong check_confirm_dialog_cb = 0 ;
7976 private bool in_slot_animation = false ;
@@ -453,22 +450,10 @@ public class Gala.WindowClone : ActorTarget, RootTarget {
453450 }
454451
455452 /**
456- * A drag action has been initiated on us, we reparent ourselves to the stage so
457- * we can move freely, scale ourselves to a smaller scale and request that the
458- * position we just freed is immediately filled by the WindowCloneContainer.
453+ * A drag action has been initiated on us, we scale ourselves to a smaller scale and
454+ * provide a clone of ourselves as drag handle so that it can move freely.
459455 */
460456 private Clutter . Actor drag_begin (float click_x, float click_y) {
461- var last_window_icon_x = window_icon. x;
462- var last_window_icon_y = window_icon. y;
463-
464- prev_parent = get_parent ();
465- prev_index = prev_parent. get_children (). index (this );
466- prev_parent. get_transformed_position (out prev_x, out prev_y);
467-
468- var stage = get_stage ();
469- prev_parent. remove_child (this );
470- stage. add_child (this );
471-
472457 active_shape. hide ();
473458
474459 var scale = window_icon. width / clone. width;
@@ -484,15 +469,8 @@ public class Gala.WindowClone : ActorTarget, RootTarget {
484469 clone. opacity = 0 ;
485470 clone. restore_easing_state ();
486471
487- request_reposition ();
488-
489472 get_transformed_position (out abs_x, out abs_y);
490473
491- set_position (abs_x, abs_y);
492-
493- // Set the last position so that it animates from there and not 0, 0
494- window_icon. set_position (last_window_icon_x, last_window_icon_y);
495-
496474 window_icon. save_easing_state ();
497475 window_icon. set_easing_duration (duration);
498476 window_icon. set_easing_mode (Clutter . AnimationMode . EASE_IN_OUT_CUBIC );
@@ -511,7 +489,13 @@ public class Gala.WindowClone : ActorTarget, RootTarget {
511489 wm. get_display (). set_cursor (Meta . Cursor . DND_IN_DRAG );
512490#endif
513491
514- return this ;
492+ drag_handle = new Clutter .Clone (this );
493+ drag_handle. set_position (abs_x, abs_y);
494+ get_stage (). add_child (drag_handle);
495+
496+ visible = false ;
497+
498+ return drag_handle;
515499 }
516500
517501 private void destination_crossed (Clutter . Actor destination, bool hovered) {
@@ -538,43 +522,36 @@ public class Gala.WindowClone : ActorTarget, RootTarget {
538522 private void drag_end (Clutter . Actor destination) {
539523 unowned var display = wm. get_display ();
540524
541- Meta . Workspace workspace = null ;
542- var primary = display. get_primary_monitor ();
543-
544525 active_shape. show ();
545526
546527 display. set_cursor (Meta . Cursor . DEFAULT );
547528
529+ bool did_move = false ;
530+
548531 if (destination is FramedBackground ) {
549- workspace = ((WorkspaceClone ) destination. get_parent ()). workspace;
532+ var primary = display. get_primary_monitor ();
533+ if (Meta . Prefs . get_workspaces_only_on_primary () && window. get_monitor () != primary) {
534+ window. move_to_monitor (primary);
535+ did_move = true ;
536+ }
537+
538+ var workspace = ((WorkspaceClone ) destination. get_parent ()). workspace;
539+ if (workspace != window. get_workspace ()) {
540+ window. change_workspace (workspace);
541+ did_move = true ;
542+ }
550543 } else if (destination is MonitorClone ) {
551544 var monitor = ((MonitorClone ) destination). monitor;
552545 if (window. get_monitor () != monitor) {
553546 window. move_to_monitor (monitor);
554- unmanaged ();
555- } else {
556- drag_canceled ();
547+ did_move = true ;
557548 }
558-
559- return ;
560549 } else if (destination is Meta . WindowActor ) {
561550 WindowDragProvider . get_instance (). notify_dropped ();
562551 }
563552
564- bool did_move = false ;
565-
566- if (Meta . Prefs . get_workspaces_only_on_primary () && ! window. is_on_primary_monitor ()) {
567- window. move_to_monitor (primary);
568- did_move = true ;
569- }
570-
571- if (workspace != null && workspace != window. get_workspace ()) {
572- window. change_workspace (workspace);
573- did_move = true ;
574- }
575-
576553 if (did_move) {
577- unmanaged ();
554+ finish_drag ();
578555 } else {
579556 // if we're dropped at the place where we came from interpret as cancel
580557 drag_canceled ();
@@ -587,15 +564,13 @@ public class Gala.WindowClone : ActorTarget, RootTarget {
587564 private void drag_canceled () {
588565 var duration = Utils . get_animation_duration (MultitaskingView . ANIMATION_DURATION );
589566
590- // Adding to the previous parent will automatically update it to take it's slot
591- // so to animate it we set the easing
592- set_position (x - prev_x, y - prev_y);
593- get_parent (). remove_child (this );
594- save_easing_state ();
595- set_easing_duration (duration);
596- set_easing_mode (Clutter . AnimationMode . EASE_OUT_QUAD );
597- prev_parent. add_child (this ); // Add above so that it is above while it animates back to its place
598- restore_easing_state ();
567+ float target_x, target_y;
568+ get_transformed_position (out target_x, out target_y);
569+ drag_handle. save_easing_state ();
570+ drag_handle. set_easing_duration (duration);
571+ drag_handle. set_easing_mode (Clutter . AnimationMode . EASE_OUT_QUAD );
572+ drag_handle. set_position (target_x, target_y);
573+ drag_handle. restore_easing_state ();
599574
600575 clone. set_pivot_point (0.0f , 0.0f );
601576 clone. save_easing_state ();
@@ -605,18 +580,25 @@ public class Gala.WindowClone : ActorTarget, RootTarget {
605580 clone. opacity = 255 ;
606581 clone. restore_easing_state ();
607582
608- request_reposition ();
609-
610583 wm. get_display (). set_cursor (Meta . Cursor . DEFAULT );
611584
612585 if (duration > 0 ) {
613586 ulong handler = 0 ;
614- handler = clone. transitions_completed. connect (() = > {
615- prev_parent. set_child_at_index (this , prev_index); // Set the correct index so that correct stacking order is kept
616- clone. disconnect (handler);
587+ handler = drag_handle. transitions_completed. connect (() = > {
588+ finish_drag ();
589+ visible = true ;
590+ drag_handle. disconnect (handler);
617591 });
618592 } else {
619- prev_parent. set_child_at_index (this , prev_index); // Set the correct index so that correct stacking order is kept
593+ finish_drag ();
594+ visible = true ;
595+ }
596+ }
597+
598+ private void finish_drag () {
599+ if (drag_handle != null ) {
600+ drag_handle. get_stage (). remove_child (drag_handle);
601+ drag_handle = null ;
620602 }
621603 }
622604
0 commit comments