def send(): from xpra.gtk_common.gobject_compat import get_xid root_xid = get_xid(root) xwin = get_xid(self.gdk_window()) X11Window.sendClientMessage(root_xid, xwin, False, event_mask, "_NET_WM_DESKTOP", workspace, CurrentTime, 0, 0, 0)
def wm_moveresize(): from xpra.gtk_common.gobject_compat import get_xid root = self.get_window().get_screen().get_root_window() root_xid = get_xid(root) xwin = get_xid(self.get_window()) X11Core.UngrabPointer() X11Window.sendClientMessage(root_xid, xwin, False, event_mask, "_NET_WM_MOVERESIZE", x_root, y_root, direction, button, source_indication)
def initiate_moveresize(self, x_root, y_root, direction, button, source_indication): statelog("initiate_moveresize%s", (x_root, y_root, direction, button, source_indication)) assert HAS_X11_BINDINGS, "cannot handle initiate-moveresize without X11 bindings" event_mask = SubstructureNotifyMask | SubstructureRedirectMask root = self.get_window().get_screen().get_root_window() root_xid = get_xid(root) xwin = get_xid(self.get_window()) with xsync: X11Core.UngrabPointer() X11Window.sendClientMessage(root_xid, xwin, False, event_mask, "_NET_WM_MOVERESIZE", x_root, y_root, direction, button, source_indication)
def send_maximized_wm_state(mode): from xpra.x11.gtk2 import gdk_display_source assert gdk_display_source from xpra.gtk_common.gobject_compat import get_xid from xpra.x11.bindings.window_bindings import constants, X11WindowBindings #@UnresolvedImport X11Window = X11WindowBindings() root = window.get_window().get_screen().get_root_window() root_xid = get_xid(root) xwin = get_xid(window.get_window()) SubstructureNotifyMask = constants["SubstructureNotifyMask"] SubstructureRedirectMask = constants["SubstructureRedirectMask"] event_mask = SubstructureNotifyMask | SubstructureRedirectMask X11Window.sendClientMessage(root_xid, xwin, False, event_mask, "_NET_WM_STATE", mode, "_NET_WM_STATE_MAXIMIZED_VERT", "_NET_WM_STATE_MAXIMIZED_HORZ", 0, 0)
def close(*args): from xpra.x11.gtk2 import gdk_display_source assert gdk_display_source from xpra.gtk_common.gobject_compat import get_xid from xpra.x11.bindings.window_bindings import constants, X11WindowBindings #@UnresolvedImport X11Window = X11WindowBindings() root = window.get_window().get_screen().get_root_window() root_xid = get_xid(root) xwin = get_xid(window.get_window()) SubstructureNotifyMask = constants["SubstructureNotifyMask"] SubstructureRedirectMask = constants["SubstructureRedirectMask"] event_mask = SubstructureNotifyMask | SubstructureRedirectMask now = gtk.gdk.x11_get_server_time(window.get_window()) X11Window.sendClientMessage(root_xid, xwin, False, event_mask, "_NET_CLOSE_WINDOW", now, 1)
def moveresize_X11(*args): new_x, new_y, new_width, new_height = get_new_geometry() from xpra.x11.gtk_x11 import gdk_display_source assert gdk_display_source from xpra.gtk_common.gobject_compat import get_xid from xpra.x11.bindings.window_bindings import constants, X11WindowBindings #@UnresolvedImport X11Window = X11WindowBindings() root = window.get_window().get_screen().get_root_window() root_xid = get_xid(root) xwin = get_xid(window.get_window()) SubstructureNotifyMask = constants["SubstructureNotifyMask"] SubstructureRedirectMask = constants["SubstructureRedirectMask"] event_mask = SubstructureNotifyMask | SubstructureRedirectMask X11Window.sendClientMessage(root_xid, xwin, False, event_mask, "_NET_MOVERESIZE_WINDOW", 1+2**8+2**9+2**10+2**11, new_x, new_y, new_width, new_height)
def send_maximized_wm_state(mode): from xpra.x11.gtk2 import gdk_display_source assert gdk_display_source from xpra.x11.bindings.window_bindings import constants, X11WindowBindings #@UnresolvedImport X11Window = X11WindowBindings() root = window.get_window().get_screen().get_root_window() root_xid = get_xid(root) xwin = get_xid(window.get_window()) SubstructureNotifyMask = constants["SubstructureNotifyMask"] SubstructureRedirectMask = constants["SubstructureRedirectMask"] event_mask = SubstructureNotifyMask | SubstructureRedirectMask X11Window.sendClientMessage(root_xid, xwin, False, event_mask, "_NET_WM_STATE", mode, "_NET_WM_STATE_MAXIMIZED_VERT", "_NET_WM_STATE_MAXIMIZED_HORZ", 0, 0)
def initiate(x_root, y_root, direction, button, source_indication): print("initiate%s" % str((x_root, y_root, direction, button, source_indication))) from xpra.x11.gtk2 import gdk_display_source assert gdk_display_source from xpra.x11.bindings.core_bindings import X11CoreBindings #@UnresolvedImport from xpra.x11.bindings.window_bindings import constants, X11WindowBindings #@UnresolvedImport event_mask = constants["SubstructureNotifyMask"] | constants["SubstructureRedirectMask"] from xpra.gtk_common.gobject_compat import get_xid root_xid = get_xid(root) xwin = get_xid(window.get_window()) X11Core = X11CoreBindings() X11Core.UngrabPointer() X11Window = X11WindowBindings() X11Window.sendClientMessage(root_xid, xwin, False, event_mask, "_NET_WM_MOVERESIZE", x_root, y_root, direction, button, source_indication)
def close(*args): from xpra.x11.gtk_x11 import gdk_display_source assert gdk_display_source from xpra.gtk_common.gobject_compat import get_xid from xpra.x11.bindings.window_bindings import constants, X11WindowBindings #@UnresolvedImport X11Window = X11WindowBindings() root = window.get_window().get_screen().get_root_window() root_xid = get_xid(root) xwin = get_xid(window.get_window()) SubstructureNotifyMask = constants["SubstructureNotifyMask"] SubstructureRedirectMask = constants["SubstructureRedirectMask"] event_mask = SubstructureNotifyMask | SubstructureRedirectMask now = gtk.gdk.x11_get_server_time(window.get_window()) X11Window.sendClientMessage(root_xid, xwin, False, event_mask, "_NET_CLOSE_WINDOW", now, 1)
def initiate_moveresize(self, x_root, y_root, direction, button, source_indication): statelog("initiate_moveresize%s", (x_root, y_root, direction, button, source_indication)) assert HAS_X11_BINDINGS, "cannot handle initiate-moveresize without X11 bindings" event_mask = SubstructureNotifyMask | SubstructureRedirectMask with xsync: from xpra.gtk_common.gobject_compat import get_xid root = self.get_window().get_screen().get_root_window() root_xid = get_xid(root) xwin = get_xid(self.get_window()) X11Core.UngrabPointer() X11Window.sendClientMessage(root_xid, xwin, False, event_mask, "_NET_WM_MOVERESIZE", x_root, y_root, direction, button, source_indication)
def x11_bell(): global device_bell if device_bell is None: #try to load it: from xpra.x11.bindings.keyboard_bindings import X11KeyboardBindings #@UnresolvedImport device_bell = X11KeyboardBindings().device_bell device_bell(get_xid(window), device, bell_class, bell_id, percent, bell_name)
def moveresize_X11(self, *args): new_x, new_y, new_width, new_height = self.get_new_geometry() from xpra.x11.gtk2 import gdk_display_source assert gdk_display_source from xpra.gtk_common.gobject_compat import get_xid from xpra.x11.bindings.window_bindings import constants, X11WindowBindings #@UnresolvedImport X11Window = X11WindowBindings() root = self.get_window().get_screen().get_root_window() root_xid = get_xid(root) xwin = get_xid(self.get_window()) SubstructureNotifyMask = constants["SubstructureNotifyMask"] SubstructureRedirectMask = constants["SubstructureRedirectMask"] event_mask = SubstructureNotifyMask | SubstructureRedirectMask X11Window.sendClientMessage(root_xid, xwin, False, event_mask, "_NET_MOVERESIZE_WINDOW", 1 + 2**8 + 2**9 + 2**10 + 2**11, new_x, new_y, new_width, new_height)
def __init__(self): self.window = gtk.Window() self.window.connect("destroy", self.destroy) self.window.set_default_size(640, 300) self.window.set_border_width(20) self.window.set_title("Clipboard Test Tool") vbox = gtk.VBox(False, 0) vbox.set_spacing(15) self.log = deque(maxlen=25) for x in range(25): self.log.append("") self.events = gtk.Label() fixed = pango.FontDescription('monospace 9') self.events.modify_font(fixed) #how many clipboards to show: self.clipboards = CLIPBOARDS tb = TableBuilder() table = tb.get_table() labels = [label("Selection")] labels += [ label("Value"), label("Clear"), label("Targets"), label("Actions") ] tb.add_row(*labels) for selection in self.clipboards: cs = ClipboardInstance(selection, self.add_event) get_actions = gtk.HBox() for x in (cs.get_get_targets_btn, cs.get_target_btn, cs.get_string_btn): get_actions.pack_start(x) tb.add_row(label(selection), cs.value_label, cs.clear_label_btn, cs.get_targets, get_actions) set_actions = gtk.HBox() for x in (cs.set_target_btn, cs.set_string_btn): set_actions.pack_start(x) tb.add_row(None, cs.value_entry, cs.clear_entry_btn, cs.set_targets, set_actions) vbox.pack_start(table) vbox.add(self.events) self.window.add(vbox) self.window.show_all() icon = get_icon("clipboard.png") if icon: self.window.set_icon(icon) try: self.add_event( "ALL", "window=%s, xid=%#x" % (self.window, get_xid(self.window.get_window()))) except: self.add_event("ALL", "window=%s" % self.window)
def set_class_instance(self, wmclass_name, wmclass_class): if not self.is_realized(): #Warning: window managers may ignore the icons we try to set #if the wm_class value is set and matches something somewhere undocumented #(if the default is used, you cannot override the window icon) self.set_wmclass(wmclass_name, wmclass_class) elif HAS_X11_BINDINGS: xid = get_xid(self.get_window()) with xsync: X11Window.setClassHint(xid, wmclass_class, wmclass_name) log("XSetClassHint(%s, %s) done", wmclass_class, wmclass_name)
def get_x11_window_value(filter_object, window): xid = get_xid(window) #log("get_x11_window_value(%s, %s) xid=%#x", filter_object, window, xid) with xsync: x11type = window_bindings.GetWindowPropertyType(xid, filter_object.property_name) ptype = get_python_type(x11type) #log("%s: %s (%s)", filter_object.property_name, x11type, ptype) assert ptype, "type '%s' is not handled!" % x11type v = prop_get(window, filter_object.property_name, ptype) log("%s=%s", filter_object.property_name, v) return v
def send_net_showing_desktop(v): from xpra.x11.gtk_x11 import gdk_display_source assert gdk_display_source from xpra.gtk_common.gobject_compat import get_xid from xpra.x11.bindings.window_bindings import constants, X11WindowBindings #@UnresolvedImport X11Window = X11WindowBindings() root = window.get_window().get_screen().get_root_window() root_xid = get_xid(root) SubstructureNotifyMask = constants["SubstructureNotifyMask"] SubstructureRedirectMask = constants["SubstructureRedirectMask"] event_mask = SubstructureNotifyMask | SubstructureRedirectMask X11Window.sendClientMessage(root_xid, root_xid, False, event_mask, "_NET_SHOWING_DESKTOP", v)
def get_x11_window_value(filter_object, window): xid = get_xid(window) #log("get_x11_window_value(%s, %s) xid=%#x", filter_object, window, xid) with xsync: x11type = window_bindings.GetWindowPropertyType( xid, filter_object.property_name) ptype = get_python_type(x11type) #log("%s: %s (%s)", filter_object.property_name, x11type, ptype) assert ptype, "type '%s' is not handled!" % x11type v = prop_get(window, filter_object.property_name, ptype) log("%s=%s", filter_object.property_name, v) return v
def do_set_shape(): xid = get_xid(self.get_window()) for kind, name in SHAPE_KIND.items(): rectangles = shape.get("%s.rectangles" % name) #ie: Bounding.rectangles = [(0, 0, 150, 100)] if rectangles is not None: #adjust for scaling: if self._client.xscale!=1 or self._client.yscale!=1: try: from PIL import Image, ImageDraw #@UnresolvedImport except: Image, ImageDraw = None, None if Image and ImageDraw: ww, wh = self._size sw, sh = self._client.cp(ww, wh) img = Image.new('1', (sw, sh), color=0) shapelog("drawing %s on bitmap(%s,%s)=%s", kind, sw, sh, img) d = ImageDraw.Draw(img) for x,y,w,h in rectangles: d.rectangle([x, y, x+w, y+h], fill=1) img = img.resize((ww, wh)) shapelog("resized %s bitmap to window size %sx%s: %s", kind, ww, wh, img) #now convert back to rectangles... rectangles = [] for y in range(wh): #for debugging, this is very useful, but costly! #shapelog("pixels[%3i]=%s", y, "".join([str(img.getpixel((x, y))) for x in range(ww)])) x = 0 start = None while x<ww: #find first white pixel: while x<ww and img.getpixel((x, y))==0: x += 1 start = x #find next black pixel: while x<ww and img.getpixel((x, y))!=0: x += 1 end = x if start<end: rectangles.append((start, y, end-start, 1)) else: #scale the rectangles without a bitmap... #results aren't so good! (but better than nothing?) srect = self._client.srect rectangles = [srect(*x) for x in rectangles] #FIXME: are we supposed to get the offset from the "extents"? x_off, y_off = 0, 0 shapelog("XShapeCombineRectangles %s=%i rectangles", name, len(rectangles)) #too expensive to log: #shapelog("XShapeCombineRectangles %s=%s", name, rectangles) with xsync: X11Window.XShapeCombineRectangles(xid, kind, x_off, y_off, rectangles)
def do_set_shape(): xid = get_xid(self.get_window()) x_off, y_off = shape.get("x", 0), shape.get("y", 0) for kind, name in SHAPE_KIND.items(): rectangles = shape.get("%s.rectangles" % name) #ie: Bounding.rectangles = [(0, 0, 150, 100)] if rectangles: #adjust for scaling: if self._client.xscale!=1 or self._client.yscale!=1: x_off, y_off = self._client.sp(x_off, y_off) rectangles = self.scale_shape_rectangles(name, rectangles) #too expensive to log with actual rectangles: shapelog("XShapeCombineRectangles(%#x, %s, %i, %i, %i rects)", xid, name, x_off, y_off, len(rectangles)) with xsync: X11Window.XShapeCombineRectangles(xid, kind, x_off, y_off, rectangles)
def __init__(self): self.window = gtk.Window() self.window.connect("destroy", self.destroy) self.window.set_default_size(640, 300) self.window.set_border_width(20) self.window.set_title("Clipboard Test Tool") vbox = gtk.VBox(False, 0) vbox.set_spacing(15) self.log = maxdeque(maxlen=25) for x in range(25): self.log.append("") self.events = gtk.Label() fixed = pango.FontDescription('monospace 9') self.events.modify_font(fixed) #how many clipboards to show: self.clipboards = CLIPBOARDS tb = TableBuilder() table = tb.get_table() labels = [label("Selection")] labels += [label("Value"), label("Clear"), label("Targets"), label("Actions")] tb.add_row(*labels) for selection in self.clipboards: cs = ClipboardInstance(selection, self.add_event) get_actions = gtk.HBox() for x in (cs.get_get_targets_btn, cs.get_target_btn, cs.get_string_btn): get_actions.pack_start(x) tb.add_row(label(selection), cs.value_label, cs.clear_label_btn, cs.get_targets, get_actions) set_actions = gtk.HBox() for x in (cs.set_target_btn, cs.set_string_btn): set_actions.pack_start(x) tb.add_row(None, cs.value_entry, cs.clear_entry_btn, cs.set_targets, set_actions) vbox.pack_start(table) vbox.add(self.events) self.window.add(vbox) self.window.show_all() icon = get_icon("clipboard.png") if icon: self.window.set_icon(icon) try: self.add_event("ALL", "window=%s, xid=%#x" % (self.window, get_xid(self.window.get_window()))) except: self.add_event("ALL", "window=%s" % self.window)
def _send_client_message(window, message_type, *values): try: from xpra.x11.gtk2 import gdk_display_source assert gdk_display_source from xpra.x11.bindings.window_bindings import constants, X11WindowBindings #@UnresolvedImport X11Window = X11WindowBindings() root_xid = X11Window.getDefaultRootWindow() if window: xid = get_xid(window) else: xid = root_xid SubstructureNotifyMask = constants["SubstructureNotifyMask"] SubstructureRedirectMask = constants["SubstructureRedirectMask"] event_mask = SubstructureNotifyMask | SubstructureRedirectMask X11Window.sendClientMessage(root_xid, xid, False, event_mask, message_type, *values) except Exception as e: log.warn("failed to send client message '%s' with values=%s: %s", message_type, values, e)
def set_workspace(self, workspace): workspacelog("set_workspace(%s)", workspace) if not self._been_mapped: #will be dealt with in the map event handler #which will look at the window metadata again workspacelog("workspace=%s will be set when the window is mapped", wn(workspace)) return desktop = self.get_desktop_workspace() ndesktops = self.get_workspace_count() current = self.get_window_workspace() workspacelog("set_workspace(%s) realized=%s, current workspace=%s, detected=%s, desktop workspace=%s, ndesktops=%s", wn(workspace), self.is_realized(), wn(self._window_workspace), wn(current), wn(desktop), ndesktops) if not self._can_set_workspace or ndesktops is None: return None if workspace==desktop or workspace==WORKSPACE_ALL or desktop is None: #window is back in view self._client.control_refresh(self._id, False, False) if (workspace<0 or workspace>=ndesktops) and workspace not in(WORKSPACE_UNSET, WORKSPACE_ALL): #this should not happen, workspace is unsigned (CARDINAL) #and the server should have the same list of desktops that we have here workspacelog.warn("Warning: invalid workspace number: %s", wn(workspace)) workspace = WORKSPACE_UNSET if workspace==WORKSPACE_UNSET: #we cannot unset via send_wm_workspace, so we have to choose one: workspace = self.get_desktop_workspace() if workspace in (None, WORKSPACE_UNSET): workspacelog.warn("workspace=%s (doing nothing)", wn(workspace)) return #we will need the gdk window: if current==workspace: workspacelog("window workspace unchanged: %s", wn(workspace)) return gdkwin = self.get_window() workspacelog("do_set_workspace: gdkwindow: %#x, mapped=%s, visible=%s", get_xid(gdkwin), self.is_mapped(), gdkwin.is_visible()) with xsync: send_wm_workspace(root, gdkwin, workspace)
def get_paint_context(self, gdk_window): assert self.context and gdk_window return GLXWindowContext(self.context, get_xid(gdk_window))