def __init__(self, parent = None, widget = None): super(BlinkYourEyesWidget, self).__init__() # Avoid this window appearing from alt-tab window selection # see the followings: # https://stackoverflow.com/questions/3553428/how-can-i-prevent-gnome-from-showing-two-windows-when-doing-alt-tab-c-qt-app # https://doc.qt.io/qt-5/qt.html#WindowType-enum self.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint|QtCore.Qt.FramelessWindowHint |QtCore.Qt.Tool) #self.setAttribute(Qt.Qt.WA_NoSystemBackground) #self.setAttribute(QtCore.Qt.WA_TranslucentBackground) self.setWindowOpacity(0.8) #self.setFocusPolicy(QtCore.Qt.NoFocus) #self.setStyleSheet("background-color:transparent;") self.background_color = QtCore.Qt.black self.timer_count = 0 self.timer = QtCore.QTimer() self.timer.setInterval(100) # [milliseconds] self.timer.timeout.connect(self.timer_callback) self.initUI() self.timer.start() self.dragmode = None self.dragstartpos = None self.dragstartgeom = None if platform.system() == 'Linux': ewmh = EWMH() all_wins = ewmh.getClientList() wins = filter(lambda w: 'blinkyoureyes' in w.get_wm_class()[1], all_wins) for w in wins: ewmh.setWmDesktop(w, 0xffffffff) ewmh.display.flush()
def __init__(self, process_manager): GObject.GObject.__init__(self) self.__inhibitors = [ GnomeInhibitor(), XdgScreenSaverInhibitor(), XdgPowerManagmentInhibitor(), XssInhibitor(), DpmsInhibitor(), XorgInhibitor(), XautolockInhibitor(), xfceInhibitor() ] self.__process_manager = process_manager # Status string (XXX: Let's double check how well this is working). self.status_string = "Caffeine is starting up..." # Inhibition has been requested (though it may not yet be active). self.__inhibition_manually_requested = False # Inhibition has successfully been activated. self.__inhibition_successful = False self.__auto_activated = False self.timer = None self.notification = None self._ewmh = EWMH() # FIXME: add capability to xdg-screensaver to report timeout. GLib.timeout_add(10000, self.__attempt_autoactivation) logger.info(self.status_string)
def __init__(self, configuration, parent=None): """ Constructor Get the XML configuration as a string """ # Parent constructor super().__init__(parent) # Parse configuration root = ET.fromstring(configuration) # Extract items for c in list(root): if c.tag == 'category': self.children.append(CategoryItem(c, self)) elif c.tag == 'program': self.children.append(ProgramItem(c, self)) else: # Unknown tag pass # Initialize interface to X server if has_ewmh: self.ewmh = EWMH() else: self.ewmh = None
def runner(): parser = argparse.ArgumentParser(description='Move windows around.') parser.add_argument('-d','--double-command', action="store_true", dest='double', help='If this is set the double command mode will activate', ) if sys.argv[1:]: parser.add_argument('direction', type=str, help='direction that you want to move', choices=('bottomright', 'bottomleft', 'topleft', 'topright', 'center', 'top', 'right', 'bottom', 'left',), nargs=1, ) else: parser.add_argument('--direction', default = ['center']) args = parser.parse_args() ewmh = EWMH() main = MainInfo(ewmh) moveWin = DispatchMove(main,args.double) if (DEBUG): import pprint print 'DOUBLE MODE:',args.double pprint.pprint(vars(main)) moveWin.move(ewmh.getActiveWindow(), args.direction[0]) return 0
def main(): engine = create_engine('sqlite:///a.db') session_factory = sessionmaker(bind=engine) session = session_factory(autoflush=True) object_manager_builder = ActivityManagerObjectManagerBuilder() object_manager = object_manager_builder.build(session) window_manager_manager = EWMH() window_type_filterer = WindowTypeFilterer(window_manager_manager, '_NET_WM_WINDOW_TYPE_NORMAL') window_state_factory = WindowStateFactory(window_manager_manager, WindowState) def get_window_states(): return [ window_state_factory.create(window) for window in window_type_filterer.filter(window_manager_manager.getClientList()) ] window_poll_stack = NItemStack(2) window_poll_stack.push(WindowPollState([])) while True: window_poll_stack.push(WindowPollState(get_window_states())) print(window_poll_stack[1].changes_since(window_poll_stack[0])) print() time.sleep(2)
def runLinuxMinimize(command, args): from ewmh import EWMH ewmh = EWMH() win = ewmh.getActiveWindow() args.insert(0, command) subprocess.call(args) ewmh.setActiveWindow(win) ewmh.display.flush()
def find_monitors(self): self.dpy = display.Display() self.root = self.dpy.screen().root self.resources = self.root.xrandr_get_screen_resources()._data self.ewmh = EWMH() # Accessing modes sometimes makes outputs mysteriously disappear, # so save outputs first. outputs = self.resources['outputs'] # Build up a mode table. There's probably some clever IterTools # construct that could do this in one line. for m in self.resources['modes']: self.allmodes[m['id']] = '%dx%d' % (m['width'], m['height']) # Loop over the outputs. for output in outputs: print("Output info:", self.dpy.xrandr_get_output_info( output, self.resources['config_timestamp']), file=DEBUGFILE) mondata = self.dpy.xrandr_get_output_info( output, self.resources['config_timestamp'])._data if mondata['mm_width'] <= 0 or mondata['mm_height'] <= 0: # Not an actual monitor; I'm not sure what these are for # but they don't seem to have any useful info continue name = mondata['name'] self.monitors[name] = mondata if name.startswith('eDP') or name.startswith('LVDS'): self.laptop_screen = name # print("laptop monitor:", name) # Figure out if it's cloned or extended, and its xinerama position # https://stackoverflow.com/questions/49136692/python-xlib-how-to-deterministically-tell-whether-display-output-is-in-extendi # which references https://www.x.org/wiki/Development/Documentation/HowVideoCardsWork/#index3h3 # crtcInfo also includes rotation info but I'm not doing anything # with that since I don't personally use it. try: crtcInfo = self.dpy.xrandr_get_crtc_info( mondata['crtc'], self.resources['config_timestamp']) # print(crtcInfo) self.mon_geom[name] = { 'x': crtcInfo.x, 'y': crtcInfo.y, 'width': crtcInfo.width, 'height': crtcInfo.height, 'mm_width': mondata['mm_width'], 'mm_height': mondata['mm_height'] } except XError: # If get_crtc_info fails it means that the monitor is # connected but not active. pass
def __attempt_autoactivation(self): """Attempts to auto-activate inhibition by verifying if any of the whitelisted processes is running OR if there's a fullscreen app. """ if self.get_activated() and not self.__auto_activated: logging.debug("Inhibition manually activated. Won't attempt to " + "auto-activate") return True process_running = False # Determine if one of the whitelisted processes is running. for proc in self.__process_manager.get_process_list(): if utils.isProcessRunning(proc): process_running = True if self.__auto_activated: logging.info( "Process {} detected but was already ".format(proc) + "auto-activated") elif not self.get_activated(): logging.info( "Process {} detected. Inhibiting.".format(proc)) # Determine if a fullscreen application is running ewmh = EWMH() window = ewmh.getActiveWindow() if window: # ewmh.getWmState(window) returns None is scenarios where # ewmh.getWmState(window, str=True) throws an exception # (it's a bug in pyewmh): fullscreen = ewmh.getWmState(window) and \ "_NET_WM_STATE_FULLSCREEN" in ewmh.getWmState(window, str=True) else: fullscreen = False if fullscreen: if self.__auto_activated: logging.debug("Fullscreen app detected, but was already " + "auto-activated") elif not self.get_activated(): logging.info("Fullscreen app detected. Inhibiting.") # Disable auto-activation? if not process_running and not fullscreen and self.__auto_activated: logging.info("Was auto-inhibited, but there's no fullscreen or " + "whitelisted process now. De-activating.") self.__auto_activated = False self.__set_activated(False) elif process_running or fullscreen and not self.__auto_activated: self.__auto_activated = True self.__set_activated(True) return True
class NegEWMH(): """ Custom EWMH support functions """ disp = Xlib.display.Display() ewmh = EWMH() @staticmethod @contextmanager def window_obj(disp, win_id): """ Simplify dealing with BadWindow (make it either valid or None) """ window_obj = None if win_id: try: window_obj = disp.create_resource_object('window', win_id) except Xlib.error.XError: pass yield window_obj @staticmethod def is_dialog_win(win) -> bool: """ Check that window [win] is not dialog window At first check typical window roles and classes, because of it more fast, then using python EWMH module to detect dialog window type or modal state of window. win : target window to check """ if win.window_instance == "Places" \ or win.window_role in { "GtkFileChooserDialog", "confirmEx", "gimp-file-open"} \ or win.window_class == "Dialog": return True with NegEWMH.window_obj(NegEWMH.disp, win.window) as win_obj: win_type = NegEWMH.ewmh.getWmWindowType(win_obj, str=True) if '_NET_WM_WINDOW_TYPE_DIALOG' in win_type: return True win_state = NegEWMH.ewmh.getWmState(win_obj, str=True) if '_NET_WM_STATE_MODAL' in win_state: return True return False @staticmethod def find_visible_windows(windows_on_ws: List) -> List: """ Find windows visible on the screen now. windows_on_ws: windows list which going to be filtered with this function. """ visible_windows = [] for win in windows_on_ws: with NegEWMH.window_obj(NegEWMH.disp, win.window) as win_obj: win_state = NegEWMH.ewmh.getWmState(win_obj, str=True) if '_NET_WM_STATE_HIDDEN' not in win_state: visible_windows.append(win) return visible_windows
def _get_ewmh(): ''' Get the EWMH object. Returns ------- object The EWMH object. ''' global ewmh if ewmh is None: ewmh = EWMH() return ewmh
def __init__(self, output: str, fps: float = 30.0): self._ewmh = EWMH() self._sct = None self._geometry = self._ewmh.getDesktopGeometry() self._writer = None self._output = output self._delay = 1.0 / fps self._fps = fps self._width = 0 self._height = 0 if not os.path.exists('recorded'): os.mkdir('recorded')
def __init__(self, name, master=None, **kw): """ Create a desktop widget that sticks on the desktop. """ Toplevel.__init__(self, master) self.name = name if CONFIG.getboolean('General', 'splash_supported', fallback=True): self.attributes('-type', 'splash') else: self.attributes('-type', 'toolbar') self.style = Style(self) self._position = StringVar(self, CONFIG.get(self.name, 'position')) self._position.trace_add( 'write', lambda *x: CONFIG.set(self.name, 'position', self._position.get())) self.ewmh = EWMH() self.title('scheduler.{}'.format(self.name.lower())) self.withdraw() # control main menu checkbutton self.variable = BooleanVar(self, False) # --- menu self.menu = Menu(self, relief='sunken', activeborderwidth=0) self._populate_menu() self.create_content(**kw) self.x = None self.y = None # --- geometry geometry = CONFIG.get(self.name, 'geometry') self.update_idletasks() if geometry: self.geometry(geometry) self.update_idletasks() if CONFIG.getboolean(self.name, 'visible', fallback=True): self.show() # --- bindings self.bind('<Configure>', self._on_configure)
def getWins(): ''' getWins() -> retval. get all active window id and title. ''' ewmh = EWMH() wins, winHDs = [], ewmh.getClientListStacking() for winHD in winHDs: try: title = ewmh.getWmName(winHD) pid = ewmh.getWmPid(winHD) except: continue if title is not None: wins.append((winHD, title, pid)) return wins
def get_recent_windows(exclude, limit): wm = EWMH() xlib_windows = wm.getClientListStacking() windows_recent_last = [ Window.from_xlib_window(xlib_win) for xlib_win in xlib_windows ] windows_recent_first = list(reversed(windows_recent_last)) windows_result = windows_recent_first if exclude: for win in windows_result: if win.name == exclude: windows_result.remove(win) if limit: windows_result = windows_result[:10] return windows_result
def __init__(self, process_manager): GObject.GObject.__init__(self) self.__inhibitors = [ GnomeInhibitor(), XdgPowerManagmentInhibitor(), XssInhibitor(), XorgInhibitor(), XautolockInhibitor(), XidlehookInhibitor(), XdgScreenSaverInhibitor(), DpmsInhibitor() ] self.__process_manager = process_manager # Status string (XXX: Let's double check how well this is working). self.status_string = "Caffeine is starting up..." # Inhibition has been requested (though it may not yet be active). self.__inhibition_manually_requested = False # Number of procs playing audio but nothing visual. This is a special # case where we want the screen to turn off while still preventing # the computer from suspending self.music_procs = 0 # Inhibition has successfully been activated. self.__inhibition_successful = False self.__auto_activated = False self.timer = None self.notification = None self._ewmh = EWMH() # FIXME: add capability to xdg-screensaver to report timeout. GLib.timeout_add(10000, self.__attempt_autoactivation) logger.info(self.status_string)
class WmEWMH(WinInfo): ewmh = EWMH() wmclass = ewmh.display.get_atom("WM_CLASS") wmcm = ewmh.display.get_atom("WM_CLIENT_MACHINE") wmname = ewmh.display.get_atom("WM_NAME") def list_windows(self): wins = WmEWMH.ewmh.getClientListStacking() lines = [] for win in wins: id = '0x' + hex(win.id)[2:].zfill(8) disp = win.display.default_screen wmcm = win.get_full_property(self.wmcm, X.AnyPropertyType) if wmcm: wmcm = wmcm.value.decode("utf-8", 'backslashreplace') else: wmcm = "N/A" itemb = win.get_full_property(WmEWMH.wmclass, X.AnyPropertyType).value cls = '.'.join(itemb.decode("utf-8").rstrip('\x00').split('\x00')) nameb = win.get_full_property(WmEWMH.wmname, X.AnyPropertyType).value name = nameb.decode("utf-8", 'backslashreplace') line = "%s %s %s %s %s" % (id, disp, cls, wmcm, name) lines.append(line) return lines def kill(self, wm_id: str) -> None: win_id = int(wm_id, 16) win = WmEWMH.ewmh._createWindow(win_id) WmEWMH.ewmh.setCloseWindow(win) WmEWMH.ewmh.display.flush() def switch_to(self, wm_id): win_id = int(wm_id, 16) win = WmEWMH.ewmh._createWindow(win_id) WmEWMH.ewmh.setActiveWindow(win) WmEWMH.ewmh.display.flush()
def unmaximize(hwnd, x, y, width, height): ewmh = EWMH() ewmh.setWmState(hwnd, 0, '_NET_WM_STATE_FULLSCREEN') ewmh.display.flush()
def maximize(hwnd): ewmh = EWMH() ewmh.setWmState(hwnd, 1, '_NET_WM_STATE_FULLSCREEN') ewmh.display.flush()
def set_win_size(hwnd, x, y, width, height): ewmh = EWMH() ewmh.setMoveResizeWindow(hwnd, 0, x, y, width, height) ewmh.display.flush()
def get_desktop(): ewmh = EWMH() width, height = ewmh.getDesktopGeometry() return 0, 0, width, height
def get_top_window(): ewmh = EWMH() return ewmh.getActiveWindow()
return "" else: return output.decode('utf-8') ################ # Main functions ################ if flag_exists(): print("Flag file exists!") sys.exit(1) create_flag() wmm = EWMH() uinput = UInput(name="VMCtrlV") def cleanup(): remove_flag() uinput.close() atexit.register(cleanup) def main(): # wait until the VM window is the active window switched_to_vm = False while not switched_to_vm:
from base64 import b64encode from io import BytesIO from ewmh import EWMH from motee.scope import ScopeHandler from PIL import Image, ImageDraw, ImageFont from Xlib import Xatom _EWMH = EWMH() def generate_icon(name): image = Image.new("RGBA", (64, 64), color=(70, 168, 231)) d = ImageDraw.Draw(image) font = ImageFont.truetype("/usr/share/fonts/truetype/ubuntu/UbuntuMono-R.ttf", 24) d.text((10, 16), name[:4].upper(), font=font, fill=(192, 192, 255)) return image class App: ICON_SIZE = 64 _icon_cache = {} def __init__(self, win): self.win = win self._icon = False @property def _key(self): return (self.name, self.pid)
import argparse, sys, os, psutil, subprocess, re, signal from PyQt5.QtWidgets import QApplication from PyQt5.QtCore import Qt, QTimer import pkg_resources import oskb from oskb import im linux = sys.platform.startswith("linux") if linux: import getpass from ewmh import EWMH, ewmh wm = EWMH() moved_windows = [] def command_line_arguments(): ap = argparse.ArgumentParser() ap.add_argument( "keyboards", help= """Which keyboard(s) to load. These are either files or names of built-in keyboards. If multiple keyboards are loaded, the user can switch between them with a menu key. If no keyboards are chosen a full keyboard is shown if display is wider than 600 pixels, otherwise a phone-style keyboard is used. If oskb comes with a keyboard for the presently set keyboard layout, that keyboard is used. Otherwise oskb will show a US keyboard layout and switch the system keyboard layout to that.""", metavar="<kbd>", nargs="*", )
def __init__(self, prefs, session_info): self.prefs = prefs self.session_info = session_info self.ewmh = EWMH() self.dpy = display.Display() self.screen = self.dpy.screen() self.dpy_root = self.screen.root self.colormap = self.screen.default_colormap self.pixel_palette = PixelPalette(self.colormap) self.display_dimensions = self.get_display_geometry() self.window_resize_options = [ "center", "maximize", "left", "right", "top", "bottom" ] self.managed_windows = [] self.exposed_windows = [] self.last_raised_window = None self.active_window_title = self.session_info.session_name self.window_order = -1 self.key_alias = {} self.keys_down = set() self.start = None self.attr = None self.wm_window_type = self.dpy.intern_atom('_NET_WM_WINDOW_TYPE') self.wm_state = self.dpy.intern_atom('_NET_WM_STATE') self.wm_window_types = { "dock": self.dpy.intern_atom('_NET_WM_WINDOW_TYPE_DOCK'), "normal": self.dpy.intern_atom('_NET_WM_WINDOW_TYPE_NORMAL'), "dialog": self.dpy.intern_atom('_NET_WM_WINDOW_TYPE_DIALOG'), "utility": self.dpy.intern_atom('_NET_WM_WINDOW_TYPE_UTILITY'), "toolbar": self.dpy.intern_atom('_NET_WM_WINDOW_TYPE_TOOLBAR'), "menu": self.dpy.intern_atom('_NET_WM_WINDOW_TYPE_MENU'), "splash": self.dpy.intern_atom('_NET_WM_WINDOW_TYPE_SPLASH') } self.wm_window_status = { "active": self.dpy.intern_atom('_NET_ACTIVE_WINDOW'), "desktop": self.dpy.intern_atom('_NET_WM_DESKTOP'), "above": self.dpy.intern_atom('_NET_WM_STATE_ABOVE'), "skip_taskbar": self.dpy.intern_atom('_NET_WM_STATE_SKIP_TASKBAR'), "maximize_vertical": self.dpy.intern_atom('_NET_WM_STATE_MAXIMIZED_VERT'), "maximize_horizontal": self.dpy.intern_atom('_NET_WM_STATE_MAXIMIZED_HORIZ') } self.wm_window_cyclical = [ self.wm_window_types["normal"], self.wm_window_types["dialog"], self.wm_window_types["utility"], self.wm_window_types["toolbar"] ] self.deskbar = None self.display_corners = None self.update_active_window_title_rt = RepeatedTimer( interval=1, function=self.update_active_window_title) self.update_active_window_title_rt.stop() self.set_cursor(self.dpy_root) XK.load_keysym_group('xf86') self.set_key_aliases()
def __init__(self): if os.environ.get("WAYLAND_DISPLAY") is None: self._ewmh = EWMH() else: logger.info("Running on Wayland; fullscreen trigger won't work.") self._ewmh = None
def __init__(self): super(MainWindow, self).__init__() logger.info('Starting...') # ------------------------------------------------------------- # Window Flags flags = QtCore.Qt.FramelessWindowHint flags |= QtCore.Qt.WindowStaysOnBottomHint flags |= QtCore.Qt.Tool # ------------------------------------------------------------- # Styles self.groupBoxStyle = """ QGroupBox { border: 1px solid white; border-radius: 5px; margin-top: 12px; padding-left: 2px; } QGroupBox:title { subcontrol-origin: margin; subcontrol-position: top left; color: rgb(252, 126, 0); left: 15px; } """ self.redPBStyle = """ QProgressBar { text-align: left; font-weight: bold; color: rgb(255, 255, 255); background-color : rgba(0, 0, 0, 0); border: 0px solid rgba(0, 0, 0, 0); border-radius: 3px; } QProgressBar::chunk { background: rgb(255, 51, 0); border-radius: 3px; } """ self.greenPBStyle = """ QProgressBar { text-align: left; font-weight: bold; color: rgb(255, 255, 255); background-color : rgba(0, 0, 0, 0); border: 0px solid rgba(0, 0, 0, 0); border-radius: 3px; } QProgressBar::chunk { background: rgb(51, 153, 51); border-radius: 3px; } """ self.orange = 'color: rgb(252, 126, 0);' self.white = 'color: rgb(255, 255, 255);' self.green = 'color: rgb(34, 255, 19);' self.red = 'color: rgb(255, 48, 79);' # --------------------------------------------------------------------- # Default font self.fontDefault = QtGui.QFont('Fira Code', 11) self.fontGroupBox = QtGui.QFont('Fira Code', 14) # ------------------------------------------------------------- self.verticalLayout.setAlignment(QtCore.Qt.AlignTop) # -------------------------------------------------------------- self.setWindowFlags(flags) self.setAttribute(QtCore.Qt.WA_TranslucentBackground) # Connect Threads Signals self.threadFast.signal.connect(self.receiveThreadFastfinish) self.threadSlow.signal.connect(self.receiveThreadSlowFinish) self.threadNetworkStats.signal.connect(self.receiveThreadNetworkStats) self.threadweather.signal.connect(self.receiveThreadWeatherFinish) self.threadNvidia.signal.connect(self.receiveThreadNvidia) centralWidGet = QtWidgets.QWidget(self) centralWidGet.setLayout(self.verticalLayout) self.setCentralWidget(centralWidGet) # ----------------------------------------------------------------------------------------------- # before show main window, check all dependencies and refuse if any thing wrong self.checkDependencies() # self.show() # Show in all workspaces self.ew = EWMH() self.all_wins = self.ew.getClientList() self.wins = filter(lambda wHandle: wHandle.get_wm_class()[1] == 'gonha', self.all_wins) for w in self.wins: self.ew.setWmDesktop(w, 0xffffffff) self.ew.display.flush() self.threadFast.start() self.threadSlow.start() self.threadNetworkStats.start() self.loadPosition() self.displayDTWeather() self.displaySystem() if self.nvidia.getStatus(): self.displayNvidia() self.displayIface() self.displayPartitions()
action="store_true", help="Do not change anything") args = parser.parse_args() r = redis.Redis(host='localhost', port=6379, db=0) if args.init: desktops_map = prepare_desktops_map() if not desktops_map: sys.exit(128) r.set("xserver/desktops_map", json.dumps(desktops_map)) sys.exit(0) desktops_map = json.loads(r.get("xserver/desktops_map")) window_rules = json.loads(r.get("xserver/window_rules")) ewmh = EWMH() NET_WM_NAME = ewmh.display.intern_atom('_NET_WM_NAME') UTF8_STRING = ewmh.display.intern_atom('UTF8_STRING') windows = ewmh.getClientList() for window in sorted( windows, key=lambda w: w.get_full_text_property(NET_WM_NAME, UTF8_STRING)): similarities = {} rule = None desktop_name = None print("================================") window_title = window.get_full_text_property(NET_WM_NAME, UTF8_STRING) window_class = window.get_wm_class()[1] if args.verbosity >= 1: print(f"window ({window_class}): {window_title}")
def get_current_window(): wm = EWMH() xlib_win = wm.getActiveWindow() window = Window.from_xlib_window(xlib_win) return window
def __init__(self): Tk.__init__(self, className="WorkHourGlass") self.on = False # is the timer on? if not CONFIG.options("Tasks"): CONFIG.set("Tasks", _("Work"), CMAP[0]) # colors self.background = { _("Work"): CONFIG.get("Work", "bg"), _("Break"): CONFIG.get("Break", "bg"), _("Rest"): CONFIG.get("Rest", "bg") } self.foreground = { _("Work"): CONFIG.get("Work", "fg"), _("Break"): CONFIG.get("Break", "fg"), _("Rest"): CONFIG.get("Rest", "fg") } # window configuration if PL[0] == "w": self.iconbitmap(ICON_WIN, default=ICON_WIN) else: self.icon = PhotoImage(master=self, file=ICON) self.iconphoto(True, self.icon) self.title("WorkHourGlass") self.protocol("WM_DELETE_WINDOW", self.exit) self.rowconfigure(1, weight=1) self.columnconfigure(0, weight=1) self.columnconfigure(1, weight=1) self.minsize(181, 190) self.geometry("200x190+%i+%i" % ((self.winfo_screenwidth() - 200) // 2, (self.winfo_screenheight() - 190) // 2)) self.configure(background=self.background[_("Work")]) # style self.style = Style(self) self.style.theme_use(STYLE) self.style.configure('fen.TLabel', foreground=self.foreground[_("Work")], background=self.background[_("Work")]) # nombre de séquence de travail effectuées d'affilée (pour # faire des pauses plus longues tous les 4 cycles) self.nb_cycles = 0 self.pomodori = IntVar(self, 0) # images self.im_go = PhotoImage(master=self, file=GO) self.im_stop = PhotoImage(master=self, file=STOP) self.im_plus = PhotoImage(master=self, file=PLUS) self.im_moins = PhotoImage(master=self, file=MOINS) self.im_params = PhotoImage(master=self, file=PARAMS) self.im_tomate = PhotoImage(master=self, file=TOMATE) self.im_graph = PhotoImage(master=self, file=GRAPH) # tasks list tasks_frame = Frame(self) tasks_frame.grid(row=3, column=0, columnspan=3, sticky="wnse") tasks = [t.capitalize() for t in CONFIG.options("Tasks")] self.task = StringVar(self, tasks[0]) self.menu_tasks = Menu(tasks_frame, tearoff=False) for task in tasks: self.menu_tasks.add_radiobutton(label=task, value=task, variable=self.task) self.menu_tasks.add_command(label=_("New task"), image=self.im_plus, compound="left", command=self.add_task) self.menu_tasks.add_command(label=_("Remove task"), image=self.im_moins, compound="left", command=self.del_task) self.menu_tasks.add_command(label=_("Statistics"), image=self.im_graph, compound="left", command=self.display_stats) self.choose_task = Menubutton(tasks_frame, textvariable=self.task, menu=self.menu_tasks) Label(tasks_frame, text=_("Task: "), font="CMU\ Sans\ Serif\ Demi\ Condensed 12", width=6, anchor="e").pack(side="left") self.choose_task.pack(side="right", fill="x") # display self.tps = [CONFIG.getint("Work", "time"), 0] # time: min, sec self.activite = StringVar(self, _("Work")) self.titre = Label(self, textvariable=self.activite, font='CMU\ Sans\ Serif\ Demi\ Condensed 14', style='fen.TLabel', anchor="center") self.titre.grid(row=0, column=0, columnspan=2, sticky="we") self.temps = Label( self, text="{0:02}:{1:02}".format(self.tps[0], self.tps[1]), font="%s %i" % (CONFIG.get( "General", "font"), CONFIG.getint("General", "fontsize")), style='fen.TLabel', anchor="center") self.temps.grid(row=1, column=0, columnspan=2, sticky="nswe", pady=(0, 10)) self.aff_pomodori = Label(self, textvariable=self.pomodori, image=self.im_tomate, compound="left", style='fen.TLabel', font='CMU\ Sans\ Serif\ Demi\ Condensed 14') self.aff_pomodori.grid(row=2, columnspan=2, sticky="e", padx=20) # buttons self.b_go = Button(self, image=self.im_go, command=self.go) self.b_go.grid(row=4, column=0, sticky="ew") self.b_params = Button(self, image=self.im_params, command=self.params) self.b_params.grid(row=4, column=1, sticky="ew") # --- make window sticky self.update_idletasks() e = EWMH() try: for w in e.getClientList(): if w.get_wm_name() == self.title(): e.setWmState(w, 1, '_NET_WM_STATE_STICKY') e.display.flush() except ewmh.display.error.BadWindow: pass