コード例 #1
0
ファイル: __init__.py プロジェクト: Tarik02/windowcolorscheme
def main():
    root.change_attributes(event_mask=X.PropertyChangeMask)
    is_bad_window = False
    while True:
        win, changed = get_active_window()
        if not is_bad_window or changed:
            try:
                # TODO: Application/window -specific detection configuration
                is_bad_window = False
                win.map()
                width = win.get_geometry().width
                height = 1
                raw = win.get_image(0, 1, width, height, X.ZPixmap, 0xffffffff)
                image = Image.frombytes('RGB', (width, height), raw.data,
                                        'raw', 'BGRX')
                colors = image.getcolors()
                if colors is None:
                    target_color = (0, 0, 0)
                else:
                    target_color = sorted(colors, key=lambda k: k[0])[-1][1]

                wm_class = ' '.join(win.get_wm_class())
                name = '_'.join(win.get_wm_class())

                set_window_config(wm_class, name,
                                  ','.join(map(str, target_color)))
            except Exception as e:
                print(e)
                is_bad_window = True

        while display.pending_events():
            event = display.next_event()
        time.sleep(1 / 60)
コード例 #2
0
ファイル: gwm.py プロジェクト: GullikX/gwm
def main() -> None:
    for cmd in CMDS:
        assert shutil.which(cmd) is not None, "'%s' not found in PATH." % cmd
    signal.signal(signal.SIGCHLD, signal.SIG_IGN)
    display: Xlib.display.Display = Xlib.display.Display()
    window_manager: WindowManager = WindowManager(display)
    while window_manager.is_running():
        window_manager.on_event(display.next_event())
    display.close()
コード例 #3
0
ファイル: i3kb.py プロジェクト: Caagr98/Dotfiles
		def on_event():
			nonlocal bound
			while display.pending_events():
				evt = display.next_event()
				if evt.type == X.KeyPress:
					k = (evt.detail, evt.state & modmask)
					if k in bound:
						asyncio.ensure_future(bound[k]())
				if evt.type == X.MappingNotify and evt.request == X.MappingKeyboard:
					display.refresh_keyboard_mapping(evt)
					regrab_keys()
コード例 #4
0
 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
コード例 #5
0
def update():
    global current_window_id, current_window
    window_id = _check_current_window_id()

    if current_window_id is None or not window_id == current_window_id:
        window = display.create_resource_object('window', window_id)
        window.change_attributes(event_mask=Xlib.X.PropertyChangeMask)
        current_window = window
        current_window_id = window_id
        print("Current window: {0}".format(get_focused_window_name()))

    event = display.next_event()
コード例 #6
0
 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
コード例 #7
0
def main(argv):

    bg_size = 16  # Default corner size
    corners = ['nw', 'ne', 'se', 'sw']  # Default corners to draw

    try:
        opts, args = getopt.getopt(argv, "h", ["help", "corners=", "size="])
    except:
        return usage()
        sys.exit(2)
    for opt, arg in opts:
        if opt in ("-h", "--help"):
            return usage()
        elif opt in ("--corners"):
            corners = ''.join(str(arg)).lower()
            if not any(sz in corners for sz in ["nw", "ne", "sw", "se"]):
                return usage()
        elif opt in ("--size"):
            try:
                bg_size = int(arg)
            except:
                return usage()

    for arg in sys.argv:
        print(arg)

    window = create_window(
        bg_size, corners)  # Make the window using specified size / corners
    window.map()  # Make the window appear

    while True:
        e = display.next_event()

        set_wm_state(window, "_NET_WM_DESKTOP",
                     data=[0xFFFFFFFF, 1, 0, 0,
                           0])  # Keeps window on all workspaces
        set_wm_state(window,
                     "_NET_WM_STATE",
                     data=[1, "_NET_WM_STATE_SKIP_TASKBAR", 0, 1,
                           0])  # Removes window from task list
        set_wm_state(window,
                     "_NET_WM_STATE",
                     data=[1, "_NET_WM_STATE_ABOVE", 0, 1,
                           0])  # Keeps window above (almost all) other windows

        # TODO: How to keep above fullscreened windows (F11 sublime / chrome / etc.) ? This doesn't work:
        # set_wm_state(window, "_NET_WM_STATE", data=[1, "_NET_WM_STATE_FULLSCREEN", 0, 1, 0])

        display.flush()  # Is this really needed? Seems to work fine without
コード例 #8
0
ファイル: xtype.py プロジェクト: Caagr98/Dotfiles
def xtype(keysyms, keycode=KEYCODE):
	keysyms = list(enumerate(keysyms, keycode))
	print(keysyms)
	import Xlib.display
	from Xlib import X
	display = Xlib.display.Display()
	display.change_keyboard_mapping(keycode, [(sym,) * 8 for code, sym in keysyms])
	while 1:
		e = display.next_event()
		if e.type == X.MappingNotify:
			for code, sym in keysyms:
				display.xtest_fake_input(X.KeyPress, code)
				display.xtest_fake_input(X.KeyRelease, code)
			break
	display.sync()
コード例 #9
0
def main():
    args = parse_args()

    ckb = CKBPipe(args.ckb_pipe)
    display = Xlib.display.Display()
    atom = display.intern_atom('_NET_CURRENT_DESKTOP', True)
    window = display.screen().root

    highlight_current_workspace(ckb, window, atom)

    window.change_attributes(event_mask=X.PropertyChangeMask)

    while True:
        ev = display.next_event()
        if ev.type == X.PropertyNotify and ev.state == X.PropertyNewValue and ev.window == window and ev.atom == atom:
            highlight_current_workspace(ckb, window, atom)
コード例 #10
0
ファイル: hooker.py プロジェクト: chuang1990/context-agent
 def get_selection():  
   display = Xlib.display.Display()
   xsel_data_atom = display.intern_atom("XSEL_DATA")
   screen = display.screen()
   w = screen.root.create_window(0, 0, 2, 2, 0, screen.root_depth)
   w.convert_selection(Xlib.Xatom.PRIMARY,
                 Xlib.Xatom.STRING,
                 xsel_data_atom,
                 Xlib.X.CurrentTime)
   
   while True:
     e = display.next_event()
     if e.type == Xlib.X.SelectionNotify:
       break
   
   assert e.property == xsel_data_atom
   assert e.target == Xlib.Xatom.STRING
   reply = w.get_full_property(xsel_data_atom, Xlib.X.AnyPropertyType)
   
   return reply.value
コード例 #11
0
ファイル: player.py プロジェクト: maxcountryman/pyxine-branch
    def __init__(self, display):
        self.display = display
        self.screen = display.screen()
        self.colormap = self.screen.default_colormap
        bg = self.colormap.alloc_named_color("gray10").pixel
        self.window = self.screen.root.create_window(
            50, 50, 600, 400, 0,
            self.screen.root_depth,
            X.InputOutput,
            X.CopyFromParent,

            # special attribute values
            background_pixel = bg,
            event_mask = (#X.ExposureMask |
                          X.StructureNotifyMask),
            colormap = self.colormap
            )
        
        
        self.window.set_wm_name('Pyxine')
        self.window.set_wm_icon_name('Pyxine')
        self.window.set_wm_class('pyxine', 'PyXine')

        self.window.set_wm_protocols([display.WM_DELETE_WINDOW])
        self.window.set_wm_hints(flags = Xutil.StateHint,
                                 initial_state = Xutil.NormalState)
        self.window.set_wm_normal_hints(flags = (Xutil.PPosition | Xutil.PSize | Xutil.PMinSize),
                                        min_width = 20,
                                        min_height = 20)

        # Map the window, making it visible
        self.window.map()

        # Wait for window to map.
        # FIXME: is this right?
        while 1:
            e = display.next_event()
            if e.type == X.MapNotify:
                break

        self.xine_visual = pyxine.XlibDrawable(self.window)
コード例 #12
0
def get_x_selection():
  import Xlib.display  # from the python X library, http://python-xlib.sf.net/
  import Xlib.X
  import Xlib.Xatom

  display = Xlib.display.Display()
  xsel_data_atom = display.intern_atom("XSEL_DATA")
  screen = display.screen()
  w = screen.root.create_window(0, 0, 2, 2, 0, screen.root_depth)
  w.convert_selection(Xlib.Xatom.PRIMARY,  # selection
                      Xlib.Xatom.STRING,   # target
                      xsel_data_atom,      # property
                      Xlib.X.CurrentTime)  # time

  while True:
    e = display.next_event()
    if e.type == Xlib.X.SelectionNotify:
      break

  assert e.property == xsel_data_atom
  assert e.target == Xlib.Xatom.STRING
  reply = w.get_full_property(xsel_data_atom, Xlib.X.AnyPropertyType)

  return reply.value
コード例 #13
0
def events(display):
    """Returns an generator which yields incoming x11 events"""
    return (display.next_event() for _ in itertools.count())
コード例 #14
0
ファイル: bg.py プロジェクト: Caagr98/Dotfiles
def on_event():
	while display.pending_events():
		display.next_event()
コード例 #15
0
ファイル: avremote-host.py プロジェクト: nikharris0/avremote
def main(argv):
    try:
        s = serial.Serial(port = SERIAL_PATH)
    except:
        print 'exception opening serial port'
        exit(0)

    # for audio control
    m = alsaaudio.Mixer()

    while True:
        try:
            cmd = long(s.readline()) & 0x0000FFFF

            if cmd == 254:
                try:
                    print '[254] volume increase'
                    m.setvolume(int(m.getvolume()[0] + 5))
                except:
                    pass	

            elif cmd == 8414:
                try:
                    print '[8414] volume decrease'
                    m.setvolume(int(m.getvolume()[0] - 5))
                except:
                    pass

            elif cmd == 24734:
                print '[24734] netflix continue'
                
                d = display.Display()
                screen  = d.screen()
                root_screen = screen.root
                root_screen.warp_pointer(831, 460)
                d.sync()
                fake_input(d, X.ButtonPress, 1)
                d.sync()
                fake_input(d, X.ButtonRelease, 1)
                d.sync()
                fake_input(d, X.ButtonPress, 1)
                d.sync()
                fake_input(d, X.ButtonRelease, 1)
                d.sync()
                
            # netflix pause button
            elif cmd == 24990:
                print '[24990] netflix pause/resume'
                
                d = display.Display()
                screen  = d.screen()
                
                # move cursor to position of pause/resume button
                root_screen = screen.root
                root_screen.warp_pointer(199, 896)
                d.sync()
                
                # click twice, once for focus and once for actual pause/resume
                fake_input(d, X.ButtonPress, 1)
                d.sync()
                fake_input(d, X.ButtonRelease, 1)
                d.sync()
                root_screen.warp_pointer(0, 0)
                d.sync()
                
                # move cursor off screen
                root_screen.warp_pointer(9999, 0)
                d.sync()
                fake_input(d, X.ButtonPress, 1)
                d.sync()
                fake_input(d, X.ButtonRelease, 1)
                d.sync()
                
            elif cmd == 510:
                print '[510] sleep displays'
                subprocess.call('xset dpms force off'.split())
                p = subprocess.Popen('gnome-screensaver-command -i'.split())
                time.sleep(1)
                print display.next_event()
                p.terminate()


        except Exception, e:
            print 'exception while reading data from serial port'
コード例 #16
0
ファイル: xlib_draw_text.py プロジェクト: fr1ht/WindowCensor
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import Xlib
from Xlib import display, X   # X is also needed

display = Xlib.display.Display()
screen = display.screen()
root = screen.root

#print(root.get_attributes())
root.change_attributes(event_mask=X.ExposureMask)  # "adds" this event mask
#print(root.get_attributes())  # see the difference

gc = root.create_gc(foreground = screen.white_pixel, background = screen.black_pixel)


def draw_it():
  root.draw_text(gc, 100, 100, b"Hello, world!")
  display.flush()


draw_it()


while 1:
  if display.pending_events() != 0:  # check to safely apply next_event
    event = display.next_event()
    if event.type == X.Expose and event.count == 0:
      draw_it()
コード例 #17
0
ファイル: xclipboard.py プロジェクト: DarkStarSword/kosh
def sendViaClipboard(blobs, record = None, txtselections = defSelections, ui=ui_null()):
  """
  Send a list of blobs via the clipboard (using X selections, cut buffers are
  not yet supported) in sequence. Typically the PRIMARY and/or SECONDARY
  selections are used for middle click and shift+insert pasting, while the
  CLIPBOARD selection is often used by Ctrl+V pasting.

  Raises an XFailConnection exception if connecting to the X DISPLAY failed.
  """
  global Xlib, X, Xatom, Xerror
  if Xlib is None:
    ui.status('Initialising python-Xlib, stand by...')
    ui.mainloop.draw_screen()
    try:
      from Xlib import X, Xatom, error as Xerror
      import Xlib.display
    except ImportError:
      ui.status('Error importing python-Xlib, X clipboard integration unavailable')
      return

  # Can't do this in the function definition - it seems that a .remove()
  # affects the default. That would be expected if it were assigned as a
  # reference to the default list, but even happens when the [:] syntax is
  # used to copy the list. I guess that must be an unexpected side effect of
  # the function definition only excuting once when the file is loaded?
  txtselections = txtselections[:]
  selections = txtselections[:]

  def findClientWindow(window, ui):
    """ walk up the tree looking for a client window """

    def get_wm_client_leader(window):
        d = window.get_full_property(Xatom.WM_CLIENT_LEADER, Xatom.WINDOW)
        if d is None or d.format != 32 or len(d.value) < 1:
          return None
        else:
          cls = window.display.get_resource_class('window', type(window))
          return cls(window.display, d.value[0])

    host = window.get_wm_client_machine()
    while True:
      comm = window.get_full_property(Xatom.WM_COMMAND, Xatom.STRING)
      name = window.get_wm_name()
      # Nokia N900 uses _NET_WM_NAME instead of WM_NAME:
      netname = window.get_full_property(Xatom._NET_WM_NAME, Xatom.UTF8_STRING)
      leadercomm = None

      # Only one top-level window for a given client has WM_COMMAND. Find the
      # leader top-level window (if we are looking at a top-level window) and
      # check it's WM_COMMAND property.
      #
      # I don't see a requirement in the ICCCM that the client leader
      # necessarily be the window with the WM_COMMAND property, it may end up
      # being necessary to iterate all the windows with the same
      # WM_CLIENT_LEADER to find the one window that has the WM_COMMAND.
      leader = get_wm_client_leader(window)
      if leader is not None and leader != window:
        leadercomm = leader.get_full_property(Xatom.WM_COMMAND, Xatom.STRING)

      requestor = name or netname or comm or leadercomm
      if hasattr(requestor, 'value'):
        requestor = requestor.value
      if requestor:
        break
      resp = window.query_tree()
      root = resp.root; parent = resp.parent
      if parent == root:
        return ('<unknown>', host)
      window = parent
    return (requestor, host)

  def handleSelectionRequest(e, field, record, ui):
    global _prev_requestor
    if ((e.time != X.CurrentTime and e.time < timestamp) or # Timestamp out of bounds
        (e.selection not in selections) or # Requesting a different selection
        (e.owner.id != win.id)): # We aren't the owner
      return _refuseSelectionRequest(e)
    if (e.target in (Xatom.STRING, Xatom.TEXT)):
      (requestor, host) = findClientWindow(e.requestor, ui)
      if requestor.lower() in blacklist or any([ pattern.match(requestor) for pattern in blacklist_re ]):
        if requestor != _prev_requestor:
          ui.status("Ignoring request from %s@%s"%(requestor, host), append=True)
          _prev_requestor = requestor
        return _refuseSelectionRequest(e)
      ui.status("Sent %s for '%s' via %s to %s@%s"%(field.upper(), record, display.get_atom_name(e.selection), requestor, host), append=True)
      oldmask = e.requestor.get_attributes().your_event_mask
      e.requestor.change_attributes(event_mask = oldmask | X.PropertyChangeMask)
      _sendSelection(blob, Xatom.STRING, 8, e, ui)
      return True
    elif (e.target == Xatom.TIMESTAMP):
      _sendSelection([timestamp], Xatom.TIMESTAMP, 32, e, ui)
    elif (e.target == Xatom.TARGETS):
      _sendSelection([Xatom.TARGETS, Xatom.TIMESTAMP, Xatom.TEXT, Xatom.STRING], Xatom.ATOM, 32, e, ui)
    else:
      return _refuseSelectionRequest(e)
    return False

  # Opening the display prints 'Xlib.protocol.request.QueryExtension' to
  # stdout, so temporarily redirect it:
  ui.status('Connecting to display, stand by...')
  ui.mainloop.draw_screen()
  import sys, StringIO
  saved_stdout = sys.stdout
  sys.stdout = StringIO.StringIO()
  try:
    display = Xlib.display.Display()
  except Xerror.DisplayError:
    raise XFailConnection()
  finally:
    sys.stdout = saved_stdout
  screen = display.screen()
  win = screen.root.create_window(0,0,1,1,0,0)

  Xatom.TEXT = display.intern_atom('TEXT', True)
  Xatom.TARGETS = display.intern_atom('TARGETS', True)
  Xatom.TIMESTAMP = display.intern_atom('TIMESTAMP', True)
  Xatom.WM_CLIENT_LEADER = display.intern_atom('WM_CLIENT_LEADER', True)
  Xatom._NET_WM_NAME = display.intern_atom('_NET_WM_NAME', True)
  Xatom.UTF8_STRING = display.intern_atom('UTF8_STRING', True)

  ui_fds = ui.mainloop.screen.get_input_descriptors()
  if ui_fds is None: ui_fds = []
  select_fds = set([display] + ui_fds)
  try:
    old = ui_tty.set_cbreak() # Set unbuffered IO (if not already)
    ui.status('')
    for (field, blob) in blobs:
      ui.status("Ready to send %s for '%s' via %s... (enter skips, escape cancels)"%(field.upper(),record,str(txtselections)), append=True)
      ui.mainloop.draw_screen()
      awaitingCompletion = []
      timestamp = _ownSelections(display, win, selections)

      timeout = None
      skip = False
      while 1:
        if skip and awaitingCompletion == []: break
        while True:
          try:
            (readable, ign, ign) = select.select(select_fds, [], [], timeout)
          except select.error as e:
            if e.args[0] == 4: continue # Interrupted system call
            raise
          break

        if not readable and awaitingCompletion == []:
          break

        for fd in readable:
          if fd == sys.stdin.fileno():
            char = sys.stdin.read(1)
            if char == '\n':
              skip = True
            elif char == '\x1b':
              return
          elif fd in ui_fds:
            # This is a hack to redraw the screen - we really should
            # restructure all this so as not to block instead:
            ui.mainloop.event_loop._loop()

          if fd == display:
            while display.pending_events():
              e = display.next_event()
              if e.type == X.SelectionRequest:
                if handleSelectionRequest(e, field, record, ui):
                  # Don't break immediately, transfer will not have finished.
                  # Wait until the property has been deleted by the requestor
                  awaitingCompletion.append((e.requestor, e.property))
              elif e.type == X.PropertyNotify:
                if (e.window, e.atom) in awaitingCompletion \
                    and e.state == 1: # Deleted
                  awaitingCompletion.remove((e.window, e.atom))
                  # Some programs, such as firefox (when pasting with
                  # shift+insert), don't expect the selection to change suddenly
                  # and behave badly if it does, so wait a moment before ending:
                  timeout = 0.01
              elif e.type == X.SelectionClear:
                if e.time == X.CurrentTime or e.time >= timestamp:
                  # If we lost CLIPBOARD (explicit copy) or no longer control any selection, abort:
                  name = display.get_atom_name(e.atom)
                  selections.remove(e.atom)
                  txtselections.remove(name)
                  if name == 'CLIPBOARD' or not selections:
                    # If transfer is in progress it should be allowed to complete:
                    if awaitingCompletion == []: return
                    timeout = 0.01
                  else:
                    ui.status("Lost control of %s, still ready to send %s via %s..."%(name, field.upper() ,str(txtselections)), append=True)
                    ui.mainloop.draw_screen()
            ui.mainloop.draw_screen()
  finally:
    ui_tty.restore_cbreak(old)
    win.destroy()
    display.close() # I may have introduced a bug while adding the urwid loop
                    # stuff here - the clipboard selection remained grabbed
                    # after destroying the window. This worked around it since
                    # I can't see what is wrong.
    ui.status('Clipboard Cleared', append=True)
コード例 #18
0
ファイル: __main__.py プロジェクト: ViktorNova/xpybar
    code = compile(code, config_file, 'exec')
    g, l = globals(), dict(locals())
    for key in l:
        g[key] = l[key]
    exec(code, g)
else:
    print('No configuration file found')
    sys.exit(1)


open_x()
display = get_display()
outputs = get_monitors()
start()

while True:
    try:
        e = display.next_event()
        if e.type == Xlib.X.DestroyNotify:
            break
        else:
            unhandled_event(e)
    except KeyboardInterrupt:
        break
    redraw()
    display.flush()

stop()
close_x()

コード例 #19
0
    def _monitor(self):
        def _reset():
            LOGGER.debug('Resetting screensaver.')
            self._reset_timer()
            self.SetActive(False)

        def _input_monitor(dev):
            LOGGER.info(f'Monitoring "{dev.name}"')
            for event in dev.read_loop():
                if self.GetSessionIdleTime() < self.input_reset_delay:
                    continue
                _reset()

        # Xlib for monitoring windows
        display = Xlib.display.Display(None)
        root = display.screen().root

        win_attr_mask = (Xlib.X.PropertyChangeMask
                         | Xlib.X.SubstructureNotifyMask)
        root.change_attributes(event_mask=win_attr_mask)

        # evdev for monitoring input devices
        devices = []
        for dev in [evdev.InputDevice(path) for path in evdev.list_devices()]:
            for k, caps in dev.capabilities(absinfo=False).items():
                if (ecodes['BTN_TOUCH'] in caps or ecodes['BTN_MOUSE'] in caps
                        or ecodes['KEY_ENTER'] in caps):
                    devices.append(dev)

        for dev in devices:
            t = threading.Thread(target=_input_monitor, args=(dev, ))
            t.daemon = True
            t.start()

        _reset()

        while True:
            event = display.next_event()

            # Test for new windows
            try:
                if event.type == Xlib.X.CreateNotify:
                    LOGGER.debug('Registering new window')
                    event.window.change_attributes(event_mask=win_attr_mask)

                elif event.type == Xlib.X.MapNotify:
                    wm_class = event.window.get_wm_class()
                    wm_name = event.window.get_wm_name()

                    LOGGER.debug('New window: class: {}, name: {}'.format(
                        wm_class, wm_name))

                    if self._should_ignore(self._idle_reset_ignore, wm_class,
                                           wm_name):
                        LOGGER.debug('Window is in ignore list. '
                                     'Not resetting ScreenSaver.')
                        continue
                    _reset()

                elif event.type == Xlib.X.PropertyNotify:
                    self._handle_fullscreen(display)

            except Xlib.error.XError:
                continue