def setup(self): super().setup() ox, oy, ow, oh = self.client_window.get_geometry()[:4] # We enable PROPERTY_CHANGE_MASK so that we can call # x11_get_server_time on this window. # clamp this window to the desktop size: x, y = self._clamp_to_desktop(ox, oy, ow, oh) self.corral_window = GDKX11Window( self.parking_window, x=x, y=y, width=ow, height=oh, window_type=Gdk.WindowType.CHILD, event_mask=Gdk.EventMask.PROPERTY_CHANGE_MASK, title="CorralWindow-%#x" % self.xid) cxid = self.corral_window.get_xid() log("setup() corral_window=%#x", cxid) prop_set(self.corral_window, "_NET_WM_NAME", "utf8", "Xpra-CorralWindow-%#x" % self.xid) X11Window.substructureRedirect(cxid) add_event_receiver(self.corral_window, self) # The child might already be mapped, in case we inherited it from # a previous window manager. If so, we unmap it now, and save the # serial number of the request -- this way, when we get an # UnmapNotify later, we'll know that it's just from us unmapping # the window, not from the client withdrawing the window. if X11Window.is_mapped(self.xid): log("hiding inherited window") self.last_unmap_serial = X11Window.Unmap(self.xid) log("setup() adding to save set") X11Window.XAddToSaveSet(self.xid) self.in_save_set = True log("setup() reparenting") X11Window.Reparent(self.xid, cxid, 0, 0) self.client_reparented = True geomlog("setup() geometry") geom = X11Window.geometry_with_border(self.xid) if geom is None: raise Unmanageable("window %#x disappeared already" % self.xid) w, h = geom[2:4] hints = self.get_property("size-hints") geomlog("setup() hints=%s size=%ix%i", hints, w, h) nw, nh = self.calc_constrained_size(w, h, hints) self._updateprop("geometry", (x, y, nw, nh)) geomlog("setup() resizing windows to %sx%s", nw, nh) #don't trigger a resize unless we have to: if ow != nw or oh != nh: self.corral_window.resize(nw, nh) if w != nw or h != nh: self.client_window.resize(nw, nh) self.client_window.show_unraised() #this is here to trigger X11 errors if any are pending #or if the window is deleted already: self.client_window.get_geometry()
def do_dock_tray(self, xid): root = get_default_root_window() window = GdkX11.X11Window.foreign_new_for_display( root.get_display(), xid) if window is None: log.warn("could not find gdk window for tray window %#x", xid) return log("dock_tray: root=%s, window=%s", root, window) w, h = window.get_geometry()[2:4] log("dock_tray: geometry=%s", (w, h)) if w == 0 and h == 0: log("dock_tray: invalid tray geometry, ignoring this request") return em = Gdk.EventMask event_mask = em.STRUCTURE_MASK | em.EXPOSURE_MASK | em.PROPERTY_CHANGE_MASK window.set_events(event_mask=event_mask) add_event_receiver(window, self) w = max(1, min(MAX_TRAY_SIZE, w)) h = max(1, min(MAX_TRAY_SIZE, h)) title = prop_get(window, "_NET_WM_NAME", "utf8", ignore_errors=True) if title is None: title = prop_get(window, "WM_NAME", "latin1", ignore_errors=True) if title is None: title = "" xid = root.get_xid() log("dock_tray(%#x) gdk window=%#x, geometry=%s, title=%s", xid, xid, window.get_geometry(), title) visual = window.get_visual() tray_window = GDKX11Window(root, width=w, height=h, event_mask=event_mask, title=title, x=-200, y=-200, override_redirect=True, visual=visual) log("dock_tray(%#x) setting tray properties", xid) set_tray_window(tray_window, window) tray_window.show() self.tray_windows[window] = tray_window self.window_trays[tray_window] = window log("dock_tray(%#x) resizing and reparenting", xid) window.resize(w, h) xwin = window.get_xid() xtray = tray_window.get_xid() X11Window.Withdraw(xwin) X11Window.Reparent(xwin, xtray, 0, 0) X11Window.MapRaised(xwin) log("dock_tray(%#x) new tray container window %#x", xid, xtray) rect = Gdk.Rectangle() rect.width = w rect.height = h tray_window.invalidate_rect(rect, True) X11Window.send_xembed_message(xwin, XEMBED_EMBEDDED_NOTIFY, 0, xtray, XEMBED_VERSION)
def init_window(self): root = get_default_root_window() self.window = GDKX11Window(root, width=1, height=1, title="Xpra-Clipboard", wclass=Gdk.WindowWindowClass.INPUT_ONLY) self.window.set_events(Gdk.EventMask.PROPERTY_CHANGE_MASK | self.window.get_events()) xid = self.window.get_xid() with xsync: X11Window.selectSelectionInput(xid) add_event_receiver(self.window, self)
def setup_tray_window(self): display = Gdk.Display.get_default() root = get_default_root_window() screen = root.get_screen() owner = X11Window.XGetSelectionOwner(SELECTION) log("setup tray: current selection owner=%#x", owner) if owner != XNone: raise Exception("%s already owned by %s" % (SELECTION, owner)) visual = screen.get_system_visual() if TRANSPARENCY: visual = screen.get_rgba_visual() if visual is None: log.warn("setup tray: using rgb visual fallback") visual = screen.get_rgb_visual() assert visual is not None, "failed to obtain visual" self.tray_window = GDKX11Window(root, width=1, height=1, title="Xpra-SystemTray", visual=visual) xtray = self.tray_window.get_xid() set_tray_visual(self.tray_window, visual) set_tray_orientation(self.tray_window, TRAY_ORIENTATION_HORZ) log("setup tray: tray window %#x", xtray) display.request_selection_notification( Gdk.Atom.intern(SELECTION, False)) try: with xsync: setsel = X11Window.XSetSelectionOwner(xtray, SELECTION) log("setup tray: set selection owner returned %s, owner=%#x", setsel, X11Window.XGetSelectionOwner(SELECTION)) event_mask = StructureNotifyMask log("setup tray: sending client message") xid = root.get_xid() X11Window.sendClientMessage(xid, xid, False, event_mask, "MANAGER", CurrentTime, SELECTION, xtray) owner = X11Window.XGetSelectionOwner(SELECTION) assert owner == xtray, "we failed to get ownership of the tray selection" add_event_receiver(self.tray_window, self) log("setup tray: done") except Exception: log("setup_tray failure", exc_info=True) self.cleanup() raise
def _setup_ewmh_window(self): # Set up a 1x1 invisible unmapped window, with which to participate in # EWMH's _NET_SUPPORTING_WM_CHECK protocol. The only important things # about this window are the _NET_SUPPORTING_WM_CHECK property, and # its title (which is supposed to be the name of the window manager). # NB, GDK will do strange things to this window. We don't want to use # it for anything. (In particular, it will call XSelectInput on it, # which is fine normally when GDK is running in a client, but since it # happens to be using the same connection as we the WM, it will # clobber any XSelectInput calls that *we* might have wanted to make # on this window.) Also, GDK might silently swallow all events that # are detected on it, anyway. self._ewmh_window = GDKX11Window( self._root, wclass=Gdk.WindowWindowClass.INPUT_ONLY, title=self._wm_name) prop_set(self._ewmh_window, "_NET_SUPPORTING_WM_CHECK", "window", self._ewmh_window) self.root_set("_NET_SUPPORTING_WM_CHECK", "window", self._ewmh_window) self.root_set("_NET_WM_NAME", "utf8", self._wm_name)