Example #1
0
 def __init__(self, x11_connection):
     self.display = x11_connection
     self.windows = set()
     self.screen = self.display.screen()
     self.root = self.screen.root
     self.ewmh = ewmh.EWMH(self.display, self.root)
     self.hlwm = hlwm
Example #2
0
    def init_window_dimensions(self):
        if IS_WINDOWS:
            max_width, max_height = map(
                win32api.GetSystemMetrics,
                (win32con.SM_CXFULLSCREEN, win32con.SM_CYFULLSCREEN))
        elif IS_MACOS:
            frame_size = AppKit.NSScreen.mainScreen().frame().size
            max_width, max_height = map(int,
                                        (frame_size.width, frame_size.height))
        elif IS_LINUX:
            self.ewmh = ewmh.EWMH()
            desktop = self.ewmh.getCurrentDesktop()
            max_width, max_height = self.ewmh.getWorkArea()[4 * desktop + 2:4 *
                                                            (desktop + 1)]

        self.width = min(self.conf.width, max_width)
        self.height = min(self.conf.height, max_height)
        self.x_pos, self.y_pos = (max_width - self.width) // 2, (
            max_height - self.height) // 2

        # 15 pixel buffer between max screen dimension, for maximizing window
        self.should_maximize = self.width >= (
            max_width - 15) or self.height >= (max_height - 15)
        logger.info(
            f'Dimensions: {self.width}x{self.height} [{max_width}x{max_height} max] '
            f'@ ({self.x_pos}, {self.y_pos}), will maximize: {self.should_maximize}'
        )
Example #3
0
 def set_position_normal(self):
     e = ewmh.EWMH()
     for w in e.getClientList():
         if w.get_wm_name() == 'mynotes%s' % self.id:
             e.setWmState(w, 0, '_NET_WM_STATE_BELOW')
             e.setWmState(w, 0, '_NET_WM_STATE_ABOVE')
     e.display.flush()
     self.save_note()
Example #4
0
    def listen_for_events(self) -> None:
        """
        Listen for X11 events covering window creation and movement
        between workspaces and, upon receiving such an event, count
        the number of windows on the currently focused workspace.

        If the number of open windows is equal to or above the set
        threshold, initiate a blur, otherwise an unblur transition.

        The following events are monitored and should be enough to
        cover any situation in which a blur operation is necessary:

        MapNotify is sent when windows are drawn, e.g. a window
          - is opened on the current workspace
          - is moved to the current workspace
          - is shown by switching to the workspace it's on

        UnmapNotify is sent when windows are undrawn, e.g. a window
          - on the current workspace is closed
          - is moved to a different workspace
          - is hidden by switching to a different workspace

        :return: None
        """
        # Connect to X server
        display = Xlib.display.Display()
        ewmh_instance = ewmh.EWMH(display)

        root = display.screen().root
        root.change_attributes(event_mask=X.SubstructureNotifyMask)

        print(':: Ready and waiting for window events...')

        blur = Transition(0, 0)
        unblur = Transition(0, 0)

        while True:
            event = display.next_event()

            if event.type in (X.MapNotify, X.UnmapNotify):
                if wallpaper.changed_externally():
                    wallpaper.set_original(wallpaper.get_current())

                    if self.frames_are_outdated():
                        self.generate_transition_frames()

                window_count = window.count_on_current_ws(
                    self.ignored_classes, ewmh_instance)
                blur, unblur = self.init_transition(window_count, blur, unblur)
Example #5
0
#!/usr/bin/python
# -*- coding: utf-8 -*-
import os
import sys
import platform
import time
import Xlib.X
import Xlib.display
import ewmh
import pyautogui
from pygetwindow import PyGetWindowException, pointInRect, BaseWindow, Rect, Point, Size

DISP = Xlib.display.Display()
ROOT = DISP.screen().root
EWMH = ewmh.EWMH(_display=DISP, root=ROOT)

# WARNING: Changes are not immediately applied, specially for hide/show (unmap/map)
#          You may set wait to True in case you need to effectively know if/when change has been applied.
WAIT_ATTEMPTS = 10
WAIT_DELAY = 0.025  # Will be progressively increased on every retry

# These _NET_WM_STATE_ constants are used to manage Window state and are documented at
# https://ewmh.readthedocs.io/en/latest/ewmh.html
STATE_NULL = 0
STATE_MODAL = '_NET_WM_STATE_MODAL'
STATE_STICKY = '_NET_WM_STATE_STICKY'
STATE_MAX_VERT = '_NET_WM_STATE_MAXIMIZED_VERT'
STATE_MAX_HORZ = '_NET_WM_STATE_MAXIMIZED_HORZ'
STATE_SHADED = '_NET_WM_STATE_SHADED'
STATE_SKIP_TASKBAR = '_NET_WM_STATE_SKIP_TASKBAR'
STATE_SKIP_PAGER = '_NET_WM_STATE_SKIP_PAGER'
Example #6
0
            if sleeping:
                wake_windows_up()

                sleeping = False

        sleep(0.25)


if __name__ == "__main__":
    uid = os.getuid()
    home = os.getenv("HOME")

    system_whitelist = "/etc/sleep-walker/whitelist"
    user_whitelist = "%s/.sleep-walker/whitelist" % home

    ewmh = ewmh.EWMH()
    xc = xcovered.XCovered(ewmh)

    # get_idle_time(xlib, dpy, root, xss)
    xlib = ctypes.cdll.LoadLibrary('libX11.so')
    dpy = xlib.XOpenDisplay(os.environ['DISPLAY'])

    root = xlib.XDefaultRootWindow(dpy)
    xss = ctypes.cdll.LoadLibrary('libXss.so.1')

    timeout = 5.0  # debug: need to find the sweet spot...
    notifications = True

    whitelist = load_whitelist()

    signal.signal(signal.SIGTERM, sigterm_handler)
Example #7
0
    def __init__(self):
        Tk.__init__(self)
        self.withdraw()
        self.notes = {}
        self.img = PhotoImage(file=cst.IM_ICON)
        self.icon = PhotoImage(master=self, file=cst.IM_ICON_48)
        self.iconphoto(True, self.icon)

        self.ewmh = ewmh.EWMH()

        style = Style(self)
        style.theme_use("clam")

        self.close1 = PhotoImage("img_close", file=cst.IM_CLOSE)
        self.close2 = PhotoImage("img_closeactive", file=cst.IM_CLOSE_ACTIVE)
        self.roll1 = PhotoImage("img_roll", file=cst.IM_ROLL)
        self.roll2 = PhotoImage("img_rollactive", file=cst.IM_ROLL_ACTIVE)

        self.protocol("WM_DELETE_WINDOW", self.quit)
        self.icon = tktray.Icon(self, docked=True)

        # --- Menu
        self.menu_notes = Menu(self.icon.menu, tearoff=False)
        self.hidden_notes = {cat: {} for cat in CONFIG.options("Categories")}
        self.menu_show_cat = Menu(self.icon.menu, tearoff=False)
        self.menu_hide_cat = Menu(self.icon.menu, tearoff=False)
        self.icon.configure(image=self.img)
        self.icon.menu.add_command(label=_("New Note"), command=self.new)
        self.icon.menu.add_separator()
        self.icon.menu.add_command(label=_('Show All'), command=self.show_all)
        self.icon.menu.add_cascade(label=_('Show Category'),
                                   menu=self.menu_show_cat)
        self.icon.menu.add_cascade(label=_('Show Note'),
                                   menu=self.menu_notes,
                                   state="disabled")
        self.icon.menu.add_separator()
        self.icon.menu.add_command(label=_('Hide All'), command=self.hide_all)
        self.icon.menu.add_cascade(label=_('Hide Category'),
                                   menu=self.menu_hide_cat)
        self.icon.menu.add_separator()
        self.icon.menu.add_command(label=_("Preferences"), command=self.config)
        self.icon.menu.add_command(label=_("Note Manager"),
                                   command=self.manage)
        self.icon.menu.add_separator()
        self.icon.menu.add_command(label=_("Backup Notes"),
                                   command=self.backup)
        self.icon.menu.add_command(label=_("Restore Backup"),
                                   command=self.restore)
        self.icon.menu.add_separator()
        self.icon.menu.add_command(label=_("Export"),
                                   command=self.export_notes)
        self.icon.menu.add_command(label=_("Import"),
                                   command=self.import_notes)
        self.icon.menu.add_separator()
        self.icon.menu.add_command(label=_('Check for Updates'),
                                   command=lambda: UpdateChecker(self))
        self.icon.menu.add_command(label=_('About'),
                                   command=lambda: About(self))
        self.icon.menu.add_command(label=_('Quit'), command=self.quit)

        # --- Restore notes
        self.note_data = {}
        if os.path.exists(PATH_DATA):
            with open(PATH_DATA, "rb") as fich:
                dp = pickle.Unpickler(fich)
                note_data = dp.load()
                for i, key in enumerate(note_data):
                    self.note_data["%i" % i] = note_data[key]
            backup()
            for key in self.note_data:
                data = self.note_data[key]
                cat = data["category"]
                if not CONFIG.has_option("Categories", cat):
                    CONFIG.set("Categories", cat, data["color"])
                if data["visible"]:
                    self.notes[key] = Sticky(self, key, **data)
                else:
                    self.add_note_to_menu(key, data["title"], cat)
        self.nb = len(self.note_data)
        self.update_menu()
        self.update_notes()
        self.make_notes_sticky()

        # --- class bindings
        # newline depending on mode
        self.bind_class("Text", "<Return>", self.insert_newline)
        # char deletion taking into account list type
        self.bind_class("Text", "<BackSpace>", self.delete_char)
        # change Ctrl+A to select all instead of go to the beginning of the line
        self.bind_class('Text', '<Control-a>', self.select_all_text)
        self.bind_class('TEntry', '<Control-a>', self.select_all_entry)
        # bind Ctrl+Y to redo
        self.bind_class('Text', '<Control-y>', self.redo_event)
        # unbind Ctrl+I and Ctrl+B
        self.bind_class('Text', '<Control-i>', lambda e: None)
        self.bind_class('Text', '<Control-b>', lambda e: None)
        # highlight checkboxes when inside text selection
        self.bind_class("Text", "<ButtonPress-1>", self.highlight_checkboxes,
                        True)
        self.bind_class("Text", "<ButtonRelease-1>", self.highlight_checkboxes,
                        True)
        self.bind_class("Text", "<B1-Motion>", self.highlight_checkboxes, True)
        evs = [
            '<<SelectAll>>', '<<SelectLineEnd>>', '<<SelectLineStart>>',
            '<<SelectNextChar>>', '<<SelectNextLine>>', '<<SelectNextPara>>',
            '<<SelectNextWord>>', '<<SelectNone>>', '<<SelectPrevChar>>',
            '<<SelectPrevLine>>', '<<SelectPrevPara>>', '<<SelectPrevWord>>'
        ]
        for ev in evs:
            self.bind_class("Text", ev, self.highlight_checkboxes, True)

        # check for updates
        if CONFIG.getboolean("General", "check_update"):
            UpdateChecker(self)
Example #8
0

Constants and functions
"""
import os
import gettext
import warnings
from subprocess import Popen
from configparser import ConfigParser
from locale import getdefaultlocale, setlocale, LC_ALL
from subprocess import check_output, CalledProcessError

import ewmh
from PIL import Image, ImageDraw

EWMH = ewmh.EWMH()

SYMBOLS = 'ΓΔΘΛΞΠΣΦΨΩαβγδεζηθικλμνξοπρςστυφχψωϐϑϒϕϖ末»¡¿£¥$€§ø∞∀∃∄∈∉∫∧∨∩∪÷±√∝∼≃≅≡≤≥≪≫≲≳▪•✭✦➔➢✔▴▸✗✚✳☎✉✎♫⚠⇒⇔'

# --- paths
PATH = os.path.dirname(__file__)

if os.access(PATH, os.W_OK) and os.path.exists(os.path.join(PATH, "images")):
    # the app is not installed
    # local directory containing config files and sticky notes data
    LOCAL_PATH = PATH
    PATH_LOCALE = os.path.join(PATH, "locale")
    PATH_IMAGES = os.path.join(PATH, "images")
    PATH_DATA_BACKUP = os.path.join(LOCAL_PATH, "backup", "notes.backup%i")
    PATH_DATA = os.path.join(LOCAL_PATH, "backup", "notes")
    if not os.path.exists(os.path.join(LOCAL_PATH, "backup")):
Example #9
0
 def iter_window(cls) -> Iterator['_Window']:
     for win in ewmh.EWMH().getClientList():
         yield Window(win)
Example #10
0
 def __init__(self):
     self.ew = ewmh.EWMH()
     self.windows = None
Example #11
0
def main():

    e  = ewmh.EWMH()
    cr = CommandReader()

    global mpv_desktop_active
    global layout_tiled
    global layout_pip

    while True:

        try:

            # we don't want to get hammered, nor do we want to hammer
            # the mpv processes with mute/unmute requests
            sleep(0.25)

            cmd = cr.get_next()
            debug_obj(cr)
            if not cmd:
                error('main: get_next command failure')
                continue
            debug_obj(cmd)

            s = Screen(e)
            debug_obj(s)

            # we can choose to manage windows on one fixed desktop
            # only, even when we're currently on another one; or
            # always manage mpv windows on the current desktop only;
            # 'None' means always manage windows only on current
            # desktop
            if mpv_desktop == None: mpv_desktop_active = s.desktop

            mpv_list = MPVClientList(s)
            if not mpv_list:
                error('main: mpv list initialization trouble, stopping iteration')
                continue

            mpv_list.inc = cmd.inc

            # limit client list to top windows if we're just toggling
            if cmd.toggle_top: mpv_list.limit_to_top()
            debug_obj(mpv_list)

            # the mpv_list methods we are going to execute in
            # succession
            call_list = []
            call_list.append(mpv_list.rotate_focus) # move focus

            if not cmd.focus_only:
                call_list.append(mpv_list.rotate_audio) # move unmute status
                if not (cmd.audio_only or s.desktop != mpv_desktop_active):
                    if cmd.next_l_tile :
                        layout_tiled = (layout_tiled + 1) % 8
                        func = mpv_list.reset_tile
                    elif cmd.next_l_pip :
                        layout_pip = (layout_pip + 1) % 8
                        func = mpv_list.reset_pip
                    elif cmd.reset_tile  : func = mpv_list.reset_tile
                    elif cmd.reset_pip   : func = mpv_list.reset_pip
                    elif cmd.toggle_top  : func = mpv_list.toggle_top
                    #elif cmd.toggle_top : func = mpv_list.test
                    else                 : func = mpv_list.rotate_or_shift
                    call_list.append(func)

            # do window manipulation first, then audio, then focus;
            # implementation depends on this order
            for f in reversed(call_list): f()

        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            traceback.print_exc(file=sys.stdout)
            pass
        finally:
            if s and getattr(s, "e", None) and s.e:
                s.e.display.flush()
            mpv_list.close_sockets()
            debug(80 * '-')
            debug('')