Skip to content

Commit

Permalink
#772: emulate _NET_WM_MOVERESIZE on non-X11 platforms, handles only M…
Browse files Browse the repository at this point in the history
…OVERESIZE_MOVE for now - can be tested on X11 with the env var XPRA_MOVERESIZE_X11=0

git-svn-id: https://xpra.org/svn/Xpra/trunk@13720 3bb7dfac-3a0b-4e04-842a-767bc560f471
  • Loading branch information
totaam committed Sep 14, 2016
1 parent bf6aca3 commit 4e3395f
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/xpra/client/gtk_base/gtk_client_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ def make_hello(self):
capabilities["metadata.supported"] = ms
#we need the bindings to support initiate-moveresize (posix only for now):
updict(capabilities, "window", {
"initiate-moveresize" : HAS_X11_BINDINGS,
"initiate-moveresize" : True,
"configure.pointer" : True,
"frame_sizes" : self.get_window_frame_sizes()
})
Expand Down
60 changes: 54 additions & 6 deletions src/xpra/client/gtk_base/gtk_client_window_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@


from xpra.os_util import memoryview_to_bytes, bytestostr
from xpra.util import AdHocStruct, typedict, envint, WORKSPACE_UNSET, WORKSPACE_ALL, WORKSPACE_NAMES, MOVERESIZE_DIRECTION_STRING, SOURCE_INDICATION_STRING
from xpra.util import AdHocStruct, typedict, envint, WORKSPACE_UNSET, WORKSPACE_ALL, WORKSPACE_NAMES, MOVERESIZE_DIRECTION_STRING, MOVERESIZE_CANCEL, MOVERESIZE_MOVE, SOURCE_INDICATION_STRING
from xpra.gtk_common.gobject_compat import import_gtk, import_gdk, import_cairo, import_pixbufloader, get_xid
from xpra.gtk_common.gobject_util import no_arg_signal
from xpra.gtk_common.gtk_util import get_pixbuf_from_data, get_default_root_window, is_realized, WINDOW_POPUP, WINDOW_TOPLEVEL, GRAB_STATUS_STRING, GRAB_SUCCESS
Expand Down Expand Up @@ -68,6 +68,9 @@
pass


BREAK_MOVERESIZE = os.environ.get("XPRA_BREAK_MOVERESIZE", "Escape").split(",")
MOVERESIZE_X11 = envint("XPRA_MOVERESIZE_X11", os.name=="posix")

SAVE_WINDOW_ICONS = envint("XPRA_SAVE_WINDOW_ICONS")
UNDECORATED_TRANSIENT_IS_OR = envint("XPRA_UNDECORATED_TRANSIENT_IS_OR", 1)
LAZY_SHAPE = envint("XPRA_LAZY_SHAPE", 1)
Expand Down Expand Up @@ -145,6 +148,8 @@ def init_window(self, metadata):
self._current_frame_extents = None
self._screen = -1
self._frozen = False
self.moveresize_timer = None
self.moveresize_event = None
self.OR_offset = None
#add platform hooks
self.on_realize_cb = {}
Expand Down Expand Up @@ -904,9 +909,45 @@ def call_action(self, action_type, action, state, pdata):
except Exception as e:
log.error("Error: failed to send %s menu rpc request for %s", action_type, action, exc_info=True)

def do_motion_notify_event(self, event):
if self.moveresize_event:
x_root, y_root, direction, button, wx, wy, ww, wh = self.moveresize_event
buttons = self._event_buttons(event)
if direction==MOVERESIZE_MOVE and button==0 or button in buttons:
x = event.x_root
y = event.y_root
dx = x-x_root
dy = y-y_root
geomlog("motion moveresize for window %ix%i: started at %s, now at %s, delta=%s, button=%s, buttons=%s", ww, wh, (x_root, y_root), (x, y), (dx, dy), button, buttons)
self.moveresize_data = int(wx+dx), int(wy+dy)
#moving the window is slower than moving the pointer,
#do it via a timer to batch things together
if self.moveresize_timer is None:
self.moveresize_timer = self.timeout_add(20, self.do_moveresize)
else:
self.moveresize_event = None
ClientWindowBase.do_motion_notify_event(self, event)

def do_moveresize(self):
self.moveresize_timer = None
self.move(*self.moveresize_data)


def initiate_moveresize(self, x_root, y_root, direction, button, source_indication):
statelog("initiate_moveresize%s", (x_root, y_root, MOVERESIZE_DIRECTION_STRING.get(direction, direction), button, SOURCE_INDICATION_STRING.get(source_indication, source_indication)))
assert HAS_X11_BINDINGS, "cannot handle initiate-moveresize without X11 bindings"
if MOVERESIZE_X11 and HAS_X11_BINDINGS:
self.initiate_moveresize_X11(x_root, y_root, direction, button, source_indication)
return
if direction==MOVERESIZE_CANCEL:
self.moveresize_event = None
else:
#use window coordinates (which include decorations)
wx, wy = self.get_window().get_root_origin()
ww, wh = self.get_window().get_size()
self.moveresize_event = (x_root, y_root, direction, button, wx, wy, ww, wh)

def initiate_moveresize_X11(self, x_root, y_root, direction, button, source_indication):
statelog("initiate_moveresize_X11%s", (x_root, y_root, MOVERESIZE_DIRECTION_STRING.get(direction, direction), button, SOURCE_INDICATION_STRING.get(source_indication, source_indication)))
event_mask = SubstructureNotifyMask | SubstructureRedirectMask
root = self.get_window().get_screen().get_root_window()
root_xid = get_xid(root)
Expand Down Expand Up @@ -1154,6 +1195,10 @@ def noop_destroy(self):
def destroy(self):
if self._client._set_window_menu:
self._client.set_window_menu(False, self._id, {})
mrt = self.moveresize_timer
if mrt:
self.moveresize_timer = None
self.source_remove(mrt)
self.on_realize_cb = {}
ClientWindowBase.destroy(self)
gtk.Window.destroy(self)
Expand Down Expand Up @@ -1181,14 +1226,14 @@ def _pointer_modifiers(self, event):
y -= self.OR_offset[1]
pointer = self._client.cp(x, y)
modifiers = self._client.mask_to_names(event.state)
buttons = []
for mask, button in self.BUTTON_MASK.items():
if event.state & mask:
buttons.append(button)
buttons = self._event_buttons(event)
v = pointer, modifiers, buttons
mouselog("pointer_modifiers(%s)=%s", event, v)
return v

def _event_buttons(self, event):
return [button for mask, button in self.BUTTON_MASK.items() if (event.state & mask)]

def parse_key_event(self, event, pressed):
keyval = event.keyval
keycode = event.hardware_keycode
Expand All @@ -1207,6 +1252,9 @@ def parse_key_event(self, event, pressed):

def do_key_press_event(self, event):
key_event = self.parse_key_event(event, True)
if self.moveresize_event and key_event.key_name in BREAK_MOVERESIZE:
#cancel move resize if there is one:
self.moveresize_event = None
self._client.handle_key_action(self, key_event)

def do_key_release_event(self, event):
Expand Down

0 comments on commit 4e3395f

Please sign in to comment.