Пример #1
0
 def do_xpra_client_message_event(self, event):
     if event.message_type == "_NET_SYSTEM_TRAY_OPCODE" and event.window == self.tray_window and event.format == 32:
         opcode = event.data[1]
         SYSTEM_TRAY_REQUEST_DOCK = 0
         SYSTEM_TRAY_BEGIN_MESSAGE = 1
         SYSTEM_TRAY_CANCEL_MESSAGE = 2
         if opcode == SYSTEM_TRAY_REQUEST_DOCK:
             xid = event.data[2]
             trap.call_synced(self.dock_tray, xid)
         elif opcode == SYSTEM_TRAY_BEGIN_MESSAGE:
             timeout = event.data[2]
             mlen = event.data[3]
             mid = event.data[4]
             log.info(
                 "tray begin message timeout=%s, mlen=%s, mid=%s - not handled yet!",
                 timeout, mlen, mid)
         elif opcode == SYSTEM_TRAY_CANCEL_MESSAGE:
             mid = event.data[2]
             log.info("tray cancel message for mid=%s - not handled yet!",
                      mid)
     elif event.message_type == "_NET_SYSTEM_TRAY_MESSAGE_DATA":
         assert event.format == 8
         log.info("tray message data - not handled yet!")
     else:
         log.info("do_xpra_client_message_event(%s)", event)
Пример #2
0
def system_bell(window, device, percent, pitch, duration, bell_class, bell_id, bell_name):
    global device_bell
    if device_bell is None:
        return False
    try:
        xwindow = get_xwindow(window)
        trap.call_synced(device_bell, xwindow, device, bell_class, bell_id, percent, bell_name)
        return  True
    except XError, e:
        log.error("error using device_bell: %s, switching native X11 bell support off", e)
        device_bell = None
        return False
Пример #3
0
 def cleanup(self):
     #this must be called from the UI thread!
     remove_event_receiver(self._root, self)
     self._root.set_events(self._saved_event_mask)
     if self._own_x11_filter:
         #only remove the x11 filter if we initialized it (ie: when running in client)
         try:
             trap.call_synced(cleanup_x11_filter)
         except Exception, e:
             log.error("failed to remove x11 event filter: %s", e)
         try:
             trap.call_synced(cleanup_all_event_receivers)
         except Exception, e:
             log.error("failed to remove event receivers: %s", e)
Пример #4
0
 def _process_button_action(self, proto, packet):
     ss = self._server_sources.get(proto)
     if ss is None:
         return
     wid, button, pressed, pointer, modifiers = packet[1:6]
     self._process_mouse_common(proto, wid, pointer, modifiers)
     ss.user_event()
     try:
         trap.call_synced(X11Keyboard.xtest_fake_button, button, pressed)
     except XError:
         err = "Failed to pass on (un)press of mouse button %s" % button
         if button >= 4:
             err += " (perhaps your Xvfb does not support mousewheels?)"
         log.warn(err)
Пример #5
0
 def cleanup(self):
     #this must be called from the UI thread!
     remove_event_receiver(self._root, self)
     self._root.set_events(self._saved_event_mask)
     if self._own_x11_filter:
         #only remove the x11 filter if we initialized it (ie: when running in client)
         try:
             trap.call_synced(cleanup_x11_filter)
         except Exception, e:
             log.error("failed to remove x11 event filter: %s", e)
         try:
             trap.call_synced(cleanup_all_event_receivers)
         except Exception, e:
             log.error("failed to remove event receivers: %s", e)
Пример #6
0
 def _process_button_action(self, proto, packet):
     ss = self._server_sources.get(proto)
     if ss is None:
         return
     wid, button, pressed, pointer, modifiers = packet[1:6]
     self._process_mouse_common(proto, wid, pointer, modifiers)
     ss.user_event()
     try:
         trap.call_synced(X11Keyboard.xtest_fake_button, button, pressed)
     except XError:
         err = "Failed to pass on (un)press of mouse button %s" % button
         if button>=4:
             err += " (perhaps your Xvfb does not support mousewheels?)"
         log.warn(err)
Пример #7
0
def system_bell(window, device, percent, pitch, duration, bell_class, bell_id,
                bell_name):
    global device_bell
    if device_bell is None:
        return False
    try:
        xwindow = get_xwindow(window)
        trap.call_synced(device_bell, xwindow, device, bell_class, bell_id,
                         percent, bell_name)
        return True
    except XError, e:
        log.error(
            "error using device_bell: %s, switching native X11 bell support off",
            e)
        device_bell = None
        return False
Пример #8
0
 def get_settings_blob(self):
     log("Fetching current XSettings data")
     try:
         return trap.call_synced(self._get_settings_blob)
     except XError:
         log("X error while fetching XSettings data; ignored")
         return None
Пример #9
0
 def get_settings_blob(self):
     log("Fetching current XSettings data")
     try:
         return trap.call_synced(self._get_settings_blob)
     except XError:
         log("X error while fetching XSettings data; ignored")
         return None
Пример #10
0
def prop_get(target, key, etype, ignore_errors=False, raise_xerrors=False):
    if isinstance(etype, list):
        scalar_type = etype[0]
    else:
        scalar_type = etype
    (_, atom, _, _, _, _) = _prop_types[scalar_type]
    try:
        data = trap.call_synced(X11Window.XGetWindowProperty, get_xwindow(target), key, atom)
    except NoSuchProperty:
        log.debug("Missing property %s (%s)", key, etype)
        return None
    except XError:
        if raise_xerrors:
            raise
        log.info("Missing window %s or wrong property type %s (%s)", target, key, etype, exc_info=True)
        return None
    except PropertyError:
        if not ignore_errors:
            log.info("Missing property or wrong property type %s (%s)", key, etype, exc_info=True)
        return None
    try:
        return _prop_decode(target, etype, data)
    except:
        if not ignore_errors:
            log.warn("Error parsing property %s (type %s); this may be a"
                     + " misbehaving application, or bug in Xpra\n"
                     + "  Data: %r[...?]",
                     key, etype, data[:160], exc_info=True)
        raise
Пример #11
0
 def do_set_workspace(self, workspace):
     assert HAS_X11_BINDINGS
     root = self.gdk_window().get_screen().get_root_window()
     ndesktops = self.xget_u32_property(root, "_NET_NUMBER_OF_DESKTOPS")
     self.debug("set_workspace() ndesktops=%s", ndesktops)
     if ndesktops is None or ndesktops<=1:
         return  -1
     workspace = max(0, min(ndesktops-1, workspace))
     event_mask = const["SubstructureNotifyMask"] | const["SubstructureRedirectMask"]
     def send():
         root_window = get_xwindow(root)
         window = get_xwindow(self.gdk_window())
         X11WindowBindings.sendClientMessage(root_window, window, False, event_mask, "_NET_WM_DESKTOP",
               workspace, const["CurrentTime"],
               0, 0, 0)
     trap.call_synced(send)
     return workspace
Пример #12
0
 def _owner(self):
     owner_x = X11Window.XGetSelectionOwner(self._selection)
     if owner_x == constants["XNone"]:
         return None
     try:
         return trap.call_synced(get_pywindow, self._clipboard, owner_x)
     except XError:
         log("X error while fetching owner of XSettings data; ignored")
         return None
Пример #13
0
    def set_workspace(self):
        if not HAS_X11_BINDINGS or not self._been_mapped:
            return -1
        root = self.gdk_window().get_screen().get_root_window()
        ndesktops = self.xget_u32_property(root, "_NET_NUMBER_OF_DESKTOPS")
        workspacelog("%s.set_workspace() workspace=%s ndesktops=%s", self, self._window_workspace, ndesktops)
        if ndesktops is None or ndesktops<=1:
            return  -1
        workspace = max(0, min(ndesktops-1, self._window_workspace))
        event_mask = SubstructureNotifyMask | SubstructureRedirectMask

        def send():
            root_xid = root.xid
            xwin = self.gdk_window().xid
            X11Window.sendClientMessage(root_xid, xwin, False, event_mask, "_NET_WM_DESKTOP",
                  workspace, CurrentTime, 0, 0, 0)
        trap.call_synced(send)
        return workspace
Пример #14
0
 def _owner(self):
     owner_x = X11Window.XGetSelectionOwner(self._selection)
     if owner_x == constants["XNone"]:
         return None
     try:
         return trap.call_synced(get_pywindow, self._clipboard, owner_x)
     except XError:
         log("X error while fetching owner of XSettings data; ignored")
         return None
Пример #15
0
 def get_settings(self):
     owner = self.xsettings_owner()
     log("Fetching current XSettings data, owner=%s", owner)
     if owner is None:
         return None
     try:
         return trap.call_synced(prop_get, owner, XSETTINGS, XSETTINGS_TYPE)
     except XError:
         log("X error while fetching XSettings data; ignored")
         return None
Пример #16
0
 def xsettings_owner(self):
     owner_x = X11Window.XGetSelectionOwner(self._selection)
     log("XGetSelectionOwner(%s)=%s", self._selection, owner_x)
     if owner_x == XNone:
         return None
     try:
         return trap.call_synced(get_pywindow, self._clipboard, owner_x)
     except XError:
         log("X error while fetching owner of XSettings data; ignored")
         return None
Пример #17
0
 def get_settings(self):
     owner = self.xsettings_owner()
     log("Fetching current XSettings data, owner=%s", owner)
     if owner is None:
         return None
     try:
         return trap.call_synced(prop_get, owner, XSETTINGS, XSETTINGS_TYPE)
     except XError:
         log("X error while fetching XSettings data; ignored")
         return None
Пример #18
0
def apply_xmodmap(instructions):
    try:
        unset = trap.call_synced(X11Keyboard.set_xmodmap, instructions)
    except:
        log.error("apply_xmodmap", exc_info=True)
        unset = instructions
    if unset is None:
        #None means an X11 error occurred, re-do all:
        unset = instructions
    return unset
Пример #19
0
def apply_xmodmap(instructions):
    try:
        unset = trap.call_synced(X11Keyboard.set_xmodmap, instructions)
    except:
        log.error("apply_xmodmap", exc_info=True)
        unset = instructions
    if unset is None:
        #None means an X11 error occurred, re-do all:
        unset = instructions
    return unset
Пример #20
0
 def xsettings_owner(self):
     owner_x = X11Window.XGetSelectionOwner(self._selection)
     log("XGetSelectionOwner(%s)=%s", self._selection, owner_x)
     if owner_x == XNone:
         return None
     try:
         return trap.call_synced(get_pywindow, self._clipboard, owner_x)
     except XError:
         log("X error while fetching owner of XSettings data; ignored")
         return None
Пример #21
0
    def do_set_workspace(self, workspace):
        assert HAS_X11_BINDINGS
        root = self.gdk_window().get_screen().get_root_window()
        ndesktops = self.xget_u32_property(root, "_NET_NUMBER_OF_DESKTOPS")
        self.debug("set_workspace() ndesktops=%s", ndesktops)
        if ndesktops is None or ndesktops <= 1:
            return -1
        workspace = max(0, min(ndesktops - 1, workspace))
        event_mask = const["SubstructureNotifyMask"] | const[
            "SubstructureRedirectMask"]

        def send():
            root_window = get_xwindow(root)
            window = get_xwindow(self.gdk_window())
            X11WindowBindings.sendClientMessage(root_window, window, False,
                                                event_mask, "_NET_WM_DESKTOP",
                                                workspace,
                                                const["CurrentTime"], 0, 0, 0)

        trap.call_synced(send)
        return workspace
Пример #22
0
    def set_workspace(self):
        if not HAS_X11_BINDINGS or not self._been_mapped:
            return -1
        root = self.gdk_window().get_screen().get_root_window()
        ndesktops = self.xget_u32_property(root, "_NET_NUMBER_OF_DESKTOPS")
        workspacelog("%s.set_workspace() workspace=%s ndesktops=%s", self,
                     self._window_workspace, ndesktops)
        if ndesktops is None or ndesktops <= 1:
            return -1
        workspace = max(0, min(ndesktops - 1, self._window_workspace))
        event_mask = SubstructureNotifyMask | SubstructureRedirectMask

        def send():
            root_xid = root.xid
            xwin = self.gdk_window().xid
            X11Window.sendClientMessage(root_xid, xwin, False, event_mask,
                                        "_NET_WM_DESKTOP", workspace,
                                        CurrentTime, 0, 0, 0)

        trap.call_synced(send)
        return workspace
Пример #23
0
 def do_xpra_client_message_event(self, event):
     if event.message_type=="_NET_SYSTEM_TRAY_OPCODE" and event.window==self.tray_window and event.format==32:
         opcode = event.data[1]
         SYSTEM_TRAY_REQUEST_DOCK = 0
         SYSTEM_TRAY_BEGIN_MESSAGE = 1
         SYSTEM_TRAY_CANCEL_MESSAGE = 2
         if opcode==SYSTEM_TRAY_REQUEST_DOCK:
             xid = event.data[2]
             trap.call_synced(self.dock_tray, xid)
         elif opcode==SYSTEM_TRAY_BEGIN_MESSAGE:
             timeout = event.data[2]
             mlen = event.data[3]
             mid = event.data[4]
             log.info("tray begin message timeout=%s, mlen=%s, mid=%s - not handled yet!", timeout, mlen, mid)
         elif opcode==SYSTEM_TRAY_CANCEL_MESSAGE:
             mid = event.data[2]
             log.info("tray cancel message for mid=%s - not handled yet!", mid)
     elif event.message_type=="_NET_SYSTEM_TRAY_MESSAGE_DATA":
         assert event.format==8
         log.info("tray message data - not handled yet!")
     else:
         log.info("do_xpra_client_message_event(%s)", event)
Пример #24
0
 def set_windows_cursor(self, gtkwindows, new_cursor):
     cursor = None
     if len(new_cursor)>0:
         cursor = None
         if len(new_cursor)>=9 and cursor_names:
             cursor_name = new_cursor[8]
             if cursor_name:
                 gdk_cursor = cursor_names.get(cursor_name.upper())
                 if gdk_cursor is not None:
                     try:
                         from xpra.x11.gtk_x11.error import trap
                         log("setting new cursor: %s=%s", cursor_name, gdk_cursor)
                         cursor = trap.call_synced(gdk.Cursor, gdk_cursor)
                     except:
                         pass
         if cursor is None:
             w, h, xhot, yhot, serial, pixels = new_cursor[2:8]
             log("new cursor at %s,%s with serial=%s, dimensions: %sx%s, len(pixels)=%s" % (xhot,yhot, serial, w,h, len(pixels)))
             pixbuf = gdk.pixbuf_new_from_data(pixels, gdk.COLORSPACE_RGB, True, 8, w, h, w * 4)
             x = max(0, min(xhot, w-1))
             y = max(0, min(yhot, h-1))
             size = gdk.display_get_default().get_default_cursor_size() 
             if size>0 and (size<w or size<h):
                 ratio = float(max(w,h))/size
                 pixbuf = pixbuf.scale_simple(int(w/ratio), int(h/ratio), gdk.INTERP_BILINEAR)
                 x = int(x/ratio)
                 y = int(y/ratio)
             cursor = gdk.Cursor(gdk.display_get_default(), pixbuf, x, y)
     for gtkwindow in gtkwindows:
         if gtk.gtk_version>=(2,14):
             gdkwin = gtkwindow.get_window()
         else:
             gdkwin = gtkwindow.window
         #trays don't have a gdk window
         if gdkwin:
             gdkwin.set_cursor(cursor)
Пример #25
0
    def acquire(self, when):
        old_owner = self._owner()
        if when is self.IF_UNOWNED and old_owner != XNone:
            raise AlreadyOwned

        self.clipboard.set_with_data([("VERSION", 0, 0)],
                                     self._get,
                                     self._clear,
                                     None)

        # Having acquired the selection, we have to announce our existence
        # (ICCCM 2.8, still).  The details here probably don't matter too
        # much; I've never heard of an app that cares about these messages,
        # and metacity actually gets the format wrong in several ways (no
        # MANAGER or owner_window atoms).  But might as well get it as right
        # as possible.

        # To announce our existence, we need:
        #   -- the timestamp we arrived at
        #   -- the manager selection atom
        #   -- the window that registered the selection
        # Of course, because Gtk is doing so much magic for us, we have to do
        # some weird tricks to get at these.

        # Ask ourselves when we acquired the selection:
        ts_data = self.clipboard.wait_for_contents("TIMESTAMP").data
        #data is a timestamp, X11 datatype is Time which is CARD32,
        #(which is 64 bits on 64-bit systems!)
        Lsize = calcsize("@L")
        if len(ts_data)==Lsize:
            ts_num = unpack("@L", ts_data[:Lsize])[0]
        else:
            ts_num = 0      #CurrentTime
            log.warn("invalid data for 'TIMESTAMP': %s", ([hex(ord(x)) for x in ts_data]))
        # Calculate the X atom for this selection:
        selection_xatom = get_xatom(self.atom)
        # Ask X what window we used:
        self._xwindow = X11Window.XGetSelectionOwner(self.atom)

        root = self.clipboard.get_display().get_default_screen().get_root_window()
        X11Window.sendClientMessage(root.xid, root.xid, False, StructureNotifyMask,
                          "MANAGER",
                          ts_num, selection_xatom, self._xwindow, 0, 0)

        if old_owner != XNone and when is self.FORCE:
            # Block in a recursive mainloop until the previous owner has
            # cleared out.
            def getwin():
                window = get_pywindow(self.clipboard, old_owner)
                window.set_events(window.get_events() | gtk.gdk.STRUCTURE_MASK)
                return window
            try:
                window = trap.call_synced(getwin)
                log("got window")
            except XError:
                log("Previous owner is already gone, not blocking")
            else:
                log("Waiting for previous owner to exit...")
                add_event_receiver(window, self)
                gtk.main()
                log("...they did.")
        window = get_pywindow(self.clipboard, self._xwindow)
        window.set_title("Xpra-ManagerSelection")
Пример #26
0
 def do_make_screenshot_packet(self):
     debug = log.debug
     debug("grabbing screenshot")
     regions = []
     OR_regions = []
     for wid in reversed(sorted(self._id_to_window.keys())):
         window = self._id_to_window.get(wid)
         debug("screenshot: window(%s)=%s", wid, window)
         if window is None:
             continue
         if window.is_tray():
             debug("screenshot: skipping tray window %s", wid)
             continue
         if not window.is_managed():
             debug("screenshot: window %s is not/no longer managed", wid)
             continue
         if window.is_OR():
             x, y = window.get_property("geometry")[:2]
         else:
             x, y = self._desktop_manager.window_geometry(window)[:2]
         debug("screenshot: position(%s)=%s,%s", window, x, y)
         w, h = window.get_dimensions()
         debug("screenshot: size(%s)=%sx%s", window, w, h)
         try:
             img = trap.call_synced(window.get_image, 0, 0, w, h)
         except:
             log.warn("screenshot: window %s could not be captured", wid)
             continue
         if img is None:
             log.warn("screenshot: no pixels for window %s", wid)
             continue
         debug("screenshot: image=%s, size=%s", (img, img.get_size()))
         if img.get_pixel_format() not in ("RGB", "RGBA", "XRGB", "BGRX", "ARGB", "BGRA"):
             log.warn("window pixels for window %s using an unexpected rgb format: %s", wid, img.get_pixel_format())
             continue
         item = (wid, x, y, img)
         if window.is_OR():
             OR_regions.append(item)
         elif self._has_focus==wid:
             #window with focus first (drawn last)
             regions.insert(0, item)
         else:
             regions.append(item)
     all_regions = OR_regions+regions
     if len(all_regions)==0:
         debug("screenshot: no regions found, returning empty 0x0 image!")
         return ["screenshot", 0, 0, "png", -1, ""]
     debug("screenshot: found regions=%s, OR_regions=%s", len(regions), len(OR_regions))
     #in theory, we could run the rest in a non-UI thread since we're done with GTK..
     minx = min([x for (_,x,_,_) in all_regions])
     miny = min([y for (_,_,y,_) in all_regions])
     maxx = max([(x+img.get_width()) for (_,x,_,img) in all_regions])
     maxy = max([(y+img.get_height()) for (_,_,y,img) in all_regions])
     width = maxx-minx
     height = maxy-miny
     debug("screenshot: %sx%s, min x=%s y=%s", width, height, minx, miny)
     from PIL import Image                           #@UnresolvedImport
     screenshot = Image.new("RGBA", (width, height))
     for wid, x, y, img in reversed(all_regions):
         pixel_format = img.get_pixel_format()
         target_format = {
                  "XRGB"   : "RGB",
                  "BGRX"   : "RGB",
                  "BGRA"   : "RGBA"}.get(pixel_format, pixel_format)
         try:
             window_image = Image.frombuffer(target_format, (w, h), img.get_pixels(), "raw", pixel_format, img.get_rowstride())
         except:
             log.warn("failed to parse window pixels in %s format", pixel_format)
             continue
         tx = x-minx
         ty = y-miny
         screenshot.paste(window_image, (tx, ty))
     buf = StringIOClass()
     screenshot.save(buf, "png")
     data = buf.getvalue()
     buf.close()
     packet = ["screenshot", width, height, "png", width*4, Compressed("png", data)]
     debug("screenshot: %sx%s %s", packet[1], packet[2], packet[-1])
     return packet
Пример #27
0
 def _setup_listening(self):
     try:
         trap.call_synced(self.do_setup_listening)
     except Exception, e:
         log("PointerGrabHelper._setup_listening() failed: %s", e)
Пример #28
0
 def _manage_client(self, gdkwindow):
     try:
         if gdkwindow not in self._windows:
             trap.call_synced(self.do_manage_client, gdkwindow)
     except Exception, e:
         log("failed to manage client %s: %s", gdkwindow, e)
Пример #29
0
 def _setup_listening(self):
     try:
         trap.call_synced(self.do_setup_listening)
     except Exception, e:
         log("PointerGrabHelper._setup_listening() failed: %s", e)
Пример #30
0
def prop_set(target, key, etype, value):
    trap.call_synced(X11Window.XChangeProperty, get_xwindow(target), key,
                       _prop_encode(target, etype, value))
Пример #31
0
 def _manage_client(self, gdkwindow):
     try:
         if gdkwindow not in self._windows:
             trap.call_synced(self.do_manage_client, gdkwindow)
     except Exception, e:
         log("failed to manage client %s: %s", gdkwindow, e)
Пример #32
0
 def fake_key(self, keycode, press):
     keylog("fake_key(%s, %s)", keycode, press)
     trap.call_synced(X11Keyboard.xtest_fake_key, keycode, press)
Пример #33
0
 def fake_key(self, keycode, press):
     keylog("fake_key(%s, %s)", keycode, press)
     trap.call_synced(X11Keyboard.xtest_fake_key, keycode, press)