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)
Exemple #2
0
		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()
 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
def do_input():
    global old_keys

    new_keys = []

    # Map cursor position to key presses
    if blob_pos is not None:
        if blob_pos[0] > 2.0 / 3.0 * WINDOW_WIDTH:
            new_keys.append('d')
        elif blob_pos[0] < 1.0 / 3.0 * WINDOW_WIDTH:
            new_keys.append('a')
        if blob_pos[1] > 2.0 / 3.0 * WINDOW_HEIGHT:
            new_keys.append('w')
        elif blob_pos[1] < 1.0 / 3.0 * WINDOW_HEIGHT:
            new_keys.append('s')

    if glfw.get_key(window, glfw.KEY_ENTER) == glfw.PRESS:
        new_keys.append('Escape')

    # Send press and release events when key state changes
    for char in ['w', 'a', 's', 'd', 'Escape']:
        new = char in new_keys
        old = char in old_keys
        if new:
            if not old:
                display.send_event(dest_window, keyev(char, True),
                        event_mask=1)
        elif old:
            if not new:
                display.send_event(dest_window, keyev(char, False),
                        event_mask=1)

    # Events don't get processed unless they are manually flushed
    while display.pending_events() > 0:
        display.poll_events()

    old_keys = new_keys
Exemple #6
0
#!/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()
Exemple #7
0
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)
Exemple #8
0
def on_event():
	while display.pending_events():
		display.next_event()