Exemple #1
0
def change_workspace(name):
	print(f"Changing to {name}", flush=True)
	display = Xlib.display.Display()
	screen = display.screen()
	root = screen.root

	w, h = screen.width_in_pixels, screen.height_in_pixels
	try:
		hue = int(name)/10+1/3
	except:
		hue = mkrand(name).random()

	if name not in colors:
		colors[name] = gen_colors(hue)
	proc = subprocess.Popen(["xrdb", "-merge"], stdin=subprocess.PIPE)
	proc.communicate(input=colors[name].encode())
	proc.wait()
	i3.command("reload")

	if (name, w, h) not in backgrounds:
		backgrounds[name, w, h] = root.create_pixmap(w, h, screen.root_depth)
		gen_bg(backgrounds[name, w, h], hue, name)
	id = backgrounds[name, w, h].id
	root.change_property(display.get_atom("_XROOTPMAP_ID"), Xatom.PIXMAP, 32, [id])
	root.change_property(display.get_atom("ESETROOT_PMAP_ID"), Xatom.PIXMAP, 32, [id])
	root.change_attributes(background_pixmap=id)
	root.clear_area(0, 0, w, h)
	display.sync()
Exemple #2
0
def set_wm_state(window, action,
                 data):  # Function to set window states via Xlib
    # Thanks parkouss for help with this (https://github.com/parkouss/pyewmh/blob/master/ewmh/ewmh.py)
    if action == "_NET_WM_STATE":
        data[1] = display.get_atom(
            data[1], 1
        )  # Get the int for associated action, as X wants this in data array, not a string

    event = protocol.event.ClientMessage(window=window,
                                         client_type=display.get_atom(action),
                                         data=(32, data))

    screen.root.send_event(event, event_mask=(X.SubstructureRedirectMask))
Exemple #3
0
def pager_auto_detect(display, screen, root):
    '''Auto-detects pager to use.'''
    pager = None
    
    grid = root.get_full_property(display.get_atom('_NET_DESKTOP_LAYOUT'), 0)
    size = root.get_full_property(display.get_atom("_NET_DESKTOP_GEOMETRY"), 0)
    
    if (grid != None and grid.value[2] > 1 and grid.value[1] > 1):
        return VirtualDesktopPager(display, screen, root)
    elif (hasattr(size, 'value') and (size.value[1]>screen.height_in_pixels or size.value[0]>screen.width_in_pixels)):
        return ViewportPager(display, screen, root)
    else:
        # defaults to VirtualDesktop
        return VirtualDesktopPager(display, screen, root)
Exemple #4
0
def pager_auto_detect(display, screen, root):
    '''Auto-detects pager to use.'''
    pager = None

    grid = root.get_full_property(display.get_atom('_NET_DESKTOP_LAYOUT'), 0)
    size = root.get_full_property(display.get_atom("_NET_DESKTOP_GEOMETRY"), 0)

    if (grid != None and grid.value[2] > 1 and grid.value[1] > 1):
        return VirtualDesktopPager(display, screen, root)
    elif (hasattr(size, 'value')
          and (size.value[1] > screen.height_in_pixels
               or size.value[0] > screen.width_in_pixels)):
        return ViewportPager(display, screen, root)
    else:
        # defaults to VirtualDesktop
        return VirtualDesktopPager(display, screen, root)
Exemple #5
0
def get_window_pid(window: Window) -> str:
    atom = display.get_atom("_NET_WM_PID")
    pid_property = window.get_full_property(atom, X.AnyPropertyType)
    if pid_property:
        pid = pid_property.value[-1]
        return pid
    else:
        # TODO: Needed?
        raise Exception("pid_property was None")
Exemple #6
0
def change_workspace(name):
    display = Xlib.display.Display()
    screen = display.screen()
    root = screen.root

    w, h = screen.width_in_pixels, screen.height_in_pixels

    if (name, w, h) not in background_cache:
        background_cache[name, w, h] = gen_bg(
            root.create_pixmap(w, h, screen.root_depth), name)

    id = background_cache[name, w, h].id
    root.change_property(display.get_atom("_XROOTPMAP_ID"), Xatom.PIXMAP, 32,
                         [id])
    root.change_property(display.get_atom("ESETROOT_PMAP_ID"), Xatom.PIXMAP,
                         32, [id])
    root.change_attributes(background_pixmap=id)
    root.clear_area()
    display.sync()
Exemple #7
0
def _get_current_window_id() -> Optional[int]:
    atom = display.get_atom("_NET_ACTIVE_WINDOW")
    window_prop = screen.root.get_full_property(atom, X.AnyPropertyType)

    if window_prop is None:
        logger.warning("window_prop was None")
        return None

    # window_prop may contain more than one value, but it seems that it's always the first we want.
    # The second has in my attempts always been 0 or rubbish.
    window_id = window_prop.value[0]
    return window_id if window_id != 0 else None
 def __update_focus_cb(self, command, sync=False):
     # Check FocusIn/FocusOut events
     if self.focus:
         focus_in = None
         focus_out = None
         for i in range(display.pending_events()):
             event = display.next_event()
             if event.type == Xlib.X.FocusIn:
                 focus_in = event.window
             elif event.type == Xlib.X.FocusOut:
                 focus_out = event.window
         if focus_in == self.focus:
             if focus_out != self.focus:
                 # This is ugly workaround, but necessary to avoid a
                 # problem that the language bar doesn't appear after
                 # moving to other workspace in Ubuntu Unity desktop.
                 # If old version of ibus.el which doesn't define
                 # `ibus-redo-focus-in-cb' is running on Emacs, the
                 # following message will just be ignored and take no effect.
                 print_command('ibus_redo_focus_in_cb')
             if sync:
                 print_command(command, focus_in.id)
             return True
     # Main part
     focus = self.display.get_input_focus().focus
     try:
         # get_input_focus() may return an integer 0 that query_tree()
         # causes AttributeError when X session is going to logout.
         tree = focus.query_tree()
         # In Ubuntu's Unity desktop, get_input_focus() often returns root
         # window incorrectly after changing workspace.
         if focus != tree.root:
             if not (focus.get_wm_class() or focus.get_wm_name()):
                 focus = tree.parent
             if focus != self.focus or sync:
                 print_command(command, focus.id)
                 focus.change_attributes(event_mask=Xlib.X.FocusChangeMask)
                 self.focus = focus
             return True
     except AttributeError:
         if sync:
             print_command(command, 0)
         return True
     # Fallback
     atom = display.get_atom("_NET_ACTIVE_WINDOW", True)
     focus_id = tree.root.get_property(atom, Xlib.Xatom.WINDOW, 0,
                                       1).value[0]
     focus = display.create_resource_object("window", focus_id)
     if focus != self.focus or sync:
         print_command(command, focus_id)
         focus.change_attributes(event_mask=Xlib.X.FocusChangeMask)
         self.focus = focus
     return True
 def __update_focus_cb(self, command, sync=False):
     # Check FocusIn/FocusOut events
     if self.focus:
         focus_in = None
         focus_out = None
         for i in range(display.pending_events()):
             event = display.next_event()
             if event.type == Xlib.X.FocusIn:
                 focus_in = event.window
             elif event.type == Xlib.X.FocusOut:
                 focus_out = event.window
         if focus_in == self.focus:
             if focus_out != self.focus:
                 # This is ugly workaround, but necessary to avoid a
                 # problem that the language bar doesn't appear after
                 # moving to other workspace in Ubuntu Unity desktop.
                 # If old version of ibus.el which doesn't define
                 # `ibus-redo-focus-in-cb' is running on Emacs, the
                 # following message will just be ignored and take no effect.
                 print_command('ibus_redo_focus_in_cb')
             if sync:
                 print_command(command, focus_in.id)
             return True
     # Main part
     focus = self.display.get_input_focus().focus
     try:
         # get_input_focus() may return an integer 0 that query_tree()
         # causes AttributeError when X session is going to logout.
         tree = focus.query_tree()
         # In Ubuntu's Unity desktop, get_input_focus() often returns root
         # window incorrectly after changing workspace.
         if focus != tree.root:
             if not (focus.get_wm_class() or focus.get_wm_name()):
                 focus = tree.parent
             if focus != self.focus or sync:
                 print_command(command, focus.id)
                 focus.change_attributes(event_mask=Xlib.X.FocusChangeMask)
                 self.focus = focus
             return True
     except AttributeError:
         if sync:
             print_command(command, 0)
         return True
     # Fallback
     atom = display.get_atom("_NET_ACTIVE_WINDOW", True)
     focus_id = tree.root.get_property(atom, Xlib.Xatom.WINDOW, 0, 1).value[0]
     focus = display.create_resource_object("window", focus_id)
     if focus != self.focus or sync:
         print_command(command, focus_id)
         focus.change_attributes(event_mask=Xlib.X.FocusChangeMask)
         self.focus = focus
     return True
Exemple #10
0
def _guess_active_window():
    display = Xlib.display.Display()
    wm = ewmh.EWMH(display)
    active_win = wm.getActiveWindow()

    if not active_win:
        debug('no active window from ewmh')
        return None, None

    window_names = []
    window_names.append(wm.getWmName(active_win))

    wm_name = active_win.get_full_property(display.get_atom('WM_NAME'), X.AnyPropertyType)
    debug('WM_NAME original %s' % wm_name.value)
    wm_name = _from_compound_text(wm_name.value)
    debug('WM_NAME decoded %s' % wm_name)
    if wm_name not in window_names:
        window_names.append(wm_name)

    gdk_display = Gdk.Display.get_default()
    gdk_window = GdkX11.X11Window.foreign_new_for_display(gdk_display, active_win.id)

    gdk_frame_rect = gdk_window.get_frame_extents()
    gdk_frame_rect = (gdk_frame_rect.x, gdk_frame_rect.y,
                      gdk_frame_rect.width, gdk_frame_rect.height)
    gdk_geom_rect = gdk_window.get_geometry()

    debug('active window %s' % (window_names,))
    debug('active window id %s' % active_win.id)

    match = []
    for win in _atspi_windows():
        atspi_name = str(win)
        matched_names = [name
                         for name in window_names
                         if atspi_name.endswith('| %s]' % name)]
        debug('win with name %s, matched %s' % (atspi_name, matched_names))
        if matched_names and _geometry_match(win, gdk_frame_rect, gdk_geom_rect):
            match.append(win)

    if not match:
        debug('no atspi window matching "%s"' % window_names)
        return None, None

    if len(match) > 1:
        debug('too many atspi windows matching "%s"' % window_names)
        return None, None

    return match[0], gdk_window
Exemple #11
0
def atom_s2i(string):
  i = display.get_atom(string, only_if_exists=True)
  if i == Xlib.X.NONE:
    raise ValueError('No Atom interned with that name.')
  else:
    return i
Exemple #12
0
def atom_s2i(string):
  i = display.get_atom(string, only_if_exists=False)
  if i == Xlib.X.NONE:
    raise ValueError('No Atom interned with that name.')
  else:
    return i
Exemple #13
0
def _guess_active_window():
    display = Xlib.display.Display()
    root = display.screen().root

    active_win = None

    active_win_atom = root.get_full_property(
        display.get_atom('_NET_ACTIVE_WINDOW'), X.AnyPropertyType)
    if active_win_atom and active_win_atom.value:
        active_win = display.create_resource_object('window',
                                                    active_win_atom.value[0])

    if not active_win:
        debug('no active window found by properties')
        return None, None

    window_names = []

    atom = active_win.get_full_property(
        display.get_atom('_NET_WM_VISIBLE_NAME'), X.AnyPropertyType)

    if atom:
        window_names.append(atom.value)

    wm_name = active_win.get_full_property(display.get_atom('WM_NAME'),
                                           X.AnyPropertyType)
    debug('WM_NAME original %s' % wm_name.value)
    wm_name = _from_compound_text(wm_name.value)
    debug('WM_NAME decoded %s' % wm_name)
    if wm_name not in window_names:
        window_names.append(wm_name)

    gdk_display = Gdk.Display.get_default()
    gdk_window = GdkX11.X11Window.foreign_new_for_display(
        gdk_display, active_win.id)

    gdk_frame_rect = gdk_window.get_frame_extents()
    gdk_frame_rect = (gdk_frame_rect.x, gdk_frame_rect.y, gdk_frame_rect.width,
                      gdk_frame_rect.height)
    gdk_geom_rect = gdk_window.get_geometry()

    debug('active window %s' % (window_names, ))
    debug('active window id %s' % active_win.id)

    match = []
    for win in _atspi_windows():
        atspi_name = str(win)
        matched_names = [
            name for name in window_names
            if atspi_name.endswith('| %s]' % name)
        ]
        debug('win with name %s, matched %s' % (atspi_name, matched_names))
        if matched_names and _geometry_match(win, gdk_frame_rect,
                                             gdk_geom_rect):
            match.append(win)

    if not match:
        debug('no atspi window matching "%s"' % window_names)
        return None, None

    if len(match) > 1:
        debug('too many atspi windows matching "%s"' % window_names)
        return None, None

    return match[0], gdk_window