generated from deepin-community/template-repository
-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
data-device: fix dnd handling during popup interactions
When a popup appears during dnd operations in wlroots-based compositors, several issues occur: 1.Drag data is lost 2.Keyboard focus changes unexpectedly 3.Other windows cannot receive drag enter events 4.Event propagation is interrupted Forwarding pointer/keyboard events from popup grab to drag grab when drag is active, preventing data loss and maintaining proper event propagation during popup interactions.
- Loading branch information
1 parent
41347e1
commit ddd7225
Showing
2 changed files
with
149 additions
and
0 deletions.
There are no files selected for viewing
148 changes: 148 additions & 0 deletions
148
debian/patches/fix-dnd-handling-during-popup-interactions.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
Author: Lu YaNing <[email protected]> | ||
Date: Fir Dec 20 10:05:24 2024 +0800 | ||
Subject: data-device: fix dnd handling during popup interactions | ||
|
||
When a popup appears during dnd operations in wlroots-based | ||
compositors, several issues occur: | ||
1.Drag data is lost | ||
2.Keyboard focus changes unexpectedly | ||
3.Other windows cannot receive drag enter events | ||
4.Event propagation is interrupted | ||
|
||
Forwarding pointer/keyboard events from popup grab to drag grab when | ||
drag is active, preventing data loss and maintaining proper event | ||
propagation during popup interactions. | ||
Upstream: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4943 | ||
|
||
--- wlroots-0.18.1.orig/types/seat/wlr_seat_pointer.c | ||
+++ wlroots-0.18.1/types/seat/wlr_seat_pointer.c | ||
@@ -4,6 +4,7 @@ | ||
#include <time.h> | ||
#include <wayland-server-core.h> | ||
#include <wlr/types/wlr_compositor.h> | ||
+#include <wlr/types/wlr_data_device.h> | ||
#include <wlr/util/log.h> | ||
#include "types/wlr_seat.h" | ||
#include "util/set.h" | ||
@@ -417,6 +418,11 @@ void wlr_seat_pointer_start_grab(struct | ||
grab->seat = wlr_seat; | ||
wlr_seat->pointer_state.grab = grab; | ||
|
||
+ // Preserve drag grab priority | ||
+ if (wlr_seat->drag && grab != &wlr_seat->drag->pointer_grab) { | ||
+ return; | ||
+ } | ||
+ | ||
wl_signal_emit_mutable(&wlr_seat->events.pointer_grab_begin, grab); | ||
} | ||
|
||
--- wlroots-0.18.1.orig/types/xdg_shell/wlr_xdg_popup.c | ||
+++ wlroots-0.18.1/types/xdg_shell/wlr_xdg_popup.c | ||
@@ -1,6 +1,7 @@ | ||
#include <assert.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
+#include <wlr/types/wlr_data_device.h> | ||
#include "types/wlr_xdg_shell.h" | ||
|
||
void handle_xdg_popup_ack_configure( | ||
@@ -52,6 +53,18 @@ static void xdg_popup_grab_end(struct wl | ||
static void xdg_pointer_grab_enter(struct wlr_seat_pointer_grab *grab, | ||
struct wlr_surface *surface, double sx, double sy) { | ||
struct wlr_xdg_popup_grab *popup_grab = grab->data; | ||
+ struct wlr_seat *seat = grab->seat; | ||
+ | ||
+ // Forward to drag grab if active | ||
+ if (seat->drag && seat->drag->pointer_grab.interface && | ||
+ seat->drag->pointer_grab.interface->enter) { | ||
+ if (grab != &seat->drag->pointer_grab) { | ||
+ seat->drag->pointer_grab.interface->enter(&seat->drag->pointer_grab, | ||
+ surface, sx, sy); | ||
+ } | ||
+ return; | ||
+ } | ||
+ | ||
if (wl_resource_get_client(surface->resource) == popup_grab->client) { | ||
wlr_seat_pointer_enter(grab->seat, surface, sx, sy); | ||
} else { | ||
@@ -65,13 +78,33 @@ static void xdg_pointer_grab_clear_focus | ||
|
||
static void xdg_pointer_grab_motion(struct wlr_seat_pointer_grab *grab, | ||
uint32_t time, double sx, double sy) { | ||
+ struct wlr_seat *seat = grab->seat; | ||
+ | ||
+ if (seat->drag && seat->drag->pointer_grab.interface && | ||
+ seat->drag->pointer_grab.interface->motion) { | ||
+ if (grab != &seat->drag->pointer_grab) { | ||
+ seat->drag->pointer_grab.interface->motion(&seat->drag->pointer_grab, | ||
+ time, sx, sy); | ||
+ } | ||
+ return; | ||
+ } | ||
+ | ||
wlr_seat_pointer_send_motion(grab->seat, time, sx, sy); | ||
} | ||
|
||
static uint32_t xdg_pointer_grab_button(struct wlr_seat_pointer_grab *grab, | ||
uint32_t time, uint32_t button, uint32_t state) { | ||
- uint32_t serial = | ||
- wlr_seat_pointer_send_button(grab->seat, time, button, state); | ||
+ struct wlr_seat *seat = grab->seat; | ||
+ | ||
+ if (seat->drag && seat->drag->pointer_grab.interface && | ||
+ seat->drag->pointer_grab.interface->button) { | ||
+ if (grab != &seat->drag->pointer_grab) { | ||
+ return seat->drag->pointer_grab.interface->button(&seat->drag->pointer_grab, | ||
+ time, button, state); | ||
+ } | ||
+ } | ||
+ | ||
+ uint32_t serial = wlr_seat_pointer_send_button(grab->seat, time, button, state); | ||
if (serial) { | ||
return serial; | ||
} else { | ||
@@ -84,11 +117,32 @@ static void xdg_pointer_grab_axis(struct | ||
uint32_t time, enum wl_pointer_axis orientation, double value, | ||
int32_t value_discrete, enum wl_pointer_axis_source source, | ||
enum wl_pointer_axis_relative_direction relative_direction) { | ||
+ struct wlr_seat *seat = grab->seat; | ||
+ | ||
+ if (seat->drag && seat->drag->pointer_grab.interface && | ||
+ seat->drag->pointer_grab.interface->axis) { | ||
+ if (grab != &seat->drag->pointer_grab) { | ||
+ seat->drag->pointer_grab.interface->axis(&seat->drag->pointer_grab, | ||
+ time, orientation, value, value_discrete, source, relative_direction); | ||
+ } | ||
+ return; | ||
+ } | ||
+ | ||
wlr_seat_pointer_send_axis(grab->seat, time, orientation, value, | ||
value_discrete, source, relative_direction); | ||
} | ||
|
||
static void xdg_pointer_grab_frame(struct wlr_seat_pointer_grab *grab) { | ||
+ struct wlr_seat *seat = grab->seat; | ||
+ | ||
+ if (seat->drag && seat->drag->pointer_grab.interface && | ||
+ seat->drag->pointer_grab.interface->frame) { | ||
+ if (grab != &seat->drag->pointer_grab) { | ||
+ seat->drag->pointer_grab.interface->frame(&seat->drag->pointer_grab); | ||
+ } | ||
+ return; | ||
+ } | ||
+ | ||
wlr_seat_pointer_send_frame(grab->seat); | ||
} | ||
|
||
@@ -110,6 +164,11 @@ static void xdg_keyboard_grab_enter(stru | ||
struct wlr_surface *surface, const uint32_t keycodes[], size_t num_keycodes, | ||
const struct wlr_keyboard_modifiers *modifiers) { | ||
// keyboard focus should remain on the popup | ||
+ if (grab->seat->drag) { | ||
+ return; | ||
+ } | ||
+ | ||
+ wlr_seat_keyboard_enter(grab->seat, surface, keycodes, num_keycodes, modifiers); | ||
} | ||
|
||
static void xdg_keyboard_grab_clear_focus(struct wlr_seat_keyboard_grab *grab) { |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
Revert-layer-shell-error-on-0-dimension-without-anchors.patch | ||
fix-dnd-handling-during-popup-interactions.patch |