def grab(self, key): accelerator = key accelerator = accelerator.replace("<Super>", "<Mod4>") keyval, modifiers = Gtk.accelerator_parse(accelerator) if not accelerator or (not keyval and not modifiers): self.keycode = None self.modifiers = None return False self.keytext = key try: self.keycode = self.keymap.get_entries_for_keyval( keyval).keys[0].keycode except AttributeError: # In older Gtk3 the get_entries_for_keyval() returns an unnamed tuple... self.keycode = self.keymap.get_entries_for_keyval( keyval)[1][0].keycode self.modifiers = int(modifiers) # Request to receive key press/release reports from other windows that may not be using modifiers catch = error.CatchError(error.BadWindow) if self.modifiers: self.window.change_attributes(onerror=catch, event_mask=X.KeyPressMask | X.KeyReleaseMask) else: self.window.change_attributes(onerror=catch, event_mask=X.NoEventMask) if catch.get_error(): return False catch = error.CatchError(error.BadAccess) for ignored_mask in self.ignored_masks: mod = modifiers | ignored_mask result = self.window.grab_key(self.keycode, mod, True, X.GrabModeAsync, X.GrabModeAsync, onerror=catch) self.display.flush() if catch.get_error(): return False catch = error.CatchError(error.BadCursor) if not self.modifiers: # We grab Super+click so that we can forward it to the window manager and allow Super+click bindings (window move, resize, etc.) self.window.grab_button(X.AnyButton, X.Mod4Mask, True, X.ButtonPressMask, X.GrabModeSync, X.GrabModeAsync, X.NONE, X.NONE) self.display.flush() if catch.get_error(): return False return True
def grab(self, key): accelerator = key accelerator = accelerator.replace("<Super>", "<Mod4>") keyval, modifiers = Gtk.accelerator_parse(accelerator) if not accelerator or (not keyval and not modifiers): self.keycode = None self.modifiers = None return False self.keytext = key self.keycode = self.get_keycode(keyval) self.modifiers = int(modifiers) catch = error.CatchError(error.BadAccess) for ignored_mask in self.ignored_masks: mod = modifiers | ignored_mask result = self.window.grab_key(self.keycode, mod, True, X.GrabModeAsync, X.GrabModeSync, onerror=catch) self.display.flush() # sync has been blocking. Don't know why. #self.display.sync() if catch.get_error(): return False return True
def grab(self, key): accelerator = key accelerator = accelerator.replace("<Super>", "<Mod4>") keyval, modifiers = Gtk.accelerator_parse(accelerator) if not accelerator or (not keyval and not modifiers): self.keycode = None self.modifiers = None return False self.keytext = key try: self.keycode = self.keymap.get_entries_for_keyval( keyval).keys[0].keycode except: # In Betsy, the get_entries_for_keyval() returns an unamed tuple... self.keycode = self.keymap.get_entries_for_keyval( keyval)[1][0].keycode self.modifiers = int(modifiers) catch = error.CatchError(error.BadAccess) for ignored_mask in self.ignored_masks: mod = modifiers | ignored_mask result = self.window.grab_key(self.keycode, mod, True, X.GrabModeAsync, X.GrabModeAsync, onerror=catch) self.display.flush() # sync has been blocking. Don't know why. #self.display.sync() if catch.get_error(): return False return True
def grab(self, key): accelerator = key accelerator = accelerator.replace("<Super>", "<Mod4>") keyval, modifiers = Gtk.accelerator_parse(accelerator) if not accelerator or (not keyval and not modifiers): self.keycode = None self.modifiers = None return False self.keytext = key try: self.keycode = self.keymap.get_entries_for_keyval( keyval).keys[0].keycode except AttributeError: # In older Gtk3 the get_entries_for_keyval() returns an unnamed tuple... self.keycode = self.keymap.get_entries_for_keyval( keyval)[1][0].keycode self.modifiers = int(modifiers) # Request to receive key press/release reports from other windows that may not be using modifiers catch = error.CatchError(error.BadWindow) if self.modifiers: self.window.change_attributes(onerror=catch, event_mask=X.KeyPressMask | X.KeyReleaseMask) else: self.window.change_attributes(onerror=catch, event_mask=X.NoEventMask) if catch.get_error(): return False catch = error.CatchError(error.BadAccess) for ignored_mask in self.ignored_masks: mod = modifiers | ignored_mask result = self.window.grab_key(self.keycode, mod, True, X.GrabModeAsync, X.GrabModeAsync, onerror=catch) self.display.flush() # sync has been blocking. Don't know why. #self.display.sync() if catch.get_error(): return False return True
def delete(self): wm_del = self.dpy.get_atom('WM_DELETE_WINDOW') catch = Xerror.CatchError(Xerror.BadWindow, Xerror.BadValue) if wm_del in self.props['WM_PROTOCOLS']: props.send_window_message(self.dpy, self.win, 'WM_PROTOCOLS', [wm_del], self.win, event_mask=0) else: self.win.kill_client() self.dpy.sync()
def grab(self): Gdk.threads_enter() self.keycode= self.keymap.get_entries_for_keyval(keyval)[1][0].keycode self.modifiers = int(modifiers) catch = error.CatchError(error.BadAccess) for ignored_mask in self.ignored_masks: mod = modifiers | ignored_mask result = self.root.grab_key(self.keycode, mod, True, X.GrabModeAsync, X.GrabModeSync, onerror=catch) self.display.sync() if catch.get_error(): return False return True
def __init__(self, parent_id): """ Initialize and display the panel """ self.display = display.Display() # Display obj self.screen = self.display.screen() # Screen obj self.root = self.screen.root # Display root self.parent_id = parent_id # self.error = error.CatchError() # Error Handler/Suppressor self.panel = {"sections":[]} # Panel data and layout global P_HEIGHT self.panel["sections"].append(TRAY) self.panel[TRAY] = Obj(id="tray", tasks={}, order=[]) self.createTray(self.display, self.screen)
def add_keybinding(self, accelerator, callback): keyval, modifiers = Gtk.accelerator_parse(accelerator) keymap = Gdk.Keymap.get_default() keycode = keymap.get_entries_for_keyval(keyval)[1][0].keycode for m in (modifiers, modifiers | X.LockMask): self.display.screen().root.grab_key( keycode, m, True, X.GrabModeAsync, X.GrabModeSync, onerror=error.CatchError(error.BadAccess), ) self.display.sync() self.keybindings[(keycode, modifiers)] = callback
def get_active_window_title( self, session_num=1, active_window_id=int ): # session_num = 0 if note option is clicked else 1 # print("\nSession Number" + str(session_num)) active_window_id = self.active_window_id if (str(os.environ["DESKTOP_SESSION"]) == "xfce" and session_num == 0): print("Session Number 0") self.active_window_id = self.prev_active_window_id active_window_id = self.active_window_id elif (str(os.environ["DESKTOP_SESSION"]) == "xubuntu" and session_num == 0): self.active_window_id = self.prev_active_window_id active_window_id = self.active_window_id else: self.active_window_id = self.get_active_window_id() active_window_id = self.active_window_id self.thread_toggle = not self.thread_toggle # print("ACTIVE EINDOW ID = "+str(active_window_id)) self.active = self.display.create_resource_object( 'window', active_window_id) # print("-----------------"+str(self.active)) atom = self.display.intern_atom('_NET_WM_NAME', True) if (self.is_ewmh_supported(atom, self.root) == False): print("EWMH is not supported by your window manager!!") return None # return ec = error.CatchError(error.BadWindow) try: w = (self.active).get_full_property(atom, Xlib.X.AnyPropertyType).value except: print("************************Bad Window") return (self.active_window_title) try: # self.prev_active_window_title = self.active_window_title self.active_window_title = w.decode("utf8") print("Previous window title :", self.prev_active_window_title) print("Current window title :", self.active_window_title) except: return (self.active_window_title) return (self.active_window_title)
def grab(self): Gdk.threads_enter() accelerator = ConfigManager.get_conf('global-key') Gdk.threads_leave() keyval, modifiers = Gtk.accelerator_parse(accelerator) if not accelerator or (not keyval and not modifiers): self.keycode = None self.modifiers = None return self.keycode = self.keymap.get_entries_for_keyval(keyval)[1][0].keycode self.modifiers = int(modifiers) catch = error.CatchError(error.BadAccess) self.root.grab_key(self.keycode, X.AnyModifier, True, X.GrabModeAsync, X.GrabModeSync, onerror=catch) self.display.sync() if catch.get_error(): return False return True
def get_wm_selection(self): catch = Xerror.CatchError(Xerror.BadAccess) self.root.change_attributes(event_mask=self.mask, onerror=catch) self.dpy.sync() if catch.get_error(): raise wm_already_running()
metavar="string", default="%ld\t%s") parser.add_option( "-r", "--range", dest="range", help= "This option specifies the range of atom values to check. If low is not given, a value of 1 assumed. If high is not given, xlsatoms will stop at the first undefined atom at or above low.", metavar="[low]-[high]", default="1-") (options, args) = parser.parse_args() low = 1 high = 1 ec = error.CatchError(error.BadAtom) d = display.Display(options.display) def print_atom(print_format, atom, value): print(print_format % (atom, value)) def list_atoms(d, re_obj, low, high): while (low <= high): try: val = d.get_atom_name(low) if (re_obj == None): print_atom(options.format, low, val) elif re_obj.match(val) != None: print_atom(options.format, low, val)
class XObject(object): """Abstract base class for classes communicating with X Server. Encapsulates common methods for communication with X Server. """ # TODO: setting Display, not only default one __DISPLAY = Display() __EVENT_DISPATCHER = EventDispatcher(__DISPLAY) __BAD_ACCESS = error.CatchError(error.BadAccess) # List of recognized key modifiers __KEY_MODIFIERS = { 'Alt': X.Mod1Mask, 'Ctrl': X.ControlMask, 'Shift': X.ShiftMask, 'Super': X.Mod4Mask, 'NumLock': X.Mod2Mask, 'CapsLock': X.LockMask, 'Mod1': X.Mod1Mask, 'Mod2': X.Mod2Mask, 'Mod3': X.Mod3Mask, 'Mod4': X.Mod4Mask, 'Mod5': X.Mod5Mask, } __KEYCODES = {} __WM_TYPE = None def __init__(self, win_id=None): """ `win_id` id of the window to be created, if no id assume it's Window Manager (root window). """ self.__root = self.__DISPLAY.screen().root self._root_id = self.__root.id if win_id and win_id != self.__root.id: # Normal window self._win = self.__DISPLAY.create_resource_object('window', win_id) self.id = win_id else: # WindowManager, act as root window self._win = self.__root self.id = self._win.id @classmethod def set_wm_type(cls, wm_type): """Set window manager's type. This method should not be called directly. Use :meth:`~pywo.core.windows.WindowManager.update_type` instead. """ cls.__WM_TYPE = wm_type @property def wm_type(self): """Return tuple of window manager's type(s).""" return CustomTuple([self.__WM_TYPE]) @classmethod def atom(cls, name): """Return atom with given name.""" return cls.__DISPLAY.intern_atom(name) @classmethod def atom_name(cls, atom): """Return atom's name.""" return cls.__DISPLAY.get_atom_name(atom) def get_property(self, name): """Return property (``None`` if there's no such property).""" atom = self.atom(name) property = self._win.get_full_property(atom, 0) return property def send_event(self, data, event_type, mask): """Send event to the root window.""" event = ClientMessage(window=self._win, client_type=event_type, data=(32, (data))) self.__root.send_event(event, event_mask=mask) def register(self, event_handler): """Register new event handler and update event mask.""" masks = self.__EVENT_DISPATCHER.register(self, event_handler) self.__set_event_mask(masks) def unregister(self, event_handler=None): """Unregister event handler(s) and update event mask. If event_handler is ``None`` all handlers will be unregistered. """ masks = self.__EVENT_DISPATCHER.unregister(self, event_handler) self.__set_event_mask(masks) def _unregister_all(self): """Unregister all event handlers for all windows.""" masks = self.__EVENT_DISPATCHER.unregister() # TODO: this will set event mask only on root window! self.__set_event_mask(masks) def __set_event_mask(self, masks): """Update event mask.""" event_mask = 0 log.debug('Setting %s masks for %s' % ([str(e) for e in masks], self)) for mask in masks: event_mask = event_mask | mask self._win.change_attributes(event_mask=event_mask) def __grab_key(self, keycode, modifiers): """Grab key.""" self._win.grab_key(keycode, modifiers, 1, X.GrabModeAsync, X.GrabModeAsync, onerror=self.__BAD_ACCESS) self.sync() if self.__BAD_ACCESS.get_error(): log.error("Can't use %s" % self.keycode2str(modifiers, keycode)) def grab_key(self, modifiers, keycode, numlock, capslock): """Grab key. Grab key alone, with CapsLock on and/or with NumLock on. """ if numlock in [0, 2] and capslock in [0, 2]: self.__grab_key(keycode, modifiers) if numlock in [0, 2] and capslock in [1, 2]: self.__grab_key(keycode, modifiers | X.LockMask) if numlock in [1, 2] and capslock in [0, 2]: self.__grab_key(keycode, modifiers | X.Mod2Mask) if numlock in [1, 2] and capslock in [1, 2]: self.__grab_key(keycode, modifiers | X.LockMask | X.Mod2Mask) def ungrab_key(self, modifiers, keycode, numlock, capslock): """Ungrab key. Ungrab key alone, with CapsLock on and/or with NumLock on. """ if numlock in [0, 2] and capslock in [0, 2]: self._win.ungrab_key(keycode, modifiers) if numlock in [0, 2] and capslock in [1, 2]: self._win.ungrab_key(keycode, modifiers | X.LockMask) if numlock in [1, 2] and capslock in [0, 2]: self._win.ungrab_key(keycode, modifiers | X.Mod2Mask) if numlock in [1, 2] and capslock in [1, 2]: self._win.ungrab_key(keycode, modifiers | X.LockMask | X.Mod2Mask) def _translate_coords(self, x, y): """Return translated coordinates. Untranslated coordinates are relative to window. Translated coordinates are relative to :ref:`viewport`. """ return self._win.translate_coords(self.__root, x, y) @classmethod def str2modifiers(cls, masks, splitted=False): """Parse modifiers.""" if not splitted: masks = masks.split('-') modifiers = 0 for mask in masks: if not mask: continue mask = mask.capitalize() if mask not in cls.__KEY_MODIFIERS.keys(): raise ValueError('Invalid modifier: %s' % mask) modifiers = modifiers | cls.__KEY_MODIFIERS[mask] return modifiers or X.AnyModifier @classmethod def str2keycode(cls, key): """Parse keycode.""" keysym = XK.string_to_keysym(key) keycode = cls.__DISPLAY.keysym_to_keycode(keysym) cls.__KEYCODES[keycode] = key if keycode == 0: raise ValueError('No key specified!') return keycode @classmethod def str2modifiers_keycode(cls, code, key=''): """Convert `code`, `key` as string(s) into (modifiers, keycode) pair. There must be both modifier(s) and key persent. If you send both modifier(s) and key in one string, they must be separated using '-'. Modifiers must be separated using '-'. Keys are case insensitive. If you want to use upper case use Shift modifier. Only modifiers defined in __KEY_MODIFIERS are valid. For example: "Ctrl-A", "Super-Alt-x" """ if key: code = '-'.join([code, key]) code = code.split('-') key = code[-1] masks = code[:-1] modifiers = cls.str2modifiers(masks, True) keycode = cls.str2keycode(key) return (modifiers, keycode) @classmethod def keycode2str(cls, modifiers, keycode): """Convert `modifiers`, `keycode` pair into string. .. note:: Works ONLY for already registered keycodes! """ key = [] for name, code in cls.__KEY_MODIFIERS.items(): if modifiers & code: key.append(name) key.append(cls.__KEYCODES[keycode]) return '-'.join(key) # TODO: check other XINERAMA methods @classmethod def has_extension(cls, extension): """Return True if given extension is available.""" return cls.__DISPLAY.has_extension(extension) @classmethod def has_xinerama(cls): """Return ``True`` if the Xinerama extension is available.""" return cls.has_extension('XINERAMA') @classmethod def has_shape(cls): """Return ``True`` if the SHAPE extension is available.""" return cls.has_extension('SHAPE') @classmethod def screen_geometries(cls): """Return list of :ref:`screen` :class:`~pywo.core.basic.Geometry`. If Xinerama extension is not avaialbe fallback to non-Xinerama. """ try: geometries = [] for screen in cls.__DISPLAY.xinerama_query_screens().screens: geometries.append( Geometry(screen.x, screen.y, screen.width, screen.height)) return geometries except AttributeError: root = cls.__DISPLAY.root return [Geometry(0, 0, root.screen_width, root.screen_height)] def draw_rectangle(self, x, y, width, height, line): """Draw simple rectangle on screen. .. note: OBSOLETE! Use osd_rectangle instead! """ color = self.__DISPLAY.screen().black_pixel gc = self.__root.create_gc( line_width=line, join_style=X.JoinRound, foreground=color, function=X.GXinvert, subwindow_mode=X.IncludeInferiors, ) self.__root.rectangle(gc, x, y, width, height) def osd_rectangle(self, geometry, color_name, line_width): """Return :class:`OSDRectangle` instance.""" if not self.has_shape(): # NOTE: I believe that (almost) all modern window managers # support SHAPE Extension return color_map = self.__DISPLAY.screen().default_colormap color = color_map.alloc_named_color(color_name) return OSDRectangle(self.__DISPLAY, geometry, color, line_width) def scroll_lock_led(self, on): """Turn on/off ScrollLock LED.""" if on: led_mode = X.LedModeOn else: led_mode = X.LedModeOff self.__DISPLAY.change_keyboard_control(led=3, led_mode=led_mode) @classmethod def flush(cls): """Flush request queue to X Server.""" cls.__DISPLAY.flush() @classmethod def sync(cls): """Flush request queue to X Server, wait until server processes them.""" cls.__DISPLAY.sync()
class XObject(object): """Abstract base class for classes communicating with X Server. Encapsulates common methods for communication with X Server. """ __DISPLAY = Display() __EVENT_DISPATCHER = EventDispatcher(__DISPLAY) __BAD_ACCESS = error.CatchError(error.BadAccess) # List of recognized key modifiers __KEY_MODIFIERS = { 'Alt': X.Mod1Mask, 'Ctrl': X.ControlMask, 'Shift': X.ShiftMask, 'Super': X.Mod4Mask, 'NumLock': X.Mod2Mask, 'CapsLock': X.LockMask } __KEYCODES = {} def __init__(self, win_id=None): """ win_id - id of the window to be created, if no id assume it's Window Manager (root window) """ self.__root = self.__DISPLAY.screen().root if win_id: # Normal window self._win = self.__DISPLAY.create_resource_object('window', win_id) self.id = win_id else: # WindowManager, act as root window self._win = self.__root self.id = self._win.id @classmethod def atom(cls, name): """Return atom with given name.""" return cls.__DISPLAY.intern_atom(name) @classmethod def atom_name(cls, atom): """Return atom's name.""" return cls.__DISPLAY.get_atom_name(atom) def get_property(self, name): """Return property (None if there's no such property).""" atom = self.atom(name) property = self._win.get_full_property(atom, 0) return property def send_event(self, data, type, mask): """Send event from (to?) the root window.""" event = protocol.event.ClientMessage(window=self._win, client_type=type, data=(32, (data))) self.__root.send_event(event, event_mask=mask) def listen(self, event_handler): """Register new event handler and update event mask.""" masks = self.__EVENT_DISPATCHER.register(self, event_handler) self.__set_event_mask(masks) def unlisten(self, event_handler=None): """Unregister event handler(s) and update event mask. If event_handler is None all handlers will be unregistered. """ masks = self.__EVENT_DISPATCHER.unregister(self, event_handler) self.__set_event_mask(masks) def __set_event_mask(self, masks): """Update event mask.""" event_mask = 0 logging.debug('Setting %s masks for window %s' % ([str(e) for e in masks], self.id)) for mask in masks: event_mask = event_mask | mask self._win.change_attributes(event_mask=event_mask) def __grab_key(self, keycode, modifiers): """Grab key.""" self._win.grab_key(keycode, modifiers, 1, X.GrabModeAsync, X.GrabModeAsync, onerror=self.__BAD_ACCESS) self.sync() if self.__BAD_ACCESS.get_error(): logging.error("Can't use %s" % self.keycode2str(modifiers, keycode)) def grab_key(self, modifiers, keycode, numlock, capslock): """Grab key. Grab key alone, with CapsLock on and/or with NumLock on. """ if numlock in [0, 2] and capslock in [0, 2]: self.__grab_key(keycode, modifiers) if numlock in [0, 2] and capslock in [1, 2]: self.__grab_key(keycode, modifiers | X.LockMask) if numlock in [1, 2] and capslock in [0, 2]: self.__grab_key(keycode, modifiers | X.Mod2Mask) if numlock in [1, 2] and capslock in [1, 2]: self.__grab_key(keycode, modifiers | X.LockMask | X.Mod2Mask) def ungrab_key(self, modifiers, keycode, numlock, capslock): """Ungrab key. Ungrab key alone, with CapsLock on and/or with NumLock on. """ if numlock in [0, 2] and capslock in [0, 1]: self._win.ungrab_key(keycode, modifiers) if numlock in [0, 2] and capslock in [1, 2]: self._win.ungrab_key(keycode, modifiers | X.LockMask) if numlock in [1, 2] and capslock in [0, 2]: self._win.ungrab_key(keycode, modifiers | X.Mod2Mask) if numlock in [1, 2] and capslock in [1, 2]: self._win.ungrab_key(keycode, modifiers | X.LockMask | X.Mod2Mask) def draw_rectangle(self, x, y, width, height, line): color = self.__DISPLAY.screen().black_pixel gc = self.__root.create_gc( line_width=line, #join_style=X.JoinRound, foreground=color, function=X.GXinvert, subwindow_mode=X.IncludeInferiors, ) self.__root.rectangle(gc, x, y, width, height) def _translate_coords(self, x, y): """Return translated coordinates. Untranslated coordinates are relative to window. Translated coordinates are relative to desktop. """ return self._win.translate_coords(self.__root, x, y) @classmethod def str2modifiers(cls, masks, splitted=False): # TODO: Check this part... not sure why it looks like that... if not splitted: masks = masks.split('-') modifiers = 0 if masks[0]: for mask in masks: if not mask in cls.__KEY_MODIFIERS.keys(): continue modifiers = modifiers | cls.__KEY_MODIFIERS[mask] else: modifiers = X.AnyModifier return modifiers @classmethod def str2keycode(cls, key): keysym = XK.string_to_keysym(key) keycode = cls.__DISPLAY.keysym_to_keycode(keysym) cls.__KEYCODES[keycode] = key return keycode @classmethod def str2modifiers_keycode(cls, code, key=''): """Convert key as string(s) into (modifiers, keycode) pair. There must be both modifier(s) and key persent. If you send both modifier(s) and key in one string, they must be separated using '-'. Modifiers must be separated using '-'. Keys are case insensitive. If you want to use upper case use Shift modifier. Only modifiers defined in __KEY_MODIFIERS are valid. For example: "Ctrl-A", "Super-Alt-x" """ if key: code = '-'.join([code, key]) code = code.split('-') key = code[-1] masks = code[:-1] modifiers = cls.str2modifiers(masks, True) keycode = cls.str2keycode(key) return (modifiers, keycode) @classmethod def keycode2str(cls, modifiers, keycode): """Convert key as (modifiers, keycode) pair into string. Works ONLY for already registered keycodes! """ key = [] for name, code in cls.__KEY_MODIFIERS.items(): if modifiers & code: key.append(name) key.append(cls.__KEYCODES[keycode]) return '-'.join(key) @classmethod def flush(cls): """Flush request queue to X Server.""" cls.__DISPLAY.flush() @classmethod def sync(cls): """Flush request queue to X Server, wait until server processes them.""" cls.__DISPLAY.sync()
def __init__(self, display, error, plugin, bar): gtk.Widget.__init__(self) # Define widget value and set to default self.curr_x = 1 self.curr_y = 1 # references to Xlib self.dsp = display.Display() self.scr = self.dsp.screen() self.root = self.scr.root self.error = error.CatchError() self.plugin = plugin self.bar = bar # Is the Xwindow realized yet? if not, can cause problems with certain functions self.realized = 0 ourmask = (X.ButtonPressMask | X.ButtonReleaseMask | X.ExposureMask) # Create an X window to hold icons self.wind = self.root.create_window(0, 0, 1, 10, 0, self.scr.root_depth, window_class=X.InputOutput, visual=X.CopyFromParent, colormap=X.CopyFromParent, event_mask=ourmask) self.wind.change_property(self.dsp.intern_atom("_NET_WM_DESKTOP"), Xatom.CARDINAL, 32, [0xffffffffL]) # set background colour to match the screenlet background col = hex(string.atoi(BG_COLOR[1:], 16)) self.intColour = int(col, 16) self.wind.change_attributes(background_pixel=self.intColour) # Create an empty Object, this will contain all the data on icons # to be added, and all currently managed self.tray = Obj(id="tray", tasks={}, order=[], first=0, last=0, window=self.wind) # Create a non-visible window to be the selection owner self._OPCODE = self.dsp.intern_atom("_NET_SYSTEM_TRAY_OPCODE") self.manager = self.dsp.intern_atom("MANAGER") self.selection = self.dsp.intern_atom("_NET_SYSTEM_TRAY_S%d" % self.dsp.get_default_screen()) self.selowin = self.scr.root.create_window(-1, -1, 1, 1, 0, self.scr.root_depth) owner = self.dsp.get_selection_owner(self.selection) if owner != X.NONE: Core.logINFO("Another System Tray is already running") print "Another System Tray is already running" else: self.selowin.set_selection_owner(self.selection, X.CurrentTime) self.tr__sendEvent( self.root, self.manager, [X.CurrentTime, self.selection, self.selowin.id], (X.StructureNotifyMask)) self.tr__setProps(self.dsp, self.wind) # Set a list of Properties that we'll need self.dsp.flush() # Show the window and flush the display plugin.trayWorks(self)
def __init__(self, screen, window, *args, **keys): wmanager.WindowProxyBase.__init__(self, screen, window, *args, **keys) # Create a proxy window that will contain the real window as a # clone of the source window. g = window.get_geometry() a = window.get_attributes() # Never trust an X server. The visual and depth as returned # by the methods just called can result in a BadMatch, despite # the reasonable assumption that if the client could create a # window with those specs, then we can also do it. # The reason for this sad state of affairs is OpenGL: a GLX # visual that have 24 bits of colour info _and_ 8 bits of # alpha info appears to a non-GL application (e.g. plwm) to # have depth 24, but you can't create windows of that depth on # it. An example of an application that does this is # OpenOffice 2.0, which is how I found it. # In this case, just create a window on the default visual for # the proxy and disable composition for this client (as plcm # require that the proxy and the client windows use the same # visual). self._composition_disabled = 0 ec = error.CatchError(error.BadMatch) self._proxy = screen.root.create_window(g.x, g.y, g.width, g.height, g.border_width, g.depth, a.win_class, a.visual, onerror=ec) # Check if the mismatch was triggered self._wm.display.sync() if ec.get_error(): wmanager.debug('composite', 'strange visual, disabling composition for %s', window) self._composition_disabled = 1 self._proxy = screen.root.create_window(g.x, g.y, g.width, g.height, g.border_width, X.CopyFromParent) # The proxy window must have the SubstructureRedirectMask set, so # we still get MapRequest, ConfigureRequest etc for the client window. self._proxy.change_attributes(event_mask=X.SubstructureRedirectMask) # Reparent the real window into the proxy window, blocking any # UnmapNotify that might generate screen.event_mask.block(X.SubstructureNotifyMask) window.configure(border_width=0) window.reparent(self._proxy, 0, 0) screen.event_mask.unblock(X.SubstructureNotifyMask) # Some methods can be overridden simply by only working on the proxy window self.get_geometry = self._proxy.get_geometry self.circulate = self._proxy.circulate self.reparent = self._proxy.reparent self._screen.add_proxy_window(self._proxy, window)