def get_wm_name(): wm_name = os.environ.get("XDG_CURRENT_DESKTOP", "") or os.environ.get( "XDG_SESSION_DESKTOP") or os.environ.get("DESKTOP_SESSION") if os.environ.get("XDG_SESSION_TYPE") == "wayland" or os.environ.get( "GDK_BACKEND") == "wayland": if wm_name: wm_name += " on wayland" else: wm_name = "wayland" elif is_X11(): try: wm_check = _get_X11_root_property("_NET_SUPPORTING_WM_CHECK", "WINDOW") if wm_check: xid = struct.unpack(b"@L", wm_check)[0] traylog("_NET_SUPPORTING_WM_CHECK window=%#x", xid) wm_name = _get_X11_window_property(xid, "_NET_WM_NAME", "UTF8_STRING") traylog("_NET_WM_NAME=%s", wm_name) if wm_name: return u(wm_name) except Exception as e: traylog("get_wm_name()", exc_info=True) traylog.error("Error accessing window manager information:") traylog.error(" %s", e) return wm_name
def system_bell(window, device, percent, _pitch, _duration, bell_class, bell_id, bell_name): if not is_X11(): return False global device_bell if device_bell is False: #failed already return False from xpra.gtk_common.error import XError def x11_bell(): global device_bell if device_bell is None: #try to load it: from xpra.x11.bindings.keyboard_bindings import X11KeyboardBindings #@UnresolvedImport device_bell = X11KeyboardBindings().device_bell device_bell(window.get_xid(), device, bell_class, bell_id, percent, bell_name) try: from xpra.gtk_common.error import xlog with xlog: x11_bell() return True except XError as e: log("x11_bell()", exc_info=True) log.error("Error using device_bell: %s", e) log.error(" switching native X11 bell support off") device_bell = False return False
def X11RandRBindings(): if is_X11(): try: from xpra.x11.bindings.randr_bindings import RandRBindings #@UnresolvedImport return RandRBindings() except Exception as e: log("RandRBindings()", exc_info=True) log.error("Error: no X11 RandR bindings") log.error(" %s", e) return None
def update(self): old_hash = self.hash self.query_xkbmap() if is_X11(): try: self.keyboard.update_modifier_map(display_get_default(), self.xkbmap_mod_meanings) except: log.error("error querying modifier map", exc_info=True) log("update() modifier_map=%s, old hash=%s, new hash=%s", self.keyboard.modifier_map, old_hash, self.hash) return old_hash!=self.hash
def X11XI2Bindings(): global X11XI2 if X11XI2 is False: X11XI2 = None if is_X11(): try: from xpra.x11.bindings.xi2_bindings import X11XI2Bindings as _X11XI2Bindings #@UnresolvedImport X11XI2 = _X11XI2Bindings() except Exception: log.error("no XI2 bindings", exc_info=True) return X11XI2
def X11WindowBindings(): global _X11Window if _X11Window is False: _X11Window = None if is_X11(): try: from xpra.x11.bindings.window_bindings import X11WindowBindings as _X11WindowBindings #@UnresolvedImport _X11Window = _X11WindowBindings() except Exception as e: log("X11WindowBindings()", exc_info=True) log.error("Error: no X11 bindings") log.error(" %s", e) return _X11Window
def do_get_wm_name(env): wm_name = env.get( "XDG_CURRENT_DESKTOP", "") or env.get("XDG_SESSION_DESKTOP") or env.get("DESKTOP_SESSION") if env.get("XDG_SESSION_TYPE") == "wayland" or env.get( "GDK_BACKEND") == "wayland": if wm_name: wm_name += " on wayland" else: wm_name = "wayland" elif is_X11(): wm_name = get_x11_wm_name() return wm_name
def get_xkb_rules_names_property(self): #parses the "_XKB_RULES_NAMES" X11 property if not is_X11(): return "" xkb_rules_names = "" from xpra.platform.xposix.gui import _get_X11_root_property prop = _get_X11_root_property("_XKB_RULES_NAMES", "STRING") log("get_xkb_rules_names_property() _XKB_RULES_NAMES=%s", prop) #ie: 'evdev\x00pc104\x00gb,us\x00,\x00\x00' if prop: xkb_rules_names = prop.split("\0") #ie: ['evdev', 'pc104', 'gb,us', ',', '', ''] log("get_xkb_rules_names_property()=%s", xkb_rules_names) return xkb_rules_names
def get_xkb_rules_names_property(self): #parses the "_XKB_RULES_NAMES" X11 property #FIXME: a bit ugly to call gtk here... #but otherwise we have to call XGetWindowProperty and deal with X11 errors.. if not is_X11(): return "" xkb_rules_names = "" from xpra.platform.xposix.gui import _get_X11_root_property prop = _get_X11_root_property("_XKB_RULES_NAMES", "STRING") log("get_xkb_rules_names_property() _XKB_RULES_NAMES=%s", prop) #ie: 'evdev\x00pc104\x00gb,us\x00,\x00\x00' if prop: xkb_rules_names = prop.split("\0") #ie: ['evdev', 'pc104', 'gb,us', ',', '', ''] log("get_xkb_rules_names_property()=%s", xkb_rules_names) return xkb_rules_names
def get_wm_name(): wm_name = os.environ.get("XDG_CURRENT_DESKTOP", "") if is_X11(): try: wm_check = _get_X11_root_property("_NET_SUPPORTING_WM_CHECK", "WINDOW") if wm_check: xid = struct.unpack(b"=I", wm_check)[0] traylog("_NET_SUPPORTING_WM_CHECK window=%#x", xid) wm_name = _get_X11_window_property(xid, "_NET_WM_NAME", "UTF8_STRING") traylog("_NET_WM_NAME=%s", wm_name) return wm_name.decode("utf-8") except Exception as e: traylog.error("Error accessing window manager information:") traylog.error(" %s", e) return wm_name
def _get_xsettings_dpi(): if XSETTINGS_DPI and is_X11(): from xpra.x11.xsettings_prop import XSettingsTypeInteger d = _get_xsettings_dict() for k,div in { "Xft.dpi" : 1, "Xft/DPI" : 1024, "gnome.Xft/DPI" : 1024, #"Gdk/UnscaledDPI" : 1024, ?? }.items(): if k in d: value_type, value = d.get(k) if value_type==XSettingsTypeInteger: actual_value = max(10, min(1000, value//div)) screenlog("_get_xsettings_dpi() found %s=%s, div=%i, actual value=%i", k, value, div, actual_value) return actual_value return -1
def get_x11_wm_name(): if not is_X11(): return None try: wm_check = _get_X11_root_property("_NET_SUPPORTING_WM_CHECK", "WINDOW") if wm_check: xid = struct.unpack(b"@L", wm_check)[0] traylog("_NET_SUPPORTING_WM_CHECK window=%#x", xid) wm_name = _get_X11_window_property(xid, "_NET_WM_NAME", "UTF8_STRING") traylog("_NET_WM_NAME=%s", wm_name) if wm_name: return u(wm_name) except Exception as e: screenlog("get_x11_wm_name()", exc_info=True) screenlog.error("Error accessing window manager information:") screenlog.error(" %s", e) return None
def __init__(self, selection): gtk.Invisible.__init__(self) self.add_events(PROPERTY_CHANGE_MASK) self._selection = selection self._clipboard = GetClipboard(selection) self._enabled = True self._have_token = False #enabled later during setup self._can_send = False self._can_receive = False #this workaround is only needed on win32 AFAIK: self._strip_nullbyte = WIN32 #clients that need a new token for every owner-change: (ie: win32 and osx) #(forces the client to request new contents - prevents stale clipboard data) self._greedy_client = False #semaphore to block the sending of the token when we change the owner ourselves: self._block_owner_change = False self._last_emit_token = 0 self._emit_token_timer = None #counters for info: self._selection_request_events = 0 self._selection_get_events = 0 self._selection_clear_events = 0 self._sent_token_events = 0 self._got_token_events = 0 self._get_contents_events = 0 self._request_contents_events = 0 self._last_targets = () if is_X11(): try: from xpra.x11.gtk_x11.prop import prop_get self.prop_get = prop_get except ImportError as e: log.warn("Warning: limited support for clipboard properties") log.warn(" %s", e) self.prop_get = None self._loop_uuid = "" self._clipboard.connect("owner-change", self.do_owner_changed)
def gl_check(): if not is_X11() and is_Wayland(): return "disabled under wayland with GTK3 (buggy)" return None
eventlog = Logger("posix", "events") screenlog = Logger("posix", "screen") dbuslog = Logger("posix", "dbus") traylog = Logger("posix", "tray") menulog = Logger("posix", "menu") mouselog = Logger("posix", "mouse") xinputlog = Logger("posix", "xinput") from xpra.os_util import bytestostr, hexstr from xpra.util import iround, envbool, envint, csv from xpra.gtk_common.gtk_util import get_xwindow from xpra.os_util import is_X11, is_Wayland X11WindowBindings = None X11XI2Bindings = None if is_X11(): try: from xpra.x11.bindings.window_bindings import X11WindowBindings #@UnresolvedImport from xpra.x11.bindings.xi2_bindings import X11XI2Bindings #@UnresolvedImport except Exception as e: log.error("no X11 bindings", exc_info=True) del e device_bell = None GTK_MENUS = envbool("XPRA_GTK_MENUS", False) RANDR_DPI = envbool("XPRA_RANDR_DPI", True) XSETTINGS_DPI = envbool("XPRA_XSETTINGS_DPI", True) USE_NATIVE_TRAY = envbool("XPRA_USE_NATIVE_TRAY", True) XINPUT_WHEEL_DIV = envint("XPRA_XINPUT_WHEEL_DIV", 15) DBUS_SCREENSAVER = envbool("XPRA_DBUS_SCREENSAVER", False)
def __init__(self, title="Xpra Toolbox"): self.exit_code = 0 self.start_session = None Gtk.Window.__init__(self) self.set_title(title) self.set_border_width(10) self.set_resizable(True) self.set_decorated(True) self.set_position(Gtk.WindowPosition.CENTER) self.set_wmclass("xpra-toolbox", "Xpra-Toolbox") hb = Gtk.HeaderBar() hb.set_show_close_button(True) hb.props.title = title button = Gtk.Button() icon = Gio.ThemedIcon(name="help-about") image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.BUTTON) button.add(image) button.set_tooltip_text("About") button.connect("clicked", self.show_about) hb.add(button) hb.show_all() self.set_titlebar(hb) icon_name = "applications-utilities" self.set_icon_name(icon_name) icon_theme = Gtk.IconTheme.get_default() try: pixbuf = icon_theme.load_icon(icon_name, 96, 0) except Exception: pixbuf = get_icon_pixbuf("xpra") if pixbuf: self.set_icon(pixbuf) add_close_accel(self, self.quit) self.connect("delete_event", self.quit) self.vbox = Gtk.VBox(homogeneous=False, spacing=10) self.add(self.vbox) epath = "example/" cpath = "../" gpath = "../../gtk_common/" def addhbox(blabel, buttons): self.vbox.add(self.label(blabel)) hbox = Gtk.HBox(homogeneous=False, spacing=10) self.vbox.add(hbox) for button in buttons: hbox.add(self.button(*button)) addhbox("Colors:", ( ("Squares", "Shows RGB+Grey squares in a window", epath+"colors_plain.py"), ("Animated", "Shows RGB+Grey squares animated", epath+"colors.py"), ("Bit Depth", "Shows color gradients and visualize bit depth clipping", epath+"colors_gradient.py"), )) addhbox("Transparency and Rendering", ( ("Circle", "Shows a semi-opaque circle in a transparent window", epath+"transparent_window.py"), ("RGB Squares", "RGB+Black shaded squares in a transparent window", epath+"transparent_colors.py"), ("OpenGL", "OpenGL window - transparent on some platforms", cpath+"gl/window_backend.py"), )) addhbox("Widgets:", ( ("Text Entry", "Simple text entry widget", epath+"text_entry.py"), ("File Selector", "Open the file selector widget", epath+"file_chooser.py"), ("Header Bar", "Window with a custom header bar", epath+"header_bar.py"), )) addhbox("Events:", ( ("Grabs", "Test keyboard and pointer grabs", epath+"grabs.py"), ("Clicks", "Double and triple click events", epath+"clicks.py"), ("Focus", "Shows window focus events", epath+"window_focus.py"), )) addhbox("Windows:", ( ("States", "Toggle various window attributes", epath+"window_states.py"), ("Title", "Update the window title", epath+"window_title.py"), ("Opacity", "Change window opacity", epath+"window_opacity.py"), ("Transient", "Show transient windows", epath+"window_transient.py"), ("Override Redirect", "Shows an override redirect window", epath+"window_overrideredirect.py"), )) addhbox("Geometry:", ( ("Size constraints", "Specify window geometry size contraints", epath+"window_geometry_hints.py"), )) if is_X11(): addhbox("X11:", ( ("Move-Resize", "Initiate move resize from application", epath+"initiate_moveresize.py"), )) addhbox("Keyboard and Clipboard:", ( ("Keyboard", "Keyboard event viewer", gpath+"gtk_view_keyboard.py"), ("Clipboard", "Clipboard event viewer", gpath+"gtk_view_clipboard.py"), )) addhbox("Misc:", ( ("Tray", "Show a system tray icon", epath+"tray.py"), ("Font Rendering", "Render characters with and without anti-aliasing", epath+"fontrendering.py"), ("Bell", "Test system bell", epath+"bell.py"), ("Cursors", "Show named cursors", epath+"cursors.py"), )) self.vbox.show_all()