def dock_tray(self, xid): root = gtk.gdk.get_default_root_window() window = gtk.gdk.window_foreign_new(xid) w, h = window.get_geometry()[2:4] event_mask = gtk.gdk.STRUCTURE_MASK | gtk.gdk.EXPOSURE_MASK | gtk.gdk.PROPERTY_CHANGE_MASK window.set_events(event_mask=event_mask) add_event_receiver(window, self) w = max(1, min(200, w)) h = max(1, min(200, h)) log("dock_tray(%s) window=%s, geometry=%s, visual.depth=%s", xid, window, window.get_geometry(), window.get_visual().depth) event_mask = gtk.gdk.STRUCTURE_MASK | gtk.gdk.EXPOSURE_MASK | gtk.gdk.PROPERTY_CHANGE_MASK tray_window = gtk.gdk.Window(root, width=w, height=h, window_type=gtk.gdk.WINDOW_TOPLEVEL, event_mask = event_mask, wclass=gtk.gdk.INPUT_OUTPUT, title="TrayWindow", x=-200, y=-200, override_redirect=True, visual=window.get_visual(), colormap=window.get_colormap()) log("dock_tray(%s) 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(%s) resizing and reparenting", xid) window.resize(w, h) withdraw(window) reparent(window, tray_window, 0, 0) map_raised(window) log("dock_tray(%s) new tray container window %s", xid, get_xwindow(tray_window)) tray_window.invalidate_rect(gtk.gdk.Rectangle(width=w, height=h), True) embedder = get_xwindow(tray_window) send_xembed_message(window, XEMBED_EMBEDDED_NOTIFY, 0, embedder, XEMBED_VERSION)
def __init__(self): gobject.GObject.__init__(self) self._clipboard = gtk.Clipboard(gtk.gdk.display_get_default(), "_XSETTINGS_S0") self._current = None self._root = self._clipboard.get_display().get_default_screen().get_root_window() add_event_receiver(self._root, self) self._add_watch()
def test_select_clientmessage_and_xselectinput(self): self.evs = [] self.w = self.window() gtk.gdk.flush() l.add_event_receiver(self.w, self) l.add_event_receiver(self.root(), self) data = (0x01020304, 0x05060708, 0x090a0b0c, 0x0d0e0f10, 0x11121314) l.sendClientMessage(self.root(), False, 0, "NOMASK", *data) l.sendClientMessage(self.w, False, 0, "NOMASK", *data) gtk.main() # Should have gotten message to w, not to root assert len(self.evs) == 1 ev = self.evs[0] assert ev.window is self.w assert ev.message_type == "NOMASK" assert ev.format == 32 assert ev.data == data self.evs = [] l.sendClientMessage(self.root(), False, l.const["Button1MotionMask"], "BAD", *data) l.addXSelectInput(self.root(), l.const["Button1MotionMask"]) l.sendClientMessage(self.root(), False, l.const["Button1MotionMask"], "GOOD", *data) gtk.main() assert len(self.evs) == 1 ev = self.evs[0] assert ev.window is self.root() assert ev.message_type == "GOOD" assert ev.format == 32 assert ev.data == data
def x11_init(self, clobber): X11ServerBase.x11_init(self, clobber) init_x11_filter() self._has_focus = 0 # Do this before creating the Wm object, to avoid clobbering its # selecting SubstructureRedirect. root = gtk.gdk.get_default_root_window() root.set_events(root.get_events() | gtk.gdk.SUBSTRUCTURE_MASK) root.property_change(gtk.gdk.atom_intern("XPRA_SERVER", False), gtk.gdk.atom_intern("STRING", False), 8, gtk.gdk.PROP_MODE_REPLACE, xpra.__version__) add_event_receiver(root, self) ### Create the WM object self._wm = Wm("Xpra", clobber) self._wm.connect("new-window", self._new_window_signaled) self._wm.connect("window-resized", self._window_resized_signaled) self._wm.connect("bell", self._bell_signaled) self._wm.connect("quit", lambda _: self.quit(True)) self.default_cursor_data = None self.last_cursor_serial = None self.send_cursor_pending = False self.cursor_data = None def get_default_cursor(): self.default_cursor_data = get_cursor_image() log("get_default_cursor=%s", self.default_cursor_data) trap.swallow_synced(get_default_cursor) self._wm.enableCursors(True)
def set_pixmap(): # The tricky part here is that the pixmap returned by # NameWindowPixmap gets invalidated every time the window's # viewable state changes. ("viewable" here is the X term that # means "mapped, and all ancestors are also mapped".) But # there is no X event that will tell you when a window's # viewability changes! Instead we have to find all ancestors, # and watch all of them for unmap and reparent events. But # what about races? I hear you cry. By doing things in the # exact order: # 1) select for StructureNotify # 2) QueryTree to get parent # 3) repeat 1 & 2 up to the root # 4) call NameWindowPixmap # we are safe. (I think.) listening = [] win = get_parent(self._window) while win is not None and win.get_parent() is not None: # We have to use a lowlevel function to manipulate the # event selection here, because SubstructureRedirectMask # does not roundtrip through the GDK event mask # functions. So if we used them, here, we would clobber # corral window selection masks, and those don't deserve # clobbering. They are our friends! X is driving me # slowly mad. addXSelectInput(win, const["StructureNotifyMask"]) add_event_receiver(win, self) listening.append(win) win = get_parent(win) handle = xcomposite_name_window_pixmap(self._window) self._contents_handle = handle # Don't save the listening set until after NameWindowPixmap # has succeeded, to maintain our invariant: self._listening_to = listening
def setup(self): if not self._already_composited: xcomposite_redirect_window(self._window) _, _, _, _, self._border_width = geometry_with_border(self._window) self.invalidate_pixmap() self._damage_handle = xdamage_start(self._window) add_event_receiver(self._window, self)
def __init__(self, name, replace_other_wm, display=None): gobject.GObject.__init__(self) self._name = name if display is None: display = gtk.gdk.display_manager_get().get_default_display() self._display = display self._alt_display = gtk.gdk.Display(self._display.get_name()) self._root = self._display.get_default_screen().get_root_window() self._ewmh_window = None self._windows = {} # EWMH says we have to know the order of our windows oldest to # youngest... self._windows_in_order = [] # Become the Official Window Manager of this year's display: self._wm_selection = wimpiggy.selection.ManagerSelection( self._display, "WM_S0") self._wm_selection.connect("selection-lost", self._lost_wm_selection) # May throw AlreadyOwned: if replace_other_wm: mode = self._wm_selection.FORCE else: mode = self._wm_selection.IF_UNOWNED self._wm_selection.acquire(mode) # (If we become a compositing manager, then we will want to do the # same thing with the _NET_WM_CM_S0 selection (says EWMH). AFAICT # this basically will just be used by clients to know that they can # use RGBA visuals.) # Set up the necessary EWMH properties on the root window. self._setup_ewmh_window() prop_set(self._root, "_NET_SUPPORTED", ["atom"], self._NET_SUPPORTED) prop_set(self._root, "_NET_DESKTOP_VIEWPORT", ["u32"], [0, 0]) # Load up our full-screen widget self._world_window = WorldWindow() self._world_window.set_screen(self._display.get_default_screen()) self.notify("toplevel") self._world_window.show_all() # Okay, ready to select for SubstructureRedirect and then load in all # the existing clients. add_event_receiver(self._root, self) substructureRedirect(self._root) for w in get_children(self._root): # Checking for FOREIGN here filters out anything that we've # created ourselves (like, say, the world window), and checking # for mapped filters out any withdrawn windows. if (w.get_window_type() == gtk.gdk.WINDOW_FOREIGN and not is_override_redirect(w) and is_mapped(w)): log("Wm managing pre-existing child") self._manage_client(w) # Also watch for focus change events on the root window selectFocusChange(self._root) selectBellNotification(self._root, True)
def __init__(self, screen_number=0): gobject.GObject.__init__(self) self._selection = "_XSETTINGS_S%s" % screen_number self._clipboard = gtk.Clipboard(gtk.gdk.display_get_default(), self._selection) self._current = None self._root = self._clipboard.get_display().get_default_screen().get_root_window() add_event_receiver(self._root, self) self._add_watch()
def acquire(self, when): old_owner = self._owner() if when is self.IF_UNOWNED and old_owner != const["XNone"]: raise AlreadyOwned self.clipboard.set_with_data([("VERSION", 0, 0)], self._get, self._clear, None) # Having acquired the selection, we have to announce our existence # (ICCCM 2.8, still). The details here probably don't matter too # much; I've never heard of an app that cares about these messages, # and metacity actually gets the format wrong in several ways (no # MANAGER or owner_window atoms). But might as well get it as right # as possible. # To announce our existence, we need: # -- the timestamp we arrived at # -- the manager selection atom # -- the window that registered the selection # Of course, because Gtk is doing so much magic for us, we have to do # some weird tricks to get at these. # Ask ourselves when we acquired the selection: ts_data = self.clipboard.wait_for_contents("TIMESTAMP").data ts_num = unpack("@i", ts_data[:4])[0] # Calculate the X atom for this selection: selection_xatom = get_xatom(self.atom) # Ask X what window we used: self._xwindow = myGetSelectionOwner(self.clipboard, self.atom) root = self.clipboard.get_display().get_default_screen().get_root_window() sendClientMessage(root, root, False, const["StructureNotifyMask"], "MANAGER", ts_num, selection_xatom, self._xwindow, 0, 0) if old_owner != const["XNone"] and when is self.FORCE: # Block in a recursive mainloop until the previous owner has # cleared out. def getwin(): window = get_pywindow(self.clipboard, old_owner) window.set_events(window.get_events() | gtk.gdk.STRUCTURE_MASK) return window try: window = trap.call_synced(getwin) log("got window") except XError: log("Previous owner is already gone, not blocking") else: log("Waiting for previous owner to exit...") add_event_receiver(window, self) gtk.main() log("...they did.") window = get_pywindow(self.clipboard, self._xwindow) window.set_title("Xpra-ManagerSelection")
def __init__(self, screen_number=0): gobject.GObject.__init__(self) self._selection = "_XSETTINGS_S%s" % screen_number self._clipboard = gtk.Clipboard(gtk.gdk.display_get_default(), self._selection) self._current = None self._root = self._clipboard.get_display().get_default_screen( ).get_root_window() add_event_receiver(self._root, self) self._add_watch()
def test_unmap_with_serial(self): w = self.window() w.show() self._event = None l.add_event_receiver(w, self) serial = l.unmap_with_serial(w) print(serial) gtk.main() assert self._event is not None assert self._event.serial == serial
def test_focus_stuff(self): self.w1 = self.window() self.w1.show() self.w2 = self.window() self.w2.show() gtk.gdk.flush() self.w1_got, self.w2_got = None, None self.w1_lost, self.w2_lost = None, None l.selectFocusChange(self.w1) l.selectFocusChange(self.w2) l.add_event_receiver(self.w1, self) l.add_event_receiver(self.w2, self) gtk.gdk.flush() l.XSetInputFocus(self.w1) gtk.gdk.flush() gtk.main() assert self.w1_got is not None assert self.w1_got.window is self.w1 assert self.w1_got.mode == l.const["NotifyNormal"] assert self.w1_got.detail == l.const["NotifyNonlinear"] self.w1_got = None assert self.w2_got is None assert self.w1_lost is None assert self.w2_lost is None l.XSetInputFocus(self.w2) gtk.gdk.flush() gtk.main() gtk.main() assert self.w1_got is None assert self.w2_got is not None assert self.w2_got.window is self.w2 assert self.w2_got.mode == l.const["NotifyNormal"] assert self.w2_got.detail == l.const["NotifyNonlinear"] self.w2_got = None assert self.w1_lost is not None assert self.w1_lost.window is self.w1 assert self.w1_lost.mode == l.const["NotifyNormal"] assert self.w1_lost.detail == l.const["NotifyNonlinear"] self.w1_lost = None assert self.w2_lost is None l.XSetInputFocus(self.root()) gtk.gdk.flush() gtk.main() assert self.w1_got is None assert self.w2_got is None assert self.w1_lost is None assert self.w2_lost is not None assert self.w2_lost.window is self.w2 assert self.w2_lost.mode == l.const["NotifyNormal"] assert self.w2_lost.detail == l.const["NotifyAncestor"] self.w2_lost = None
def __init__(self, window): gobject.GObject.__init__(self) self.window = window self.hotkeys = {} disp = get_display_for(self.window) self.keymap = gtk.gdk.keymap_get_for_display(disp) self.keymap_id = self.keymap.connect("keys-changed", self._keys_changed) self._keys_changed() add_event_receiver(self.window, self)
def __init__(self, window, already_composited): super(CompositeHelper, self).__init__() self._window = window self._already_composited = already_composited def setup(): if not self._already_composited: xcomposite_redirect_window(window) (_, _, _, _, self._border_width) = geometry_with_border(window) trap.call(setup) self._listening_to = None self.invalidate_pixmap() self._damage_handle = xdamage_start(window) add_event_receiver(self._window, self)
def test_event_routing(self): w1 = self.window() w2 = self.window() w2.reparent(w1, 0, 0) results = set() r1 = _EventRoutingReceiver(1, results) r2 = _EventRoutingReceiver(2, results) r3 = _EventRoutingReceiver(3, results) r4 = _EventRoutingReceiver(4, results) l.add_event_receiver(w1, r1) l.add_event_receiver(w1, r2) l.add_event_receiver(w2, r3) l.add_event_receiver(w2, r4) w1.set_events(gtk.gdk.SUBSTRUCTURE_MASK) w2.set_events(gtk.gdk.STRUCTURE_MASK) w2.show() while len(results) != 4: gtk.main() w2.hide() assert results == set([("child-map", 1), ("child-map", 2), ("map", 3), ("map", 4)]) l.remove_event_receiver(w1, r2) l.remove_event_receiver(w2, r4) results.clear() w2.show() while len(results) != 2: gtk.main() assert results == set([("child-map", 1), ("map", 3)])
def test_send_wm_take_focus_large_time(self): self.evs = [] win = self.window() l.add_event_receiver(win, self) gtk.gdk.flush() send_wm.send_wm_take_focus(win, 0xff000000) gtk.main() assert len(self.evs) == 1 event = self.evs[0] assert event is not None assert event.window is win assert event.message_type == "WM_PROTOCOLS" assert event.format == 32 assert event.data == (l.get_xatom("WM_TAKE_FOCUS"), 0xff000000, 0, 0, 0)
def set_pixmap(): # The tricky part here is that the pixmap returned by # NameWindowPixmap gets invalidated every time the window's # viewable state changes. ("viewable" here is the X term that # means "mapped, and all ancestors are also mapped".) But # there is no X event that will tell you when a window's # viewability changes! Instead we have to find all ancestors, # and watch all of them for unmap and reparent events. But # what about races? I hear you cry. By doing things in the # exact order: # 1) select for StructureNotify # 2) QueryTree to get parent # 3) repeat 1 & 2 up to the root # 4) call NameWindowPixmap # we are safe. (I think.) listening = [] try: win = get_parent(self._window) while win is not None and win.get_parent() is not None: # We have to use a lowlevel function to manipulate the # event selection here, because SubstructureRedirectMask # does not roundtrip through the GDK event mask # functions. So if we used them, here, we would clobber # corral window selection masks, and those don't deserve # clobbering. They are our friends! X is driving me # slowly mad. addXSelectInput(win, const["StructureNotifyMask"]) add_event_receiver(win, self) listening.append(win) win = get_parent(win) handle = xcomposite_name_window_pixmap(self._window) except: try: self._cleanup_listening(listening) except: pass raise if handle is None: log.warn( "failed to name a window pixmap (expect an X error soon)", type="pixmap") self._cleanup_listening(listening) else: self._contents_handle = handle # Don't save the listening set until after # NameWindowPixmap has succeeded, to maintain our # invariant: self._listening_to = listening
def setup_tray_window(self): display = gtk.gdk.display_get_default() root = gtk.gdk.get_default_root_window() screen = root.get_screen() if TRANSPARENCY: colormap, visual = screen.get_rgba_colormap( ), screen.get_rgba_visual() if colormap is None or visual is None: log.warn("setup tray: using rgb visual fallback") colormap, visual = screen.get_rgb_colormap( ), screen.get_rgb_visual() assert colormap is not None and visual is not None, "failed to obtain visual or colormap" owner = myGetSelectionOwner(root, SELECTION) log("setup tray: current selection owner=%s", owner) if owner != const["XNone"]: raise Exception("%s already owned by %s" % (SELECTION, owner)) self.tray_window = gtk.gdk.Window(root, width=1, height=1, window_type=gtk.gdk.WINDOW_TOPLEVEL, event_mask=0, wclass=gtk.gdk.INPUT_OUTPUT, title="Xpra-SystemTray", visual=visual, colormap=colormap) set_tray_visual(self.tray_window, visual) set_tray_orientation(self.tray_window, TRAY_ORIENTATION_HORZ) log("setup tray: tray window %s", get_xwindow(self.tray_window)) display.request_selection_notification(SELECTION) setsel = mySetSelectionOwner(root, self.tray_window, SELECTION) log("setup tray: set selection owner returned %s", setsel) event_mask = const["StructureNotifyMask"] sendClientMessage(root, root, False, event_mask, "MANAGER", const["CurrentTime"], SELECTION, get_xwindow(self.tray_window), 0, 0) owner = myGetSelectionOwner(root, SELECTION) #FIXME: cleanup if we fail! assert owner == get_xwindow( self.tray_window ), "we failed to get ownership of the tray selection" add_event_receiver(self.tray_window, self) log("setup tray: done")
def __init__(self, sock): gobject.GObject.__init__(self) self._window_to_id = {} self._id_to_window = {} root = gtk.gdk.get_default_root_window() root.set_events(root.get_events() | gtk.gdk.PROPERTY_NOTIFY) add_event_receiver(root, self) self._protocol = Protocol(sock, self.process_packet) ClientSource(self._protocol) self.send(["hello", default_capabilities]) self._keymap = gtk.gdk.keymap_get_default() self._keymap.connect("keys-changed", self._keys_changed) self._keys_changed() self._clipboard_helper = ClipboardProtocolHelper(self.send) self._focused = None
def __init__(self, clobber, sockets): gobject.GObject.__init__(self) # Do this before creating the Wm object, to avoid clobbering its # selecting SubstructureRedirect. root = gtk.gdk.get_default_root_window() root.set_events(root.get_events() | gtk.gdk.SUBSTRUCTURE_MASK) add_event_receiver(root, self) ### Create the WM object self._wm = Wm("Xpra", clobber) self._wm.connect("new-window", self._new_window_signaled) self._wm.connect("quit", lambda _: self.quit(True)) ### Create our window managing data structures: self._desktop_manager = DesktopManager() self._wm.get_property("toplevel").add(self._desktop_manager) self._desktop_manager.show_all() self._window_to_id = {} self._id_to_window = {} # Window id 0 is reserved for "not a window" self._max_window_id = 1 ### Load in existing windows: for window in self._wm.get_property("windows"): self._add_new_window(window) for window in get_children(root): if (is_override_redirect(window) and is_mapped(window)): self._add_new_or_window(window) ### Set up keymap: self._keymap = gtk.gdk.keymap_get_default() self._keymap.connect("keys-changed", self._keys_changed) self._keys_changed() try: xmodmap = subprocess.Popen(["xmodmap", "-"], stdin=subprocess.PIPE) except OSError, e: sys.stderr.write("Error running xmodmap: %s\n" % (e,))
def test_configureAndNotify(self): self.conf_ev = None l.substructureRedirect(self.root()) l.add_event_receiver(self.root(), self) # Need to hold onto a handle to this, so connection doesn't get # dropped: client = self.clone_display() w1_client = self.window(client) gtk.gdk.flush() w1_wm = l.get_pywindow(self.display, l.get_xwindow(w1_client)) l.configureAndNotify(w1_client, 11, 12, 13, 14) gtk.main() assert self.conf_ev is not None assert self.conf_ev.delivered_to is self.root() assert self.conf_ev.window is w1_wm assert self.conf_ev.x == 11 assert self.conf_ev.y == 12 assert self.conf_ev.width == 13 assert self.conf_ev.height == 14 assert self.conf_ev.border_width == 0 assert self.conf_ev.value_mask == (l.const["CWX"] | l.const["CWY"] | l.const["CWWidth"] | l.const["CWHeight"] | l.const["CWBorderWidth"]) partial_mask = l.const["CWWidth"] | l.const["CWStackMode"] l.configureAndNotify(w1_client, 11, 12, 13, 14, partial_mask) gtk.main() assert self.conf_ev is not None assert self.conf_ev.delivered_to is self.root() assert self.conf_ev.window is w1_wm assert self.conf_ev.width == 13 assert self.conf_ev.border_width == 0 assert self.conf_ev.value_mask == (l.const["CWWidth"] | l.const["CWBorderWidth"])
def setup_tray_window(self): display = gtk.gdk.display_get_default() root = gtk.gdk.get_default_root_window() screen = root.get_screen() if TRANSPARENCY: colormap, visual = screen.get_rgba_colormap(), screen.get_rgba_visual() if colormap is None or visual is None: log.warn("setup tray: using rgb visual fallback") colormap, visual = screen.get_rgb_colormap(), screen.get_rgb_visual() assert colormap is not None and visual is not None, "failed to obtain visual or colormap" owner = myGetSelectionOwner(root, SELECTION) log("setup tray: current selection owner=%s", owner) if owner!=const["XNone"]: raise Exception("%s already owned by %s" % (SELECTION, owner)) self.tray_window = gtk.gdk.Window(root, width=1, height=1, window_type=gtk.gdk.WINDOW_TOPLEVEL, event_mask = 0, wclass=gtk.gdk.INPUT_OUTPUT, title="Xpra-SystemTray", visual=visual, colormap=colormap) set_tray_visual(self.tray_window, visual) set_tray_orientation(self.tray_window, TRAY_ORIENTATION_HORZ) log("setup tray: tray window %s", get_xwindow(self.tray_window)) display.request_selection_notification(SELECTION) setsel = mySetSelectionOwner(root, self.tray_window, SELECTION) log("setup tray: set selection owner returned %s", setsel) event_mask = const["StructureNotifyMask"] sendClientMessage(root, root, False, event_mask, "MANAGER", const["CurrentTime"], SELECTION, get_xwindow(self.tray_window), 0, 0) owner = myGetSelectionOwner(root, SELECTION) #FIXME: cleanup if we fail! assert owner==get_xwindow(self.tray_window), "we failed to get ownership of the tray selection" add_event_receiver(self.tray_window, self) log("setup tray: done")
def test_substructure_redirect(self): self.map_ev = None self.conf_ev = None root = self.root() d2 = self.clone_display() w2 = self.window(d2) gtk.gdk.flush() w1 = l.get_pywindow(self.display, l.get_xwindow(w2)) l.add_event_receiver(root, self) l.substructureRedirect(root) gtk.gdk.flush() # gdk_window_show does both a map and a configure (to raise the # window) print("showing w2") w2.show() # Can't just call gtk.main() twice, the two events may be delivered # together and processed in a single mainloop iteration. while None in (self.map_ev, self.conf_ev): gtk.main() assert self.map_ev.delivered_to is root assert self.map_ev.window is w1 assert self.conf_ev.delivered_to is root assert self.conf_ev.window is w1 for field in ("x", "y", "width", "height", "border_width", "above", "detail", "value_mask"): print(field) assert hasattr(self.conf_ev, field) self.map_ev = None self.conf_ev = None w2.move_resize(1, 2, 3, 4) gtk.main() assert self.map_ev is None assert self.conf_ev is not None assert self.conf_ev.delivered_to is root assert self.conf_ev.window is w1 assert self.conf_ev.x == 1 assert self.conf_ev.y == 2 assert self.conf_ev.width == 3 assert self.conf_ev.height == 4 assert self.conf_ev.value_mask == (l.const["CWX"] | l.const["CWY"] | l.const["CWWidth"] | l.const["CWHeight"]) self.map_ev = None self.conf_ev = None w2.move(5, 6) gtk.main() assert self.map_ev is None assert self.conf_ev.x == 5 assert self.conf_ev.y == 6 assert self.conf_ev.value_mask == (l.const["CWX"] | l.const["CWY"]) self.map_ev = None self.conf_ev = None w2.raise_() gtk.main() assert self.map_ev is None assert self.conf_ev.detail == l.const["Above"] assert self.conf_ev.value_mask == l.const["CWStackMode"]
def __init__(self, name, replace_other_wm, display=None): gobject.GObject.__init__(self) self._name = name if display is None: display = gtk.gdk.display_manager_get().get_default_display() self._display = display self._alt_display = gtk.gdk.Display(self._display.get_name()) self._root = self._display.get_default_screen().get_root_window() self._ewmh_window = None self._windows = {} # EWMH says we have to know the order of our windows oldest to # youngest... self._windows_in_order = [] # Become the Official Window Manager of this year's display: self._wm_selection = wimpiggy.selection.ManagerSelection(self._display, "WM_S0") self._wm_selection.connect("selection-lost", self._lost_wm_selection) # May throw AlreadyOwned: if replace_other_wm: mode = self._wm_selection.FORCE else: mode = self._wm_selection.IF_UNOWNED self._wm_selection.acquire(mode) # (If we become a compositing manager, then we will want to do the # same thing with the _NET_WM_CM_S0 selection (says EWMH). AFAICT # this basically will just be used by clients to know that they can # use RGBA visuals.) # Set up the necessary EWMH properties on the root window. self._setup_ewmh_window() prop_set(self._root, "_NET_SUPPORTED", ["atom"], self._NET_SUPPORTED) prop_set(self._root, "_NET_DESKTOP_VIEWPORT", ["u32"], [0, 0]) # Load up our full-screen widget self._world_window = WorldWindow() self._world_window.set_screen(self._display.get_default_screen()) self.notify("toplevel") self._world_window.show_all() # Okay, ready to select for SubstructureRedirect and then load in all # the existing clients. add_event_receiver(self._root, self) substructureRedirect(self._root) for w in get_children(self._root): # Checking for FOREIGN here filters out anything that we've # created ourselves (like, say, the world window), and checking # for mapped filters out any withdrawn windows. if (w.get_window_type() == gtk.gdk.WINDOW_FOREIGN and not is_override_redirect(w) and is_mapped(w)): log("Wm managing pre-existing child") self._manage_client(w) # Also watch for focus change events on the root window selectFocusChange(self._root) selectBellNotification(self._root, True)
def _add_watch(self): owner = self._owner() if owner is not None: add_event_receiver(owner, self)
def __init__(self, props): gobject.GObject.__init__(self) self._props = props self._root = gtk.gdk.get_default_root_window() add_event_receiver(self._root, self)