def main(): import logging logging.basicConfig(format="%(asctime)s %(message)s") logging.root.setLevel(logging.DEBUG) appindicator = get_appindicator() if not appindicator: debug("appindicator not available") return if not can_use_appindicator(): debug("appindicator may not be shown...") from xpra.gtk_common.gobject_compat import import_gobject, import_gtk gobject = import_gobject() gtk = import_gtk() menu = gtk.Menu() item = gtk.MenuItem("Some Menu Item Here") menu.append(item) menu.show_all() a = AppindicatorTray(menu, "test", "xpra.png", None, None, None, gtk.main_quit) a.show() gobject.timeout_add(1000 * 10, gtk.main_quit) gtk.main()
def win32_bonjour_download_warning(gui): from xpra.gtk_common.gobject_compat import import_pango from xpra.gtk_common.gtk_util import DIALOG_MODAL, DESTROY_WITH_PARENT gtk = import_gtk() dialog = gtk.Dialog("Bonjour not found", gui, DIALOG_MODAL | DESTROY_WITH_PARENT) RESPONSE_CANCEL = 1 RESPONSE_DOWNLOAD = 2 dialog.add_button(gtk.STOCK_CANCEL, RESPONSE_CANCEL) dialog.add_button("Download Bonjour", RESPONSE_DOWNLOAD) def add(widget, padding=0): a = gtk.Alignment() a.set(0.5, 0.5, 1, 1) a.add(widget) a.set_padding(padding, padding, padding, padding) dialog.vbox.pack_start(a) pango = import_pango() title = gtk.Label("Bonjour support not found") title.modify_font(pango.FontDescription("sans 14")) add(title, 16) info = gtk.Label("To automatically discover xpra sessions via mDNS,\n" + "you can install 'Bonjour'.\n\n") add(info, 10) dialog.vbox.show_all() def handle_response(dialog, response): dialog.destroy() if response == RESPONSE_DOWNLOAD: import webbrowser webbrowser.open("https://support.apple.com/kb/DL999") dialog.connect("response", handle_response) dialog.show()
def setup_tray(self): try: from xpra.gtk_common.gobject_compat import import_gtk gtk = import_gtk() from xpra.gtk_common.gtk_util import popup_menu_workaround #menu: self.tray_menu = gtk.Menu() self.tray_menu.set_title("Xpra Server") from xpra.gtk_common.about import about self.tray_menu.append( self.traymenuitem("About Xpra", "information.png", None, about)) self.tray_menu.append( self.traymenuitem("Exit", "quit.png", None, self.tray_exit_callback)) self.tray_menu.append( self.traymenuitem("Close Menu", "close.png", None, self.close_tray_menu)) #maybe add: session info, clipboard, sharing, etc #control: disconnect clients self.tray_menu.connect("deactivate", self.tray_menu_deactivated) popup_menu_workaround(self.tray_menu, self.close_tray_menu) self.tray_widget = self.make_tray_widget() self.set_tray_icon(self.tray_icon or "server-notconnected") except ImportError as e: traylog.warn("Warning: failed to load systemtray:") traylog.warn(" %s", e) except Exception as e: traylog.error("Error setting up system tray", exc_info=True)
def main(): import logging logging.basicConfig(format="%(asctime)s %(message)s") logging.root.setLevel(logging.DEBUG) appindicator = get_appindicator() if not appindicator: debug("appindicator not available") return if not can_use_appindicator(): debug("appindicator may not be shown...") from xpra.gtk_common.gobject_compat import import_gobject, import_gtk gobject = import_gobject() gtk = import_gtk() menu = gtk.Menu() item = gtk.MenuItem("Some Menu Item Here") menu.append(item) menu.show_all() a = AppindicatorTray(menu, "test", "xpra.png", None, None, None, gtk.main_quit) a.show() gobject.timeout_add(1000*10, gtk.main_quit) gtk.main()
def main(): from xpra.gtk_common.gobject_compat import import_glib, import_gtk glib = import_glib() gtk = import_gtk() def show(): n = PyNotify_Notifier() n.show_notify("", None, 0, "Test", 0, "", "Summary", "Body...", ["0", "Hello", "1", "Bye"], {}, 0, "") return False glib.idle_add(show) glib.timeout_add(20000, gtk.main_quit) gtk.main()
def setup_tray(self): if OSX: return try: from xpra.gtk_common.gobject_compat import import_gtk gtk = import_gtk() from xpra.gtk_common.gtk_util import popup_menu_workaround #menu: label = u"Xpra Shadow Server" display = os.environ.get("DISPLAY") if POSIX and display: label = u"Xpra %s Shadow Server" % display self.tray_menu = gtk.Menu() self.tray_menu.set_title(label) title_item = gtk.MenuItem() title_item.set_label(label) title_item.set_sensitive(False) title_item.show() self.tray_menu.append(title_item) from xpra.gtk_common.about import about self.tray_menu.append( self.traymenuitem("About Xpra", "information.png", None, about)) if server_features.windows: def readonly_toggled(menuitem): log("readonly_toggled(%s)", menuitem) ro = menuitem.get_active() if ro != self.readonly: self.readonly = ro self.setting_changed("readonly", ro) readonly_menuitem = self.checkitem("Read-only", cb=readonly_toggled, active=self.readonly) self.tray_menu.append(readonly_menuitem) self.tray_menu.append( self.traymenuitem("Exit", "quit.png", None, self.tray_exit_callback)) self.tray_menu.append( self.traymenuitem("Close Menu", "close.png", None, self.close_tray_menu)) #maybe add: session info, clipboard, sharing, etc #control: disconnect clients self.tray_menu.connect("deactivate", self.tray_menu_deactivated) popup_menu_workaround(self.tray_menu, self.close_tray_menu) self.tray_widget = self.make_tray_widget() self.set_tray_icon(self.tray_icon or "server-notconnected") except ImportError as e: traylog.warn("Warning: failed to load systemtray:") traylog.warn(" %s", e) except Exception as e: traylog.error("Error setting up system tray", exc_info=True)
def exec_dialog_subprocess(cmd): try: log("exec_dialog_subprocess(%s)", cmd) kwargs = {} if POSIX: kwargs["close_fds"] = True else: #win32 platform code would create a log file for the command's output, #tell it not to do that: env = os.environ.copy() env["XPRA_LOG_TO_FILE"] = "0" kwargs["env"] = env proc = Popen(cmd, stdout=PIPE, stderr=PIPE, **kwargs) stdout = [] stderr = [] from xpra.gtk_common.gobject_compat import import_gtk gtk = import_gtk() def read_thread(fd, out): while proc.poll() is None: try: v = fd.read() if v: out.append(v) except: time.sleep(0.1) try: gtk.main_quit() except: pass from xpra.make_thread import start_thread start_thread(read_thread, "dialog-stdout-reader", True, (proc.stdout, stdout)) start_thread(read_thread, "dialog-stderr-reader", True, (proc.stderr, stderr)) if is_WSL(): #WSL needs to wait before calling communicate, #is this still needed now that we read using threads? proc.wait() gtk.main() log("exec_dialog_subprocess(%s) returncode=%s", cmd, proc.poll()) if stderr: log.warn("Warning: dialog process error output:") for x in (b"".join(stderr)).decode().splitlines(): log.warn(" %s", x) return proc.returncode, (b"".join(stdout)).decode() except Exception as e: log("exec_dialog_subprocess(..)", exc_info=True) log.error("Error: failed to execute the dialog subcommand") log.error(" %s", e) return -1, None
def check_support(self, force_enable=False): i = self.props gtk = import_gtk() tmp = gtk.Window(WINDOW_TOPLEVEL) tmp.resize(1, 1) tmp.set_decorated(False) tmp.realize() enable_alpha(tmp) win = tmp.get_window() log("check_support(%s) using temporary window=%s", force_enable, tmp) with self.get_paint_context(win): i.update(check_PyOpenGL_support(force_enable)) tmp.destroy() return i
def main(): from xpra.gtk_common.gobject_compat import import_glib, import_gtk glib = import_glib() gtk = import_gtk() def show(): n = DBUS_Notifier_factory() #actions = ["0", "Hello", "1", "Bye"] actions = [] n.show_notify("", None, 0, "Test", 0, "", "Summary", "Body line1\nline2...", actions, {}, 0, "") return False glib.idle_add(show) glib.timeout_add(20000, gtk.main_quit) gtk.main()
def gtk_main_quit_forever(): # We import gtk inside here, rather than at the top of the file, # because importing gtk has the side-effect of trying to connect to # the X server (and this process may block, may cause us to later be # killed if the X server goes away, etc.), and we don't want to impose # that on every user of this function. from xpra.gtk_common.gobject_compat import import_gtk gtk = import_gtk() gtk.main_quit() # So long as there are more nested main loops, re-register ourselves # to be called again: if gtk.main_level() > 1: return True else: # But when we've just quit the outermost main loop, then # unregister ourselves so that it's possible to start the # main-loop again if desired: return False
def main(): from xpra.platform import program_context with program_context("AppIndicator-Test", "AppIndicator Test"): if "-v" in sys.argv: from xpra.log import enable_debug_for enable_debug_for("tray") from xpra.gtk_common.gobject_compat import import_gtk, register_os_signals gtk = import_gtk() menu = gtk.Menu() item = gtk.MenuItem("Some Menu Item Here") menu.append(item) menu.show_all() a = AppindicatorTray(None, None, menu, "test", "xpra.png", None, None, None, gtk.main_quit) a.show() register_os_signals(gtk.main_quit) gtk.main()
def check_support(self, force_enable=False): i = self.props if not self.xdisplay: return { "success": False, "safe": False, "message": "cannot access X11 display", } gtk = import_gtk() tmp = gtk.Window(WINDOW_TOPLEVEL) tmp.resize(1, 1) tmp.set_decorated(False) tmp.realize() enable_alpha(tmp) win = tmp.get_window() log("check_support(%s) using temporary window=%s", force_enable, tmp) with self.get_paint_context(win): i.update(check_PyOpenGL_support(force_enable)) tmp.destroy() return i
def main(): log.enable_debug() appindicator = get_appindicator() if not appindicator: log("appindicator not available") return if not can_use_appindicator(): log("appindicator may not be shown...") from xpra.gtk_common.gobject_compat import import_gobject, import_gtk gobject = import_gobject() gtk = import_gtk() menu = gtk.Menu() item = gtk.MenuItem("Some Menu Item Here") menu.append(item) menu.show_all() a = AppindicatorTray(menu, "test", "xpra.png", None, None, None, gtk.main_quit) a.show() gobject.timeout_add(1000*10, gtk.main_quit) gtk.main()
def setup_tray(self): try: from xpra.gtk_common.gobject_compat import import_gtk gtk = import_gtk() from xpra.gtk_common.gtk_util import popup_menu_workaround #menu: self.tray_menu = gtk.Menu() self.tray_menu.set_title("Xpra Server") from xpra.gtk_common.about import about self.tray_menu.append(self.traymenuitem("About Xpra", "information.png", None, about)) self.tray_menu.append(self.traymenuitem("Exit", "quit.png", None, self.tray_exit_callback)) self.tray_menu.append(self.traymenuitem("Close Menu", "close.png", None, self.close_tray_menu)) #maybe add: session info, clipboard, sharing, etc #control: disconnect clients self.tray_menu.connect("deactivate", self.tray_menu_deactivated) popup_menu_workaround(self.tray_menu, self.close_tray_menu) self.tray_widget = self.make_tray_widget() self.set_tray_icon(self.tray_icon or "server-notconnected") except ImportError as e: traylog.warn("Warning: failed to load systemtray:") traylog.warn(" %s", e) except Exception as e: traylog.error("Error setting up system tray", exc_info=True)
# This file is part of Xpra. # Copyright (C) 2010 Nathaniel Smith <*****@*****.**> # Copyright (C) 2011-2018 Antoine Martin <*****@*****.**> # Xpra is released under the terms of the GNU GPL v2, or, at your option, any # later version. See the file COPYING for details. # A tray implemented using gtk.StatusIcon import os from xpra.os_util import WIN32, OSX, POSIX, PYTHON3, monotonic_time from xpra.util import envbool from xpra.gtk_common.gobject_compat import import_gtk, import_gdk gtk = import_gtk() gdk = import_gdk() from xpra.client.tray_base import TrayBase, log from xpra.gtk_common.gtk_util import get_icon_from_file, get_pixbuf_from_data, get_default_root_window, \ INTERP_HYPER, SHIFT_MASK, ORIENTATION_VERTICAL, ORIENTATION_HORIZONTAL ORIENTATION = { ORIENTATION_HORIZONTAL: "HORIZONTAL", ORIENTATION_VERTICAL: "VERTICAL", } GUESS_GEOMETRY = WIN32 or OSX GUESS_GEOMETRY = envbool("XPRA_GUESS_ICON_GEOMETRY", GUESS_GEOMETRY) log("tray GUESS_GEOMETRY=%s", GUESS_GEOMETRY) class GTKStatusIconTray(TrayBase): def __init__(self, *args, **kwargs):
#!/usr/bin/env python # This file is part of Xpra. # Copyright (C) 2011-2014 Antoine Martin <*****@*****.**> from xpra.gtk_common.gobject_compat import import_gtk, import_gdk, is_gtk3, import_pango, import_gobject from xpra.gtk_common.gtk_util import SHIFT_MASK, LOCK_MASK, CONTROL_MASK, MOD1_MASK, MOD2_MASK, MOD3_MASK, MOD4_MASK, MOD5_MASK import sys gtk = import_gtk() gdk = import_gdk() pango = import_pango() gobject = import_gobject() from xpra.deque import maxdeque from xpra.platform.paths import get_icon from xpra.gtk_common import gtk_util assert gtk_util, "cannot load compat class" modifier_names = { SHIFT_MASK : "Shift", LOCK_MASK : "Lock", CONTROL_MASK : "Control", MOD1_MASK : "mod1", MOD2_MASK : "mod2", MOD3_MASK : "mod3", MOD4_MASK : "mod4", MOD5_MASK : "mod5" } short_modifier_names = { SHIFT_MASK : "S",
def main(): from xpra.platform import program_context with program_context("U2F-Register", "Xpra U2F Registration Tool"): gui = not sys.stdin.isatty() or os.environ.get("MSYSCON") if gui: from xpra.gtk_common.gobject_compat import import_gtk, import_glib gtk = import_gtk() glib = import_glib() from xpra.gtk_common.gtk_util import MESSAGE_INFO, MESSAGE_ERROR, BUTTONS_CLOSE def show_dialog(mode, *msgs): dialog = gtk.MessageDialog(None, 0, mode, BUTTONS_CLOSE, "\n".join(msgs)) dialog.set_title("Xpra U2F Registration Tool") v = dialog.run() dialog.destroy() #run the main loop long enough to destroy the dialog: glib.idle_add(gtk.main_quit) gtk.main() return v def error(*msgs): return show_dialog(MESSAGE_ERROR, *msgs) def info(*msgs): return show_dialog(MESSAGE_INFO, *msgs) else: print("U2F Registration Tool") def printmsgs(*msgs): for x in msgs: print(x) error = info = printmsgs key_handle_filenames = [ os.path.join(d, "u2f-keyhandle.hex") for d in get_user_conf_dirs() ] assert len(key_handle_filenames) > 0 for filename in key_handle_filenames: p = osexpand(filename) key_handle_str = load_binary_file(p) if key_handle_str: error( " found an existing key handle in file '%s':" % p, #" %s" % key_handle_str, " skipping U2F registration", " delete this file if you want to register again") return 1 public_key_filenames = [] for d in get_user_conf_dirs(): public_key_filenames += glob.glob(os.path.join(d, "u2f*.pub")) if public_key_filenames: info( " found %i existing public key%s" % (len(public_key_filenames, engs(public_key_filenames))), *((" - %s" % x) for x in public_key_filenames)) #pick the first directory: conf_dir = osexpand(get_user_conf_dirs()[0]) if not os.path.exists(conf_dir): os.mkdir(conf_dir) from pyu2f.u2f import GetLocalU2FInterface #@UnresolvedImport try: dev = GetLocalU2FInterface() except Exception as e: error("Failed to open local U2F device:", "%s" % (str(e) or type(e))) return 1 info("Please activate your U2F device now to generate a new key") registered_keys = [] challenge = b'01234567890123456789012345678901' #unused rr = dev.Register(APP_ID, challenge, registered_keys) b = rr.registration_data assert b[0] == 5 pubkey = bytes(b[1:66]) khl = b[66] key_handle = bytes(b[67:67 + khl]) #save to files: key_handle_filename = osexpand(key_handle_filenames[0]) f = open(key_handle_filename, "wb") f.write(hexstr(key_handle).encode()) f.close #find a filename we can use for this public key: i = 1 while True: c = "" if i > 1: c = "-%i" public_key_filename = os.path.join(conf_dir, "u2f%s-pub.hex" % c) if not os.path.exists(public_key_filename): break f = open(public_key_filename, "wb") f.write(hexstr(pubkey).encode()) f.close #info("key handle: %s" % csv(hex40(key_handle)), # "saved to file '%s'" % key_handle_filename, # "public key: %s" % csv(hex40(pubkey)), # "saved to file '%s'" % public_key_filename, # ) info( "key handle saved to file:", "'%s'" % key_handle_filename, "public key saved to file:", "'%s'" % public_key_filename, ) return 0
def test_gl_client_window(gl_client_window_class, max_window_size=(1024, 1024), pixel_depth=24, show=False): #try to render using a temporary window: draw_result = {} window = None try: x, y = -100, -100 if show: x, y = 100, 100 w, h = 250, 250 from xpra.client.window_border import WindowBorder border = WindowBorder() default_cursor_data = None noclient = FakeClient() #test with alpha, but not on win32 #because we can't do alpha on win32 with opengl metadata = typedict({b"has-alpha" : not WIN32}) window = gl_client_window_class(noclient, None, None, 2**32-1, x, y, w, h, w, h, metadata, False, typedict({}), border, max_window_size, default_cursor_data, pixel_depth) window_backing = window._backing window_backing.idle_add = no_idle_add window_backing.timeout_add = no_timeout_add window_backing.source_remove = no_source_remove window.realize() window_backing.paint_screen = True pixel_format = "BGRX" bpp = len(pixel_format) options = typedict({"pixel_format" : pixel_format}) stride = bpp*w coding = "rgb32" widget = window_backing._backing widget.realize() def paint_callback(success, message): log("paint_callback(%s, %s)", success, message) draw_result.update({ "success" : success, "message" : message, }) log("OpenGL: testing draw on %s widget %s with %s : %s", window, widget, coding, pixel_format) pix = AtomicInteger(0x7f) REPAINT_DELAY = envint("XPRA_REPAINT_DELAY", 0) def draw(): if PYTHON3: img_data = bytes([pix.increase() % 256]*stride*h) else: img_data = chr(pix.increase() % 256)*stride*h window.draw_region(0, 0, w, h, coding, img_data, stride, 1, options, [paint_callback]) return REPAINT_DELAY>0 #the paint code is actually synchronous here, #so we can check the present_fbo() result: if show: widget.show() window.show() from xpra.gtk_common.gobject_compat import import_gtk, import_glib gtk = import_gtk() glib = import_glib() def window_close_event(*_args): gtk.main_quit() noclient.window_close_event = window_close_event glib.timeout_add(REPAINT_DELAY, draw) gtk.main() else: draw() if window_backing.last_present_fbo_error: return { "success" : False, "message" : "failed to present FBO on screen: %s" % window_backing.last_present_fbo_error } finally: if window: window.destroy() log("test_gl_client_window(..) draw_result=%s", draw_result) return draw_result