mirror of
https://github.com/elementary/gala.git
synced 2024-11-27 15:45:31 +03:00
DnD: Stop using captured_event in Mutter 42 (#1468)
This commit is contained in:
parent
a12c1a1c47
commit
47c4e8346b
@ -103,6 +103,13 @@ namespace Gala {
|
||||
float last_x;
|
||||
float last_y;
|
||||
|
||||
#if HAS_MUTTER42
|
||||
Grab? grab = null;
|
||||
static unowned Actor? grabbed_actor = null;
|
||||
InputDevice? grabbed_device = null;
|
||||
ulong on_event_id = 0;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Create a new DragDropAction
|
||||
*
|
||||
@ -141,7 +148,9 @@ namespace Gala {
|
||||
|
||||
void release_actor (Actor actor) {
|
||||
if (DragDropActionType.SOURCE in drag_type) {
|
||||
#if !HAS_MUTTER42
|
||||
actor.button_press_event.disconnect (source_clicked);
|
||||
#endif
|
||||
|
||||
var source_list = sources.@get (drag_id);
|
||||
source_list.remove (actor);
|
||||
@ -155,7 +164,9 @@ namespace Gala {
|
||||
|
||||
void connect_actor (Actor actor) {
|
||||
if (DragDropActionType.SOURCE in drag_type) {
|
||||
#if !HAS_MUTTER42
|
||||
actor.button_press_event.connect (source_clicked);
|
||||
#endif
|
||||
|
||||
var source_list = sources.@get (drag_id);
|
||||
if (source_list == null) {
|
||||
@ -182,6 +193,190 @@ namespace Gala {
|
||||
destination_crossed (destination, is_hovered);
|
||||
}
|
||||
|
||||
#if HAS_MUTTER42
|
||||
public override bool handle_event (Event event) {
|
||||
switch (event.get_type ()) {
|
||||
case EventType.BUTTON_PRESS:
|
||||
if (event.get_button () != 1) {
|
||||
actor_clicked (event.get_button ());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (grabbed_actor != null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
grab_actor (actor, event.get_device ());
|
||||
clicked = true;
|
||||
|
||||
float x, y;
|
||||
event.get_coords (out x, out y);
|
||||
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
|
||||
return true;
|
||||
|
||||
case EventType.BUTTON_RELEASE:
|
||||
if (!dragging) {
|
||||
float x, y, ex, ey;
|
||||
event.get_coords (out ex, out ey);
|
||||
actor.get_transformed_position (out x, out y);
|
||||
|
||||
// release has happened within bounds of actor
|
||||
if (x < ex && x + actor.width > ex && y < ey && y + actor.height > ey) {
|
||||
actor_clicked (event.get_button ());
|
||||
}
|
||||
|
||||
ungrab_actor ();
|
||||
clicked = false;
|
||||
dragging = false;
|
||||
return true;
|
||||
} else if (dragging) {
|
||||
if (hovered != null) {
|
||||
finish ();
|
||||
} else {
|
||||
cancel ();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return base.handle_event (event);
|
||||
}
|
||||
|
||||
void grab_actor (Actor actor, InputDevice device) {
|
||||
if (grabbed_actor != null) {
|
||||
critical ("Tried to grab an actor with a grab already in progress");
|
||||
}
|
||||
|
||||
grab = actor.get_stage ().grab (actor);
|
||||
grabbed_actor = actor;
|
||||
grabbed_device = device;
|
||||
on_event_id = actor.event.connect (on_event);
|
||||
}
|
||||
|
||||
void ungrab_actor () {
|
||||
if (on_event_id == 0 || grabbed_actor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (grab != null) {
|
||||
grab.dismiss ();
|
||||
grab = null;
|
||||
}
|
||||
|
||||
grabbed_device = null;
|
||||
grabbed_actor.disconnect (on_event_id);
|
||||
on_event_id = 0;
|
||||
grabbed_actor = null;
|
||||
}
|
||||
|
||||
bool on_event (Clutter.Event event) {
|
||||
var device = event.get_device ();
|
||||
|
||||
if (grabbed_device != null &&
|
||||
device != grabbed_device &&
|
||||
device.get_device_type () != InputDeviceType.KEYBOARD_DEVICE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (event.get_type ()) {
|
||||
case EventType.KEY_PRESS:
|
||||
if (event.get_key_symbol () == Key.Escape) {
|
||||
cancel ();
|
||||
}
|
||||
break;
|
||||
case EventType.MOTION:
|
||||
float x, y;
|
||||
event.get_coords (out x, out y);
|
||||
|
||||
if (!dragging && clicked) {
|
||||
var drag_threshold = Clutter.Settings.get_default ().dnd_drag_threshold;
|
||||
if (Math.fabsf (last_x - x) > drag_threshold || Math.fabsf (last_y - y) > drag_threshold) {
|
||||
handle = drag_begin (x, y);
|
||||
if (handle == null) {
|
||||
ungrab_actor ();
|
||||
critical ("No handle has been returned by the started signal, aborting drag.");
|
||||
return false;
|
||||
}
|
||||
|
||||
clicked = false;
|
||||
dragging = true;
|
||||
|
||||
ungrab_actor ();
|
||||
grab_actor (handle, event.get_device ());
|
||||
|
||||
handle.reactive = false;
|
||||
|
||||
var source_list = sources.@get (drag_id);
|
||||
if (source_list != null) {
|
||||
var dest_list = destinations[drag_id];
|
||||
foreach (var actor in source_list) {
|
||||
// Do not unset reactivity on destinations
|
||||
if (dest_list == null || actor in dest_list) {
|
||||
continue;
|
||||
}
|
||||
|
||||
actor.reactive = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else if (dragging) {
|
||||
handle.x -= last_x - x;
|
||||
handle.y -= last_y - y;
|
||||
last_x = x;
|
||||
last_y = y;
|
||||
|
||||
var stage = actor.get_stage ();
|
||||
var actor = stage.get_actor_at_pos (PickMode.REACTIVE, (int) x, (int) y);
|
||||
DragDropAction action = null;
|
||||
// if we're allowed to bubble and this actor is not a destination, check its parents
|
||||
if (actor != null && (action = get_drag_drop_action (actor)) == null && allow_bubbling) {
|
||||
while ((actor = actor.get_parent ()) != stage) {
|
||||
if ((action = get_drag_drop_action (actor)) != null)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// didn't change, no need to do anything
|
||||
if (actor == hovered)
|
||||
return true;
|
||||
|
||||
if (action == null) {
|
||||
// apparently we left ours if we had one before
|
||||
if (hovered != null) {
|
||||
emit_crossed (hovered, false);
|
||||
hovered = null;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// signal the previous one that we left it
|
||||
if (hovered != null) {
|
||||
emit_crossed (hovered, false);
|
||||
}
|
||||
|
||||
// tell the new one that it is hovered
|
||||
hovered = actor;
|
||||
emit_crossed (hovered, true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
#else
|
||||
bool source_clicked (ButtonEvent event) {
|
||||
if (event.button != 1) {
|
||||
actor_clicked (event.button);
|
||||
@ -314,6 +509,7 @@ namespace Gala {
|
||||
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Looks for a DragDropAction instance if this actor has one or NULL.
|
||||
@ -382,8 +578,13 @@ namespace Gala {
|
||||
}
|
||||
}
|
||||
|
||||
if (dragging)
|
||||
if (dragging) {
|
||||
#if HAS_MUTTER42
|
||||
ungrab_actor ();
|
||||
#else
|
||||
actor.get_stage ().captured_event.disconnect (follow_move);
|
||||
#endif
|
||||
}
|
||||
|
||||
dragging = false;
|
||||
}
|
||||
|
@ -464,6 +464,10 @@ public class Gala.WindowClone : Clutter.Actor {
|
||||
}
|
||||
|
||||
public override bool enter_event (Clutter.CrossingEvent event) {
|
||||
if (drag_action.dragging) {
|
||||
return false;
|
||||
}
|
||||
|
||||
close_button.opacity = in_slot_animation ? 0 : 255;
|
||||
window_title.opacity = in_slot_animation ? 0 : 255;
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user