Exemple #1
0
 def __init__(self, id, windows=None, name=None):
     self.id = id
     if not name:
         name = "(desktop %s)" % id(self)
     self.log = Log("desktop %s" % name)
     if not windows:
         windows = []
     self.windows = windows
     self.name = name
     self.cur_focus = None
     self.prev_focus = None
     self.were_mapped = []
     self.hidden = True  # TODO: rename to active
Exemple #2
0
 def __init__(self, wm, wid, atoms, mapped=True):
     from wm import WM  # TODO: dirtyhack to avoid circular imports
     assert isinstance(wm, WM), "wm must be an instance of WM"
     assert isinstance(wid, int), "wid must be int"
     self.wid = wid
     self.wm = wm
     self._conn = self.wm._conn
     self.prev_geometry = None
     self.props = Props(conn=self._conn, window=self, atoms=atoms)
     self.update_name()  # TODO: this is not updated
     self.update_window_type()
     # do it after self.name is set (so repr works)
     self.log = Log(self)
     self.mapped = mapped
     self.hints = {}
     self.update_wm_hints()
     # subscribe for notifications
     self._conn.core.ChangeWindowAttributesChecked(wid, CW.EventMask,
                                                   [EventMask.EnterWindow])
Exemple #3
0
    def __init__(self, xcb_setup, conn):
        self._conn = conn
        self.code_to_syms = {}
        self.first_sym_to_code = {}
        self.log = Log("keyboard")

        first = xcb_setup.min_keycode
        count = xcb_setup.max_keycode - xcb_setup.min_keycode + 1
        q = self._conn.core.GetKeyboardMapping(first, count).reply()
        assert len(q.keysyms) % q.keysyms_per_keycode == 0,  \
            "Wrong keyboard mapping from X server??"

        for i in range(len(q.keysyms) // q.keysyms_per_keycode):
            self.code_to_syms[first + i] = \
                q.keysyms[
                    i * q.keysyms_per_keycode:(i + 1) * q.keysyms_per_keycode]
        for k, s in self.code_to_syms.items():
            if s[0] and not s[0] in self.first_sym_to_code:
                self.first_sym_to_code[s[0]] = k
Exemple #4
0
from useful.log import Log
from defs import ModMasks

from subprocess import Popen
from itertools import chain
import shlex
import os
log = Log("utils")


def run(cmd):
    if isinstance(cmd, str):
        cmd = shlex.split(cmd)
    # os.setpgrp supressses signal forwarding to children  # TODO: test this
    return Popen(cmd, preexec_fn=os.setpgrp)


def run_(cmd):
    try:
        return run(cmd)
    except Exception as err:
        log.run_.error("failed to exec %s: %s" % (cmd, err))


def get_modmask(modifiers):
    result = 0
    for m in modifiers:
        assert m in ModMasks, "unknown modifier %s" % m
        result |= ModMasks[m]
    return result
Exemple #5
0
    def __init__(self, display=None, desktops=None, loop=None):
        self.log = Log("WM")
        # INIT SOME BASIC STUFF
        self.hook = Hook()
        self.windows = {}  # mapping between window id and Window
        self.win2desk = {}

        if not display:
            display = os.environ.get("DISPLAY")

        try:
            self._conn = xcffib.connect(display=display)
        except xcffib.ConnectionException:
            sys.exit("cannot connect to %s" % display)

        self.atoms = AtomVault(self._conn)
        self.desktops = desktops or [Desktop()]
        self.cur_desktop = self.desktops[0]
        self.cur_desktop.show()

        # CREATE ROOT WINDOW
        xcb_setup = self._conn.get_setup()
        xcb_screens = [i for i in xcb_setup.roots]
        self.xcb_default_screen = xcb_screens[self._conn.pref_screen]
        root_wid = self.xcb_default_screen.root
        self.root = Window(self, wid=root_wid, atoms=self.atoms, mapped=True)
        self.windows[root_wid] = self.root
#        for desktop in self.desktops:
#            desktop.windows.append(self.root)

        self.root.set_attr(
            eventmask=(
                  EventMask.StructureNotify
                | EventMask.SubstructureNotify
                | EventMask.FocusChange
                # | EventMask.SubstructureRedirect
                | EventMask.EnterWindow
                # | EventMask.LeaveWindow
                # | EventMask.PropertyChange
                | EventMask.OwnerGrabButton
            )
        )

        # INFORM X WHICH FEATURES WE SUPPORT
        self.root.props[self.atoms._NET_SUPPORTED] = [self.atoms[a] for a in SUPPORTED_ATOMS]

        # PRETEND TO BE A WINDOW MANAGER
        supporting_wm_check_window = self.create_window(-1, -1, 1, 1)
        supporting_wm_check_window.props['_NET_WM_NAME'] = "SWM"
        self.root.props['_NET_SUPPORTING_WM_CHECK'] = supporting_wm_check_window.wid
        self.root.props['_NET_NUMBER_OF_DESKTOPS'] = len(self.desktops)
        self.root.props['_NET_CURRENT_DESKTOP'] = 0

        # TODO: set cursor

        # EVENTS THAT HAVE LITTLE USE FOR US...
        self.ignoreEvents = {
            "KeyRelease",
            "ReparentNotify",
            # "CreateNotify",
            # DWM handles this to help "broken focusing windows".
            # "MapNotify",
            "ConfigureNotify",
            "LeaveNotify",
            "FocusOut",
            "FocusIn",
            "NoExposure",
        }
        # KEYBOARD
        self.kbd = Keyboard(xcb_setup, self._conn)
        self.mouse = Mouse(conn=self._conn, root=self.root)

        # FLUSH XCB BUFFER
        self.xsync()    # apply settings
        # the event loop is not yet there, but we might have some pending
        # events...
        self._xpoll()
        # TODO: self.grabMouse

        # NOW IT'S TIME TO GET PHYSICAL SCREEN CONFIGURATION
        self.xrandr = Xrandr(root=self.root, conn=self._conn)

        # TODO: self.update_net_desktops()

        # SETUP EVENT LOOP
        if not loop:
            loop = asyncio.new_event_loop()
        self._eventloop = loop
        self._eventloop.add_signal_handler(signal.SIGINT, self.stop)
        self._eventloop.add_signal_handler(signal.SIGTERM, self.stop)
        self._eventloop.add_signal_handler(signal.SIGCHLD, self.on_sigchld)
        self._eventloop.set_exception_handler(
            lambda loop, ctx: self.log.error(
                "Got an exception in {}: {}".format(loop, ctx))
        )
        fd = self._conn.get_file_descriptor()
        self._eventloop.add_reader(fd, self._xpoll)

        # HANDLE STANDARD EVENTS
        self.hook.register("MapRequest", self.on_map_request)
        self.hook.register("MapNotify", self.on_map_notify)
        self.hook.register("UnmapNotify", self.on_window_unmap)
        self.hook.register("KeyPress", self.on_key_press)
        # self.hook.register("KeyRelease", self.on_key_release)
        # self.hook.register("CreateNotify", self.on_window_create)
        self.hook.register("PropertyNotify", self.on_property_notify)
        self.hook.register("ClientMessage", self.on_client_message)
        self.hook.register("DestroyNotify", self.on_window_destroy)
        self.hook.register("EnterNotify", self.on_window_enter)
        self.hook.register("ConfigureRequest", self.on_configure_window)
        self.hook.register("MotionNotify", self.on_mouse_event)
        self.hook.register("ButtonPress", self.on_mouse_event)
        self.hook.register("ButtonRelease", self.on_mouse_event)
Exemple #6
0
from useful.prettybt import prettybt
sys.excepthook = prettybt

# USEFUL ALIASES
up, down, left, right = 'Up', 'Down', 'Left', 'Right'
win = fail = 'mod4'
ctrl = control = 'control'
shift = 'shift'
caps = 'Caps_Lock'
alt = 'mod1'
tab = 'Tab'
MouseL = 1
MouseC = 2
MouseR = 3
log = Log("USER HOOKS")
osd = OSD()

mod = win

# PRE-INIT
# switch to english just in case
run_("setxkbmap -layout en")

# create event loop and setup text GUI
loop = asyncio.new_event_loop()
# logwidget = gui(loop=loop)
# Log.file = logwidget

# INIT
num_desktops = 4
Exemple #7
0
 def __init__(self):
     self.cb_map = defaultdict(list)
     self.log = Log("hook")
     self.suppressed = set()