Skip to content

Commit

Permalink
add "force-ungrab" packet and capability so we can ask the server to …
Browse files Browse the repository at this point in the history
…ungrab without having to fake a key (was "Escape" by default) - keep the old fake key code for older servers

git-svn-id: https://xpra.org/svn/Xpra/trunk@6120 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Apr 19, 2014
1 parent 9e44f30 commit faec633
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 4 deletions.
5 changes: 5 additions & 0 deletions src/xpra/client/ui_client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ def __init__(self):
self.opengl_props = {}
self.toggle_cursors_bell_notify = False
self.toggle_keyboard_sync = False
self.force_ungrab = False
self.window_unmap = False
self.window_refresh_config = False
self.server_generic_encodings = False
Expand Down Expand Up @@ -1059,6 +1060,7 @@ def parse_server_capabilities(self, c):
self.session_name = c.strget("session_name", "")
set_application_name(self.session_name or "Xpra")
self.window_unmap = c.boolget("window_unmap")
self.force_ungrab = c.boolget("force_ungrab")
self.window_refresh_config = c.boolget("window_refresh_config")
self.suspend_resume = c.boolget("suspend-resume")
self.server_supports_notifications = c.boolget("notifications")
Expand Down Expand Up @@ -1521,6 +1523,9 @@ def send_cursors_enabled(self):
assert self.toggle_cursors_bell_notify, "cannot toggle cursors: server lacks the feature"
self.send("set-cursors", self.cursors_enabled)

def send_force_ungrab(self, wid):
assert self.force_ungrab
self.send("force-ungrab", wid)

def set_deflate_level(self, level):
self.compression_level = level
Expand Down
15 changes: 11 additions & 4 deletions src/xpra/platform/win32/gui.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import os
from xpra.log import Logger
log = Logger("win32")
grablog = Logger("win32", "grab")

from xpra.platform.win32.win32_events import get_win32_event_listener
from xpra.util import AdHocStruct
Expand Down Expand Up @@ -80,7 +81,7 @@ def activateapp(self, wParam, lParam):
if wParam==0 and self.client:
#our app has lost focus
wid = self.client.window_with_grab
log("window with grab=%s, UNGRAB_KEY=%s", wid, UNGRAB_KEY)
grablog("window with grab=%s, UNGRAB_KEY=%s", wid, UNGRAB_KEY)
if wid is not None and UNGRAB_KEY:
self.force_ungrab(wid)

Expand All @@ -95,22 +96,28 @@ def power_broadcast_event(self, wParam, lParam):
self.client.resume()

def force_ungrab(self, wid):
grablog("force_ungrab(%s) server supports force ungrab: %s", wid, self.client.force_ungrab)
if self.client.force_ungrab:
#ungrab via dedicated server packet:
self.client.send_force_ungrab(wid)
return
#fallback: try to find a key to press:
kh = self.client.keyboard_helper
if not kh:
if not self._kh_warning:
self._kh_warning = True
log.warn("no keyboard support, cannot simulate keypress to lose grab!")
grablog.warn("no keyboard support, cannot simulate keypress to lose grab!")
return
#xkbmap_keycodes is a list of: (keyval, name, keycode, group, level)
ungrab_keys = [x for x in kh.xkbmap_keycodes if x[1]==UNGRAB_KEY]
if len(ungrab_keys)==0:
if not self._kh_warning:
self._kh_warning = True
log.warn("ungrab key %s not found, cannot simulate keypress to lose grab!", UNGRAB_KEY)
grablog.warn("ungrab key %s not found, cannot simulate keypress to lose grab!", UNGRAB_KEY)
return
#ungrab_keys.append((65307, "Escape", 27, 0, 0)) #ugly hardcoded default value
ungrab_key = ungrab_keys[0]
log("lost focus whilst window %s has grab, simulating keypress: %s", wid, ungrab_key)
grablog("lost focus whilst window %s has grab, simulating keypress: %s", wid, ungrab_key)
key_event = AdHocStruct()
key_event.keyname = ungrab_key[1]
key_event.pressed = True
Expand Down
12 changes: 12 additions & 0 deletions src/xpra/x11/bindings/core_bindings.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ from xpra.log import Logger
log = Logger("x11", "bindings", "core")


include "constants.pxi"

###################################
# Headers, python magic
###################################
Expand All @@ -36,6 +38,7 @@ cdef extern from "X11/Xlib.h":
# over and over again, here are some convenience typedefs. (Yes, CARD32
# really is 64 bits on 64-bit systems. Why? I have no idea.)
ctypedef CARD32 XID
ctypedef CARD32 Time

ctypedef int Bool
ctypedef int Status
Expand All @@ -47,6 +50,9 @@ cdef extern from "X11/Xlib.h":

void XGetErrorText(Display * display, int code, char * buffer_return, int length)

int XUngrabKeyboard(Display * display, Time time)
int XUngrabPointer(Display * display, Time time)


from display_source cimport get_display
from display_source import get_display_name
Expand Down Expand Up @@ -77,3 +83,9 @@ cdef class X11CoreBindings:
cdef char[128] buffer
XGetErrorText(self.display, code, buffer, 128)
return str(buffer[:128])

def UngrabKeyboard(self, time=CurrentTime):
return XUngrabKeyboard(self.display, time)

def UngrabPointer(self, time=CurrentTime):
return XUngrabPointer(self.display, time)
14 changes: 14 additions & 0 deletions src/xpra/x11/x11_server_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@ def init_keyboard(self):
clean_keyboard_state()


def init_packet_handlers(self):
GTKServerBase.init_packet_handlers(self)
self._authenticated_ui_packet_handlers["force-ungrab"] = self._process_force_ungrab


def get_uuid(self):
return get_uuid()

Expand All @@ -139,6 +144,7 @@ def set_keyboard_repeat(self, key_repeat):
def make_hello(self):
capabilities = GTKServerBase.make_hello(self)
capabilities["resize_screen"] = self.randr
capabilities["force_ungrab"] = True
return capabilities

def do_get_info(self, proto, server_sources, window_ids):
Expand Down Expand Up @@ -425,6 +431,14 @@ def update_server_settings(self, settings, reset=False):
log("ignoring server settings update in %s", self)


def _process_force_ungrab(self, proto, packet):
#ignore the window id: wid = packet[1]
def X11_ungrab():
X11Core.UngrabKeyboard()
X11Core.UngrabPointer()
trap.call_synced(X11_ungrab)


def fake_key(self, keycode, press):
keylog("fake_key(%s, %s)", keycode, press)
trap.call_synced(X11Keyboard.xtest_fake_key, keycode, press)
Expand Down

0 comments on commit faec633

Please sign in to comment.