Skip to content

Commit 8b251d3

Browse files
committed
KeybindingWidgets.py: Fix keybinding teaching in wayland sessions.
Device grabs require a GdkSeat in wayland, not GdkDevice. GdkSeat path seems to work fine for both session types but for now let's detect the session and keep what we know works for x11.
1 parent ee43cc4 commit 8b251d3

1 file changed

Lines changed: 39 additions & 9 deletions

File tree

files/usr/share/cinnamon/cinnamon-settings/bin/KeybindingWidgets.py

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#!/usr/bin/python3
22

33
from gi.repository import Gtk, Gdk, GObject
4+
import util
5+
6+
print("KeybindingWidgets session type: %s" % util.get_session_type())
47

58
FORBIDDEN_KEYVALS = [
69
Gdk.KEY_Home,
@@ -170,6 +173,8 @@ def __init__(self, a_widget, accel_string=None):
170173
self.teaching = False
171174
self.default_value = True
172175
self.text_string = ""
176+
self.seat = None
177+
self.keyboard = None
173178

174179
self.update_label()
175180

@@ -222,15 +227,33 @@ def set_value(self, accel_string=None):
222227
def editing_started(self, renderer, editable, path):
223228
if not self.teaching:
224229
self.path = path
225-
device = Gtk.get_current_event_device()
226-
if device.get_source() == Gdk.InputSource.KEYBOARD:
227-
self.keyboard = device
228-
else:
229-
self.keyboard = device.get_associated_device()
230230

231-
self.keyboard.grab(self.a_widget.get_window(), Gdk.GrabOwnership.WINDOW, False,
232-
Gdk.EventMask.KEY_PRESS_MASK | Gdk.EventMask.KEY_RELEASE_MASK,
233-
None, Gdk.CURRENT_TIME)
231+
if util.get_session_type() == "x11":
232+
device = Gtk.get_current_event_device()
233+
if device.get_source() == Gdk.InputSource.KEYBOARD:
234+
self.keyboard = device
235+
else:
236+
self.keyboard = device.get_associated_device()
237+
238+
self.keyboard.grab(self.a_widget.get_window(), Gdk.GrabOwnership.WINDOW, False,
239+
Gdk.EventMask.KEY_PRESS_MASK | Gdk.EventMask.KEY_RELEASE_MASK,
240+
None, Gdk.CURRENT_TIME)
241+
else:
242+
display = self.a_widget.get_display()
243+
self.seat = display.get_default_seat()
244+
245+
# Grab both keyboard and pointer to prevent mouse events from canceling the operation
246+
grab_status = self.seat.grab(
247+
self.a_widget.get_window(),
248+
Gdk.SeatCapabilities.KEYBOARD | Gdk.SeatCapabilities.POINTER,
249+
False,
250+
None,
251+
None,
252+
None
253+
)
254+
255+
if grab_status != Gdk.GrabStatus.SUCCESS:
256+
print(f"Warning: Keyboard grab failed with status: {grab_status}")
234257

235258
editable.set_text(CellRendererKeybinding.PICK_AN_ACCELERATOR)
236259
self.accel_editable = editable
@@ -356,7 +379,14 @@ def on_key_release(self, widget, event):
356379
return True
357380

358381
def ungrab(self):
359-
self.keyboard.ungrab(Gdk.CURRENT_TIME)
382+
if util.get_session_type() == "x11":
383+
if self.keyboard is not None:
384+
self.keyboard.ungrab(Gdk.CURRENT_TIME)
385+
self.keyboard = None
386+
else:
387+
if self.seat is not None:
388+
self.seat.ungrab()
389+
self.seat = None
360390
if self.release_event_id > 0:
361391
self.accel_editable.disconnect(self.release_event_id)
362392
self.release_event_id = 0

0 commit comments

Comments
 (0)