def client_startup_complete(self, ss):
     super().client_startup_complete(ss)
     log("is_Wayland()=%s", is_Wayland())
     if is_Wayland():
         ss.may_notify(XPRA_SHADOWWAYLAND_NOTIFICATION_ID,
                       "Wayland Shadow Server",
                       "This shadow session is running under wayland,\n" +
                       "the screen scraping will probably come up empty",
                       icon_name="unticked")
Exemple #2
0
 def do_get_keymap_modifiers(self):
     if not self.keyboard_bindings:
         log.warn("keyboard bindings are not available")
         log.warn(" expect keyboard mapping problems")
         if is_Wayland():
             log.warn(" (incomplete wayland support)")
         return {}, [], []
     try:
         from xpra.gtk_common.error import xsync
         with xsync:
             mod_mappings = self.keyboard_bindings.get_modifier_mappings()
             if mod_mappings:
                 #ie: {"shift" : ["Shift_L", "Shift_R"], "mod1" : "Meta_L", ...]}
                 log("modifier mappings=%s", mod_mappings)
                 meanings = {}
                 for modifier, keys in mod_mappings.items():
                     for _, keyname in keys:
                         meanings[keyname] = modifier
                 #probably a GTK bug? but easier to put here
                 mod_missing = []
                 numlock_mod = meanings.get("Num_Lock", [])
                 if numlock_mod:
                     mod_missing.append(numlock_mod)
                 return meanings, [], mod_missing
     except Exception:
         log.error("failed to use native get_modifier_mappings",
                   exc_info=True)
     return {}, [], []
Exemple #3
0
 def make_hello(self):
     caps = XpraClientBase.make_hello(self)
     caps["session-type"] = get_session_type()
     #don't try to find the server uuid if this platform cannot run servers..
     #(doing so causes lockups on win32 and startup errors on osx)
     if POSIX and not is_Wayland():
         #we may be running inside another server!
         try:
             from xpra.server.server_uuid import get_uuid
             caps["server_uuid"] = get_uuid() or ""
         except:
             pass
     for x in (#generic feature flags:
         "notify-startup-complete", "wants_events", "setting-change",
         "xdg-menu-update",
         ):
         caps[x] = True
     #FIXME: the messy bits without proper namespace:
     caps.update({
         #generic server flags:
         "share"                     : self.client_supports_sharing,
         "lock"                      : self.client_lock,
         })
     caps.update(self.get_keyboard_caps())
     for c in CLIENT_BASES:
         caps.update(c.get_caps(self))
     def u(prefix, c):
         updict(caps, prefix, c, flatten_dicts=False)
     u("control_commands",   self.get_control_commands_caps())
     u("platform",           get_platform_info())
     u("opengl",             self.opengl_props)
     return caps
Exemple #4
0
def _get_xresources():
    if not is_Wayland():
        try:
            from xpra.x11.gtk_x11.prop import prop_get
            from xpra.gtk_common.gtk_util import get_default_root_window
            root = get_default_root_window()
            value = prop_get(root,
                             "RESOURCE_MANAGER",
                             "latin1",
                             ignore_errors=True)
            log("RESOURCE_MANAGER=%s", value)
            if value is None:
                return None
            #parse the resources into a dict:
            values = {}
            options = value.split("\n")
            for option in options:
                if not option:
                    continue
                parts = option.split(":\t", 1)
                if len(parts) != 2:
                    log("skipped invalid option: '%s'", option)
                    continue
                values[parts[0]] = parts[1]
            return values
        except Exception as e:
            log("_get_xresources error: %s", e)
    return None
 def __init__(self, xwindow):
     self.xshm = None
     self.xwindow = xwindow
     assert USE_XSHM and XImage.has_XShm(), "no XShm support"
     if is_Wayland():
         log.warn("Warning: shadow servers do not support Wayland")
         log.warn(" please switch to X11 for shadow support")
Exemple #6
0
def get_workarea():
    if not is_Wayland():
        try:
            d = get_current_desktop()
            if d < 0:
                return None
            workarea = _get_X11_root_property("_NET_WORKAREA", "CARDINAL")
            if not workarea:
                return None
            screenlog("get_workarea() _NET_WORKAREA=%s (%s), len=%s",
                      ellipsizer(workarea), type(workarea), len(workarea))
            #workarea comes as a list of 4 CARDINAL dimensions (x,y,w,h), one for each desktop
            sizeof_long = struct.calcsize(b"@L")
            if len(workarea) < (d + 1) * 4 * sizeof_long:
                screenlog.warn("get_workarea() invalid _NET_WORKAREA value")
            else:
                cur_workarea = workarea[d * 4 * sizeof_long:(d + 1) * 4 *
                                        sizeof_long]
                v = struct.unpack(b"@LLLL", cur_workarea)
                screenlog("get_workarea() %s=%s", hexstr(cur_workarea), v)
                return v
        except Exception as e:
            screenlog("get_workarea()", exc_info=True)
            screenlog.warn("Warning: failed to query workarea: %s", e)
    return None
Exemple #7
0
def get_icc_info():
    if not is_Wayland():
        try:
            data = _get_X11_root_property("_ICC_PROFILE", "CARDINAL")
            if data:
                screenlog("_ICC_PROFILE=%s (%s)", type(data), len(data))
                version = _get_X11_root_property("_ICC_PROFILE_IN_X_VERSION",
                                                 "CARDINAL")
                screenlog(
                    "get_icc_info() found _ICC_PROFILE_IN_X_VERSION=%s, _ICC_PROFILE=%s",
                    hexstr(version or ""), hexstr(data))
                icc = {
                    "source": "_ICC_PROFILE",
                    "data": data,
                }
                if version:
                    try:
                        version = ord(version)
                    except TypeError:
                        pass
                    icc["version"] = version
                screenlog("get_icc_info()=%s", icc)
                return icc
        except Exception as e:
            screenlog.error(
                "Error: cannot access _ICC_PROFILE X11 window property")
            screenlog.error(" %s", e)
            screenlog("get_icc_info()", exc_info=True)
    from xpra.platform.gui import default_get_icc_info
    return default_get_icc_info()
 def verify_capture(self, ss):
     #verify capture works:
     log("verify_capture(%s)", ss)
     try:
         capture = GTKImageCapture(self.root)
         bdata = capture.take_screenshot()[-1]
         nid = XPRA_DISPLAY_NOTIFICATION_ID
         title = body = ""
         if any(b != 0 for b in bdata):
             log("verify_capture(%s) succeeded", ss)
             if is_Wayland():
                 title = "Wayland Session Warning"
                 body = "Wayland sessions are not supported,\n"+\
                         "the screen capture is likely to be empty"
         else:
             log.warn("Warning: shadow screen capture is blank")
             body = "The shadow display capture is blank"
             if get_loaded_kernel_modules("vboxguest", "vboxvideo"):
                 body += "\nthis may be caused by the VirtualBox video driver."
             title = "Shadow Capture Failure"
         log("verify_capture: title=%r, body=%r", ss, title, body)
         if title and body:
             ss.may_notify(nid, title, body, icon_name="server")
     except Exception as e:
         ss.may_notify(nid,
                       "Shadow Error",
                       "Error shadowing the display:\n%s" % e,
                       icon_name="bugs")
Exemple #9
0
    def do_selection_get(self, selection_data, info, time):
        # Either call selection_data.set() or don't, and then return.
        # In practice, send a call across the wire, then block in a recursive
        # main loop.
        def nodata():
            selectiondata_set(selection_data, "STRING", 8, "")

        if not self._enabled or not self._can_receive:
            nodata()
            return
        if not self._have_token:
            try:
                return gtk.Invisible.do_selection_get(self, selection_data,
                                                      info, time)
            except Exception as e:
                log("gtk.Invisible.do_selection_get", exc_info=True)
                if first_time("selection-%s-not-implemented" %
                              self._selection):
                    log.warn("Warning: limited clipboard support for %s",
                             self._selection)
                    if is_Wayland():
                        log.warn(
                            " looks like a Wayland implementation limitation")
                    log.warn(" %s", e)
                nodata()
                return
        selection = selectiondata_get_selection(selection_data)
        target = selectiondata_get_target(selection_data)
        log("do_selection_get(%s, %s, %s) selection=%s", selection_data, info,
            time, selection)
        self._selection_get_events += 1
        assert str(selection) == self._selection, "expected %s but got %s" % (
            selection, self._selection)
        self._request_contents_events += 1
        result = self.emit("get-clipboard-from-remote", self._selection,
                           target)
        if result is None or result["type"] is None:
            log("remote selection fetch timed out or empty")
            nodata()
            return
        data = result["data"]
        dformat = result["format"]
        dtype = result["type"]
        if dtype:
            dtype = bytestostr(dtype)
        log(
            "do_selection_get(%s,%s,%s) calling selection_data.set(%s, %s, %s:%s)",
            selection_data, info, time, dtype, dformat, type(data),
            len(data or ""))
        boc = self._block_owner_change
        self._block_owner_change = True
        if is_gtk3() and dtype in ("UTF8_STRING", "STRING") and dformat == 8:
            #GTK3 workaround: can only use set_text and only on the clipboard?
            s = bytestostr(data)
            self._clipboard.set_text(s, len(s))
        else:
            selectiondata_set(selection_data, dtype, dformat, data)
        if boc is False:
            glib.idle_add(self.remove_block)
Exemple #10
0
    def populate_form(self):
        btn = link_btn(
            "https://github.com/Xpra-org/xpra/blob/master/docs/Features/README.md",
            label="Open Features Documentation",
            icon_name=None)
        self.vbox.pack_start(btn, expand=True, fill=False, padding=20)

        tb = self.table()
        self.bool_cb(tb, "Splash Screen", "splash",
                     "Show a splash screen during startup")
        self.bool_cb(tb, "Read only", "readonly",
                     "Mouse and keyboard events will be ignored")
        self.radio_cb(
            tb, "Border", "border",
            "Show a colored border around xpra windows to differentiate them",
            None, {
                "auto": ("auto,5:off", "auto"),
                "none": FALSE_OPTIONS,
                "blue": ("blue", ),
                "red": ("red", ),
                "green": ("green", )
            })
        self.radio_cb(
            tb, "Header Bar", "headerbar", None, None, {
                "auto": ["auto"] + list(TRUE_OPTIONS),
                "no": FALSE_OPTIONS,
                "force": ("force", ),
            })
        self.sep(tb)
        #"https://github.com/Xpra-org/xpra/blob/master/docs/Features/Notifications.md")
        self.bool_cb(tb, "Xpra's System Tray", "tray")
        self.bool_cb(tb, "Forward System Trays", "system-tray")
        self.bool_cb(tb, "Notifications", "notifications")
        #"https://github.com/Xpra-org/xpra/blob/master/docs/Features/System-Tray.md")
        #self.bool_cb(tb, "Cursors", "cursors")
        #self.bool_cb(tb, "Bell", "bell")
        self.bool_cb(tb, "Modal Windows", "modal-windows")
        self.sep(tb)
        #"https://github.com/Xpra-org/xpra/blob/master/docs/Features/Image-Depth.md")
        self.combo(
            tb, "Mouse Wheel", "mousewheel", {
                "on": "on",
                "no": "disabled",
                "invert-x": "invert X axis",
                "invert-y": "invert Y axis",
                "invert-z": "invert Z axis",
                "invert-all": "invert all axes",
            })
        self.combo(
            tb, "Clipboard", "clipboard-direction", {
                "both": "enabled",
                "to-server": "to server only",
                "to-client": "to client only",
                "disabled": "disabled",
            })
        if POSIX and not OSX and not is_Wayland():
            self.bool_cb(tb, "XSettings", "xsettings")
        self.vbox.show_all()
Exemple #11
0
 def __init__(self):
     super().__init__()
     if not is_Wayland():
         try:
             from xpra.x11.bindings.keyboard_bindings import X11KeyboardBindings  #@UnresolvedImport
             self.keyboard_bindings = X11KeyboardBindings()
         except Exception as e:
             log.error("Error: failed to load posix keyboard bindings")
             log.error(" %s", str(e) or type(e))
Exemple #12
0
 def client_toolkit(self) -> str:
     if POSIX and not OSX:
         backend = os.environ.get("GDK_BACKEND", "")
         if not backend and is_Wayland():
             backend = "Wayland"
         if backend:
             #capitalize, ie: "x11" -> "X11"
             backend = backend[0].upper() + backend[1:]
             return "GTK3 %s" % backend
     return "GTK3"
Exemple #13
0
def _get_xsettings_dict():
    d = {}
    if is_Wayland():
        return d
    v = _get_xsettings()
    if v:
        _, values = v
        for setting_type, prop_name, value, _ in values:
            d[bytestostr(prop_name)] = (setting_type, value)
    return d
Exemple #14
0
def make_window():
    window = Gtk.Window(type=Gtk.WindowType.TOPLEVEL)
    window.set_title("Window Focus")
    window.set_size_request(640, 200)
    window.connect("delete_event", Gtk.main_quit)
    vbox = Gtk.VBox()
    N = 8
    labels = []
    font = Pango.FontDescription("sans 12")
    for _ in range(N):
        l = Gtk.Label()
        l.modify_font(font)
        labels.append(l)
    for l in labels:
        al = Gtk.Alignment(xalign=0, yalign=0.5, xscale=0.0, yscale=0)
        al.add(l)
        vbox.add(al)
    window.add(vbox)
    window.show_all()
    text = deque(maxlen=N)

    def update(s):
        text.append("%s: %s" % (datetime.now(), s))
        for i, t in enumerate(text):
            labels[i].set_text(t)

    #self.selectX11FocusChange(self)
    def focus_in(_window, event):
        update("focus-in-event")

    def focus_out(_window, event):
        update("focus-out-event")

    def has_toplevel_focus(window, _event):
        update("has-toplevel-focus: %s" % window.has_toplevel_focus())

    window.connect("focus-in-event", focus_in)
    window.connect("focus-out-event", focus_out)
    window.connect("notify::has-toplevel-focus", has_toplevel_focus)
    if POSIX and not OSX:
        from xpra.gtk_common.error import xlog
        from xpra.x11.gtk_x11.gdk_display_source import init_gdk_display_source
        from xpra.x11.gtk_x11.gdk_bindings import init_x11_filter
        from xpra.x11.bindings.window_bindings import X11WindowBindings  #pylint: disable=no-name-in-module
        from xpra.os_util import is_Wayland
        if not is_Wayland():
            #x11 focus events:
            gdk_win = window.get_window()
            xid = gdk_win.get_xid()
            init_gdk_display_source()
            os.environ["XPRA_X11_DEBUG_EVENTS"] = "FocusIn,FocusOut"
            init_x11_filter()
            with xlog:
                X11WindowBindings().selectFocusChange(xid)
    return window
Exemple #15
0
def get_current_desktop():
    v = -1
    if not is_Wayland():
        d = None
        try:
            d = _get_X11_root_property("_NET_CURRENT_DESKTOP", "CARDINAL")
            if d:
                v = struct.unpack(b"@L", d)[0]
        except Exception as e:
            log.warn("failed to get current desktop: %s", e)
        log("get_current_desktop() %s=%s", hexstr(d or ""), v)
    return v
Exemple #16
0
def get_number_of_desktops():
    v = 0
    if not is_Wayland():
        d = None
        try:
            d = _get_X11_root_property("_NET_NUMBER_OF_DESKTOPS", "CARDINAL")
            if d:
                v = struct.unpack(b"@L", d)[0]
        except Exception as e:
            screenlog.warn("failed to get number of desktop: %s", e)
        v = max(1, v)
        screenlog("get_number_of_desktops() %s=%s", hexstr(d or ""), v)
    return v
Exemple #17
0
def get_vrefresh():
    v = -1
    if not is_Wayland():
        try:
            from xpra.x11.bindings.randr_bindings import RandRBindings      #@UnresolvedImport
            randr = RandRBindings()
            v = randr.get_vrefresh()
        except Exception as e:
            log("get_vrefresh()", exc_info=True)
            log.warn("Warning: failed to query the display vertical refresh rate:")
            log.warn(" %s", e)
        screenlog("get_vrefresh()=%s", v)
    return v
Exemple #18
0
def _get_randr_dpi():
    if RANDR_DPI and not is_Wayland():
        from xpra.gtk_common.error import xlog
        from xpra.x11.bindings.randr_bindings import RandRBindings  #@UnresolvedImport
        with xlog:
            randr_bindings = RandRBindings()
            wmm, hmm = randr_bindings.get_screen_size_mm()
            w, h = randr_bindings.get_screen_size()
            dpix = iround(w * 25.4 / wmm)
            dpiy = iround(h * 25.4 / hmm)
            screenlog("xdpi=%s, ydpi=%s - size-mm=%ix%i, size=%ix%i", dpix,
                      dpiy, wmm, hmm, w, h)
            return dpix, dpiy
    return -1, -1
Exemple #19
0
def _get_randr_dpi():
    if RANDR_DPI and not is_Wayland():
        from xpra.gtk_common.error import xlog
        with xlog:
            randr_bindings = X11RandRBindings()
            if randr_bindings and randr_bindings.has_randr():
                wmm, hmm = randr_bindings.get_screen_size_mm()
                if wmm > 0 and hmm > 0:
                    w, h = randr_bindings.get_screen_size()
                    dpix = iround(w * 25.4 / wmm)
                    dpiy = iround(h * 25.4 / hmm)
                    screenlog("xdpi=%s, ydpi=%s - size-mm=%ix%i, size=%ix%i",
                              dpix, dpiy, wmm, hmm, w, h)
                    return dpix, dpiy
    return -1, -1
Exemple #20
0
def get_desktop_names():
    v = []
    if not is_Wayland():
        v = ["Main"]
        d = None
        try:
            d = _get_X11_root_property("_NET_DESKTOP_NAMES", "UTF8_STRING")
            if d:
                v = d.split(b"\0")
                if len(v) > 1 and v[-1] == "":
                    v = v[:-1]
        except Exception as e:
            screenlog.warn("failed to get desktop names: %s", e)
        screenlog("get_desktop_names() %s=%s", hexstr(d or ""), v)
    return v
Exemple #21
0
def _get_randr_dpi():
    if RANDR_DPI and not is_Wayland():
        try:
            from xpra.gtk_common.error import xsync
            from xpra.x11.bindings.randr_bindings import RandRBindings  #@UnresolvedImport
            with xsync:
                randr_bindings = RandRBindings()
                wmm, hmm = randr_bindings.get_screen_size_mm()
                w, h =  randr_bindings.get_screen_size()
                dpix = iround(w * 25.4 / wmm)
                dpiy = iround(h * 25.4 / hmm)
                screenlog("xdpi=%s, ydpi=%s - size-mm=%ix%i, size=%ix%i", dpix, dpiy, wmm, hmm, w, h)
                return dpix, dpiy
        except Exception as e:
            screenlog.warn("failed to get dpi: %s", e)
    return -1, -1
Exemple #22
0
 def process_ui_capabilities(self, caps : typedict):
     log("process_ui_capabilities() clipboard_enabled=%s", self.clipboard_enabled)
     if self.clipboard_enabled:
         ch = self.make_clipboard_helper()
         if not ch:
             log.warn("Warning: no clipboard support")
             if is_Wayland():
                 log.warn(" (wayland display)")
         self.clipboard_helper = ch
         self.clipboard_enabled = ch is not None
         log("clipboard helper=%s", ch)
         if self.clipboard_enabled:
             #tell the server about which selections we really want to sync with
             #(could have been translated, or limited if the client only has one, etc)
             self.send_clipboard_selections(ch.get_remote_selections())
             ch.send_all_tokens()
     #ui may want to know this is now set:
     self.emit("clipboard-toggled")
Exemple #23
0
 def get_keymap_spec(self):
     log("get_keymap_spec() keyboard_bindings=%s", self.keyboard_bindings)
     if is_Wayland() or not self.keyboard_bindings:
         locale = self.get_locale_status()
         query_struct = {}
         if locale:
             layout = locale.get("X11 Layout")
             if layout:
                 query_struct["layout"] = layout
         log("query_struct(%s)=%s", locale, query_struct)
         return None, None, query_struct
     query_struct = self.keyboard_bindings.getXkbProperties()
     _query = xkbmap_query_tostring(query_struct)
     log("get_keymap_spec() Xkb query tostring(%s)=%s", query_struct, _query)
     #we no longer support servers via xkbmap_print:
     xkbmap_print = ""
     log("get_keymap_spec()=(%s, %s, %s)", nonl(xkbmap_print), nonl(_query), nonl(query_struct))
     return xkbmap_print, _query, query_struct
Exemple #24
0
 def after_draw_refresh(self, success, message=""):
     plog("after_draw_refresh(%s, %s) pending_refresh=%s", success, message,
          self.pending_refresh)
     backing = self._backing
     if not backing:
         return
     if backing.repaint_all or self._xscale != 1 or self._yscale != 1 or is_Wayland(
     ):
         #easy: just repaint the whole window:
         rw, rh = self.get_size()
         self.idle_add(self.repaint, 0, 0, rw, rh)
         return
     pr = self.pending_refresh
     self.pending_refresh = []
     for x, y, w, h in pr:
         rx, ry, rw, rh = self._client.srect(x, y, w, h)
         if self.window_offset:
             rx += self.window_offset[0]
             ry += self.window_offset[1]
         self.idle_add(self.repaint, rx, ry, rw, rh)
Exemple #25
0
def get_workarea():
    if not is_Wayland():
        try:
            d = get_current_desktop()
            if d<0:
                return None
            workarea = _get_X11_root_property("_NET_WORKAREA", "CARDINAL")
            if not workarea:
                return None
            screenlog("get_workarea()=%s, len=%s", type(workarea), len(workarea))
            #workarea comes as a list of 4 CARDINAL dimensions (x,y,w,h), one for each desktop
            if len(workarea)<(d+1)*4*4:
                screenlog.warn("get_workarea() invalid _NET_WORKAREA value")
            else:
                cur_workarea = workarea[d*4*4:(d+1)*4*4]
                v = struct.unpack(b"=IIII", cur_workarea)
                screenlog("get_workarea() %s=%s", hexstr(cur_workarea), v)
                return v
        except Exception as e:
            screenlog.warn("failed to get workarea: %s", e)
    return None
Exemple #26
0
    def make_hello(self):
        caps = XpraClientBase.make_hello(self)
        caps["session-type"] = get_session_type()
        #don't try to find the server uuid if this platform cannot run servers..
        #(doing so causes lockups on win32 and startup errors on osx)
        if POSIX and not is_Wayland():
            #we may be running inside another server!
            try:
                from xpra.server.server_uuid import get_uuid, get_mode  #pylint: disable=import-outside-toplevel
                if get_mode() != "shadow":
                    caps["server_uuid"] = get_uuid() or ""
            except ImportError:
                pass
        for x in (  #generic feature flags:
                "wants_events",
                "setting-change",
                "xdg-menu-update",
        ):
            caps[x] = True
        caps.update({
            #generic server flags:
            "share": self.client_supports_sharing,
            "lock": self.client_lock,
            "xdg-menu": self.start_new_commands,
        })
        caps.update({"mouse": True})
        caps.update(self.get_keyboard_caps())
        for c in CLIENT_BASES:
            caps.update(c.get_caps(self))

        def u(prefix, c):
            updict(caps, prefix, c, flatten_dicts=False)

        u("control_commands", self.get_control_commands_caps())
        u("platform", get_platform_info())
        u("opengl", self.opengl_props)
        return caps
Exemple #27
0
 def setup_xprops(self):
     #wait for handshake to complete:
     if not is_Wayland():
         self.client.after_handshake(self.do_setup_xprops)
Exemple #28
0
def gl_check():
    if not is_X11() and is_Wayland():
        return "disabled under wayland with GTK3 (buggy)"
    return None
Exemple #29
0
def get_clipboard_native_class():
    if is_Wayland():
        return None
    return "xpra.x11.gtk_x11.clipboard.X11Clipboard"
Exemple #30
0
def get_clipboard_native_class():
    if is_Wayland():
        return "xpra.gtk_common.gtk_clipboard.GTK_Clipboard"
    return "xpra.x11.gtk_x11.clipboard.X11Clipboard"