def __init__(self, run_callback=None, can_share=False): self.run_callback = run_callback self.window = gtk.Window() self.window.connect("destroy", self.close) self.window.set_default_size(400, 150) self.window.set_border_width(20) self.window.set_title("Start New Command") self.window.modify_bg(STATE_NORMAL, gdk.Color(red=65535, green=65535, blue=65535)) icon_pixbuf = self.get_icon("forward.png") if icon_pixbuf: self.window.set_icon(icon_pixbuf) self.window.set_position(WIN_POS_CENTER) vbox = gtk.VBox(False, 0) vbox.set_spacing(0) # Label: label = gtk.Label("Command to run:") label.modify_font(pango.FontDescription("sans 14")) al = gtk.Alignment(xalign=0, yalign=0.5, xscale=0.0, yscale=0) al.add(label) vbox.add(al) # Actual command: self.entry = gtk.Entry(max=100) self.entry.set_width_chars(32) self.entry.connect('activate', self.run_command) vbox.add(self.entry) if can_share: self.share = gtk.CheckButton("Shared", use_underline=False) #Shared commands will also be shown to other clients self.share.set_active(True) vbox.add(self.share) else: self.share = None # Buttons: hbox = gtk.HBox(False, 20) vbox.pack_start(hbox) def btn(label, tooltip, callback, icon_name=None): btn = gtk.Button(label) btn.set_tooltip_text(tooltip) btn.connect("clicked", callback) if icon_name: icon = self.get_icon(icon_name) if icon: btn.set_image(scaled_image(icon, 24)) hbox.pack_start(btn) return btn btn("Run", "Run this command", self.run_command, "forward.png") btn("Cancel", "", self.close, "quit.png") def accel_close(*args): self.close() add_close_accel(self.window, accel_close) vbox.show_all() self.window.vbox = vbox self.window.add(vbox)
def about(on_close=None): global about_dialog if about_dialog: about_dialog.show() about_dialog.present() return from xpra.platform.paths import get_icon xpra_icon = get_icon("xpra.png") dialog = gtk.AboutDialog() if not is_gtk3(): def on_website_hook(dialog, web, *args): ''' called when the website item is selected ''' webbrowser.open(SITE_URL) def on_email_hook(dialog, mail, *args): webbrowser.open("mailto://[email protected]") gtk.about_dialog_set_url_hook(on_website_hook) gtk.about_dialog_set_email_hook(on_email_hook) if xpra_icon: dialog.set_icon(xpra_icon) dialog.set_name("Xpra") dialog.set_version(__version__) dialog.set_authors(('Antoine Martin <*****@*****.**>', 'Nathaniel Smith <*****@*****.**>', 'Serviware - Arthur Huillet <*****@*****.**>')) _license = load_license() dialog.set_license(_license or "Your installation may be corrupted," + " the license text for GPL version 2 could not be found," + "\nplease refer to:\nhttp://www.gnu.org/licenses/gpl-2.0.txt") dialog.set_comments("\n".join(get_build_info())) dialog.set_website(SITE_URL) dialog.set_website_label(SITE_DOMAIN) if xpra_icon: dialog.set_logo(xpra_icon) if hasattr(dialog, "set_program_name"): dialog.set_program_name(APPLICATION_NAME) def close(*args): close_about() #the about function may be called as a widget callback #so avoid calling the widget as if it was a function! if on_close and hasattr(on_close, '__call__'): on_close() dialog.connect("response", close) add_close_accel(dialog, close) about_dialog = dialog dialog.show()
def __init__(self, options, title="Xpra Session Browser"): gtk.Window.__init__(self) self.exit_code = 0 self.set_title(title) self.set_border_width(20) self.set_resizable(True) self.set_decorated(True) self.set_size_request(440, 200) self.set_position(WIN_POS_CENTER) icon = self.get_pixbuf("xpra") if icon: self.set_icon(icon) add_close_accel(self, self.quit) self.connect("delete_event", self.quit) self.clients = {} self.clients_disconnecting = set() self.child_reaper = getChildReaper() self.vbox = gtk.VBox(False, 20) self.add(self.vbox) title_label = gtk.Label(title) title_label.modify_font(pango.FontDescription("sans 14")) title_label.show() self.vbox.add(title_label) self.warning = gtk.Label(" ") red = color_parse("red") self.warning.modify_fg(STATE_NORMAL, red) self.warning.show() self.vbox.add(self.warning) hbox = gtk.HBox(False, 10) self.password_label = gtk.Label("Password:"******"" #log.info("options=%s (%s)", options, type(options)) self.local_info_cache = {} self.dotxpra = DotXpra(options.socket_dir, options.socket_dirs, username) self.poll_local_sessions() self.populate() glib.timeout_add(5 * 1000, self.update) self.vbox.show() self.show()
def __init__(self, client, session_name, window_icon_pixbuf, conn, get_pixbuf): gtk.Window.__init__(self) self.client = client self.session_name = session_name self.connection = conn self.last_populate_time = 0 self.last_populate_statistics = 0 self.is_closed = False self.get_pixbuf = get_pixbuf if self.session_name == "Xpra": title = "Session Info" else: title = "%s: Session Info" % self.session_name self.set_title(title) self.set_destroy_with_parent(True) self.set_resizable(True) self.set_decorated(True) if window_icon_pixbuf: self.set_icon(window_icon_pixbuf) if is_gtk3(): self.set_position(gtk.WindowPosition.CENTER) else: self.set_position(gtk.WIN_POS_CENTER) #tables on the left in a vbox with buttons at the top: self.tab_box = gtk.VBox(False, 0) self.tab_button_box = gtk.HBox(True, 0) self.tabs = [] #pairs of button, table self.populate_cb = None self.tab_box.pack_start(self.tab_button_box, expand=False, fill=True, padding=0) #Package Table: tb = self.table_tab("package.png", "Software", self.populate_package) #title row: tb.attach(title_box(""), 0, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0) tb.attach(title_box("Client"), 1, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0) tb.attach(title_box("Server"), 2, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0) tb.inc() def make_os_str(sys_platform, platform_release, platform_platform, platform_linux_distribution): s = platform_name(sys_platform, platform_release) if platform_linux_distribution and len( platform_linux_distribution) == 3 and len( platform_linux_distribution[0]) > 0: s += "\n%s" % (" ".join(platform_linux_distribution)) elif platform_platform: s += "\n%s" % platform_platform return s LOCAL_PLATFORM_NAME = make_os_str(sys.platform, python_platform.release(), python_platform.platform(), python_platform.linux_distribution()) SERVER_PLATFORM_NAME = make_os_str( self.client._remote_platform, self.client._remote_platform_release, self.client._remote_platform_platform, self.client._remote_platform_linux_distribution) tb.new_row("Operating System", label(LOCAL_PLATFORM_NAME), label(SERVER_PLATFORM_NAME)) scaps = self.client.server_capabilities from xpra.__init__ import __version__ tb.new_row("Xpra", label(__version__), label(self.client._remote_version or "unknown")) cl_rev, cl_ch, cl_date = "unknown", "", "" try: from xpra.build_info import BUILD_DATE as cl_date from xpra.src_info import REVISION as cl_rev, LOCAL_MODIFICATIONS as cl_ch except: pass def make_version_str(version): if version and type(version) in (tuple, list): version = ".".join([str(x) for x in version]) return version or "unknown" def server_info(*prop_names): for x in prop_names: v = scaps.get(x) if v is not None: return v return None def server_version_info(*prop_names): return make_version_str(server_info(*prop_names)) tb.new_row("Revision", label(cl_rev), label(make_version_str(self.client._remote_revision))) tb.new_row( "Local Changes", label(cl_ch), label( server_version_info("build.local_modifications", "local_modifications"))) tb.new_row("Build date", label(cl_date), label(server_info("build_date", "build.date"))) def client_version_info(prop_name): info = "unknown" if hasattr(gtk, prop_name): info = make_version_str(getattr(gtk, prop_name)) return info if is_gtk3(): tb.new_row("PyGobject", label(gobject._version)) tb.new_row("Client GDK", label(gdk._version)) tb.new_row("GTK", label(gtk._version), label(server_version_info("gtk_version"))) else: tb.new_row( "PyGTK", label(client_version_info("pygtk_version")), label(server_version_info("pygtk.version", "pygtk_version"))) tb.new_row( "GTK", label(client_version_info("gtk_version")), label(server_version_info("gtk.version", "gtk_version"))) tb.new_row( "Python", label(python_platform.python_version()), label( server_version_info("server.python.version", "python_version"))) cl_gst_v, cl_pygst_v = "", "" if HAS_SOUND: try: from xpra.sound.gstreamer_util import gst_version as cl_gst_v, pygst_version as cl_pygst_v except: pass tb.new_row( "GStreamer", label(make_version_str(cl_gst_v)), label(server_version_info("sound.gst.version", "gst_version"))) tb.new_row( "pygst", label(make_version_str(cl_pygst_v)), label(server_version_info("sound.pygst.version", "pygst_version"))) tb.new_row( "OpenGL", label( make_version_str(self.client.opengl_props.get("opengl", "n/a"))), label("n/a")) tb.new_row( "OpenGL Vendor", label(make_version_str(self.client.opengl_props.get("vendor", ""))), label("n/a")) tb.new_row( "PyOpenGL", label( make_version_str( self.client.opengl_props.get("pyopengl", "n/a"))), label("n/a")) # Features Table: tb = self.table_tab("features.png", "Features", self.populate_features) randr_box = gtk.HBox(False, 20) self.server_randr_label = label() self.server_randr_icon = gtk.Image() randr_box.add(self.server_randr_icon) randr_box.add(self.server_randr_label) tb.new_row("RandR Support", randr_box) opengl_box = gtk.HBox(False, 20) self.client_opengl_label = label() self.client_opengl_label.set_line_wrap(True) self.client_opengl_icon = gtk.Image() opengl_box.add(self.client_opengl_icon) opengl_box.add(self.client_opengl_label) tb.new_row("Client OpenGL", opengl_box) self.opengl_buffering = label() tb.new_row("OpenGL Buffering", self.opengl_buffering) self.server_encodings_label = label() tb.new_row("Server Encodings", self.server_encodings_label) self.client_encodings_label = label() tb.new_row("Client Encodings", self.client_encodings_label) self.server_mmap_icon = gtk.Image() tb.new_row("Memory Mapped Transfers", self.server_mmap_icon) self.server_clipboard_icon = gtk.Image() tb.new_row("Clipboard", self.server_clipboard_icon) self.server_notifications_icon = gtk.Image() tb.new_row("Notification Forwarding", self.server_notifications_icon) self.server_bell_icon = gtk.Image() tb.new_row("Bell Forwarding", self.server_bell_icon) self.server_cursors_icon = gtk.Image() tb.new_row("Cursor Forwarding", self.server_cursors_icon) speaker_box = gtk.HBox(False, 20) self.server_speaker_icon = gtk.Image() speaker_box.add(self.server_speaker_icon) self.speaker_codec_label = label() speaker_box.add(self.speaker_codec_label) tb.new_row("Speaker Forwarding", speaker_box) self.server_speaker_codecs_label = label() tb.new_row("Server Codecs", self.server_speaker_codecs_label) self.client_speaker_codecs_label = label() tb.new_row("Client Codecs", self.client_speaker_codecs_label) microphone_box = gtk.HBox(False, 20) self.server_microphone_icon = gtk.Image() microphone_box.add(self.server_microphone_icon) self.microphone_codec_label = label() microphone_box.add(self.microphone_codec_label) tb.new_row("Microphone Forwarding", microphone_box) self.server_microphone_codecs_label = label() tb.new_row("Server Codecs", self.server_microphone_codecs_label) self.client_microphone_codecs_label = label() tb.new_row("Client Codecs", self.client_microphone_codecs_label) # Connection Table: tb = self.table_tab("connect.png", "Connection", self.populate_connection) tb.new_row("Server Endpoint", label(self.connection.target)) if self.client.server_display: tb.new_row("Server Display", label(self.client.server_display)) if "hostname" in scaps: tb.new_row("Server Hostname", label(scaps.get("hostname"))) if self.client.server_platform: tb.new_row("Server Platform", label(self.client.server_platform)) self.server_load_label = label() tb.new_row("Server Load", self.server_load_label, label_tooltip="Average over 1, 5 and 15 minutes") self.session_started_label = label() tb.new_row("Session Started", self.session_started_label) self.session_connected_label = label() tb.new_row("Session Connected", self.session_connected_label) self.input_packets_label = label() tb.new_row("Packets Received", self.input_packets_label) self.input_bytes_label = label() tb.new_row("Bytes Received", self.input_bytes_label) self.output_packets_label = label() tb.new_row("Packets Sent", self.output_packets_label) self.output_bytes_label = label() tb.new_row("Bytes Sent", self.output_bytes_label) self.compression_label = label() tb.new_row("Compression Level", self.compression_label) self.connection_type_label = label() tb.new_row("Connection Type", self.connection_type_label) self.input_encryption_label = label() tb.new_row("Input Encryption", self.input_encryption_label) self.output_encryption_label = label() tb.new_row("Output Encryption", self.output_encryption_label) self.speaker_label = label() self.speaker_details = label(font="monospace 10") tb.new_row("Speaker", self.speaker_label, self.speaker_details) self.microphone_label = label() tb.new_row("Microphone", self.microphone_label) # Details: tb = self.table_tab("browse.png", "Statistics", self.populate_statistics) tb.widget_xalign = 1.0 tb.attach(title_box(""), 0, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0) tb.attach(title_box("Latest"), 1, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0) tb.attach(title_box("Minimum"), 2, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0) tb.attach(title_box("Average"), 3, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0) tb.attach(title_box("90 percentile"), 4, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0) tb.attach(title_box("Maximum"), 5, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0) tb.inc() def maths_labels(): return label(), label(), label(), label(), label() self.server_latency_labels = maths_labels() tb.add_row(label("Server Latency (ms)"), *self.server_latency_labels) self.client_latency_labels = maths_labels() tb.add_row(label("Client Latency (ms)"), *self.client_latency_labels) if self.client.windows_enabled: if self.client.server_info_request: self.batch_labels = maths_labels() tb.add_row(label("Batch Delay (ms)"), *self.batch_labels) self.damage_labels = maths_labels() tb.add_row(label("Damage Latency (ms)"), *self.damage_labels) self.quality_labels = maths_labels() tb.add_row(label("Encoding Quality (pct)"), *self.quality_labels) self.speed_labels = maths_labels() tb.add_row(label("Encoding Speed (pct)"), *self.speed_labels) self.decoding_labels = maths_labels() tb.add_row(label("Decoding Latency (ms)"), *self.decoding_labels) self.regions_per_second_labels = maths_labels() tb.add_row(label("Regions/s"), *self.regions_per_second_labels) self.regions_sizes_labels = maths_labels() tb.add_row(label("Pixels/region"), *self.regions_sizes_labels) self.pixels_per_second_labels = maths_labels() tb.add_row(label("Pixels/s"), *self.pixels_per_second_labels) self.windows_managed_label = label() tb.new_row("Regular Windows", self.windows_managed_label), self.transient_managed_label = label() tb.new_row("Transient Windows", self.transient_managed_label), self.trays_managed_label = label() tb.new_row("Trays Managed", self.trays_managed_label), if self.client.client_supports_opengl: self.opengl_label = label() tb.new_row("OpenGL Windows", self.opengl_label), self.graph_box = gtk.VBox(False, 10) self.add_tab("statistics.png", "Graphs", self.populate_graphs, self.graph_box) bandwidth_label = "Number of bytes measured by the networks sockets" if SHOW_PIXEL_STATS: bandwidth_label += ",\nand number of pixels rendered" self.bandwidth_graph = self.add_graph_button(bandwidth_label, self.save_graphs) self.latency_graph = self.add_graph_button( "The time it takes to send an echo packet and get the reply", self.save_graphs) self.pixel_in_data = maxdeque(N_SAMPLES + 4) self.net_in_bytecount = maxdeque(N_SAMPLES + 4) self.net_out_bytecount = maxdeque(N_SAMPLES + 4) self.set_border_width(15) self.add(self.tab_box) if not is_gtk3(): self.set_geometry_hints(self.tab_box) def window_deleted(*args): self.is_closed = True self.connect('delete_event', window_deleted) self.show_tab(self.tabs[0][1]) self.set_size_request(-1, 480) self.populate() self.populate_all() gobject.timeout_add(1000, self.populate) gobject.timeout_add(100, self.populate_tab) self.connect("realize", self.populate_graphs) add_close_accel(self, self.destroy)
def __init__(self, stack, title, message, callback, image): log("Popup%s", (stack, title, message, callback, image)) self.stack = stack gtk.Window.__init__(self) self.set_size_request(stack.size_x, -1) self.set_decorated(False) self.set_deletable(False) self.set_property("skip-pager-hint", True) self.set_property("skip-taskbar-hint", True) self.connect("enter-notify-event", self.on_hover, True) self.connect("leave-notify-event", self.on_hover, False) self.set_opacity(0.2) self.set_keep_above(True) self.destroy_cb = stack.destroy_popup_cb main_box = gtk.VBox() header_box = gtk.HBox() self.header = gtk.Label() self.header.set_markup("<b>%s</b>" % title) self.header.set_padding(3, 3) self.header.set_alignment(0, 0) header_box.pack_start(self.header, True, True, 5) if True: close_button = gtk.Image() close_button.set_from_stock(gtk.STOCK_CANCEL, gtk.ICON_SIZE_BUTTON) close_button.set_padding(3, 3) close_window = gtk.EventBox() close_window.set_visible_window(False) close_window.connect("button-press-event", self.hide_notification) close_window.add(close_button) header_box.pack_end(close_window, False, False) main_box.pack_start(header_box) body_box = gtk.HBox() if image is not None: self.image = gtk.Image() self.image.set_size_request(70, 70) self.image.set_alignment(0, 0) self.image.set_from_pixbuf(image) body_box.pack_start(self.image, False, False, 5) self.message = gtk.Label() self.message.set_property("wrap", True) self.message.set_size_request(stack.size_x - 90, -1) self.message.set_alignment(0, 0) self.message.set_padding(5, 10) self.message.set_text(message) self.counter = gtk.Label() self.counter.set_alignment(1, 1) self.counter.set_padding(3, 3) self.timeout = stack.timeout body_box.pack_start(self.message, True, False, 5) body_box.pack_end(self.counter, False, False, 5) main_box.pack_start(body_box) if callback: cb_text, cb = callback button = gtk.Button(cb_text) button.set_relief(gtk.RELIEF_NORMAL) def popup_cb_clicked(*args): self.hide_notification() log("popup_cb_clicked%s", args) cb() button.connect("clicked", popup_cb_clicked) alignment = gtk.Alignment(xalign=1.0, yalign=0.5, xscale=0.0, yscale=0.0) alignment.add(button) main_box.pack_start(alignment) self.add(main_box) if stack.bg_color is not None: self.modify_bg(gtk.STATE_NORMAL, stack.bg_color) if stack.fg_color is not None: self.message.modify_fg(gtk.STATE_NORMAL, stack.fg_color) self.header.modify_fg(gtk.STATE_NORMAL, stack.fg_color) self.counter.modify_fg(gtk.STATE_NORMAL, stack.fg_color) self.show_timeout = stack.show_timeout self.hover = False self.show_all() self.w, self.h = self.size_request() self.move(self.get_x(self.w), self.get_y(self.h)) self.wait_timer = None self.fade_out_timer = None self.fade_in_timer = glib.timeout_add(100, self.fade_in) #ensure we dont show it in the taskbar: self.window.set_skip_taskbar_hint(True) self.window.set_skip_pager_hint(True) self.realize() add_close_accel(self, self.hide_notification)
def create_window(self): self.window = gtk.Window() self.window.connect("destroy", self.destroy) self.window.set_default_size(400, 300) self.window.set_border_width(20) self.window.set_title("Xpra Launcher") self.window.modify_bg(STATE_NORMAL, gdk.Color(red=65535, green=65535, blue=65535)) icon_pixbuf = self.get_icon("xpra.png") if icon_pixbuf: self.window.set_icon(icon_pixbuf) self.window.set_position(WIN_POS_CENTER) vbox = gtk.VBox(False, 0) vbox.set_spacing(15) # Title hbox = gtk.HBox(False, 0) if icon_pixbuf: logo_button = gtk.Button("") settings = logo_button.get_settings() settings.set_property('gtk-button-images', True) logo_button.connect("clicked", about) set_tooltip_text(logo_button, "About") image = gtk.Image() image.set_from_pixbuf(icon_pixbuf) logo_button.set_image(image) hbox.pack_start(logo_button, expand=False, fill=False) label = gtk.Label("Connect to xpra server") label.modify_font(pango.FontDescription("sans 14")) hbox.pack_start(label, expand=True, fill=True) vbox.pack_start(hbox) # Mode: hbox = gtk.HBox(False, 20) hbox.set_spacing(20) hbox.pack_start(gtk.Label("Mode: ")) self.mode_combo = gtk.combo_box_new_text() self.mode_combo.get_model().clear() self.mode_combo.append_text("TCP") if "AES" in ENCRYPTION_CIPHERS: self.mode_combo.append_text("TCP + AES") self.mode_combo.append_text("SSH") self.mode_combo.connect("changed", self.mode_changed) hbox.pack_start(self.mode_combo) vbox.pack_start(hbox) # Encoding: hbox = gtk.HBox(False, 20) hbox.set_spacing(20) hbox.pack_start(gtk.Label("Encoding: ")) self.encoding_combo = OptionMenu() def get_current_encoding(): return self.config.encoding def set_new_encoding(e): self.config.encoding = e encodings = [x for x in PREFERED_ENCODING_ORDER if x in self.client.get_encodings()] server_encodings = encodings es = make_encodingsmenu(get_current_encoding, set_new_encoding, encodings, server_encodings) self.encoding_combo.set_menu(es) set_history_from_active(self.encoding_combo) hbox.pack_start(self.encoding_combo) vbox.pack_start(hbox) self.encoding_combo.connect("changed", self.encoding_changed) # Quality hbox = gtk.HBox(False, 20) hbox.set_spacing(20) self.quality_label = gtk.Label("Quality: ") hbox.pack_start(self.quality_label) self.quality_combo = OptionMenu() def set_min_quality(q): self.config.min_quality = q def set_quality(q): self.config.quality = q def get_min_quality(): return self.config.min_quality def get_quality(): return self.config.quality sq = make_min_auto_menu("Quality", MIN_QUALITY_OPTIONS, QUALITY_OPTIONS, get_min_quality, get_quality, set_min_quality, set_quality) self.quality_combo.set_menu(sq) set_history_from_active(self.quality_combo) hbox.pack_start(self.quality_combo) vbox.pack_start(hbox) # Speed hbox = gtk.HBox(False, 20) hbox.set_spacing(20) self.speed_label = gtk.Label("Speed: ") hbox.pack_start(self.speed_label) self.speed_combo = OptionMenu() def set_min_speed(s): self.config.min_speed = s def set_speed(s): self.config.speed = s def get_min_speed(): return self.config.min_speed def get_speed(): return self.config.speed ss = make_min_auto_menu("Speed", MIN_SPEED_OPTIONS, SPEED_OPTIONS, get_min_speed, get_speed, set_min_speed, set_speed) self.speed_combo.set_menu(ss) set_history_from_active(self.speed_combo) hbox.pack_start(self.speed_combo) vbox.pack_start(hbox) # Username@Host:Port hbox = gtk.HBox(False, 0) hbox.set_spacing(5) self.username_entry = gtk.Entry(max=128) self.username_entry.set_width_chars(16) self.username_entry.connect("changed", self.validate) set_tooltip_text(self.username_entry, "SSH username") self.username_label = gtk.Label("@") self.host_entry = gtk.Entry(max=128) self.host_entry.set_width_chars(24) self.host_entry.connect("changed", self.validate) set_tooltip_text(self.host_entry, "hostname") self.ssh_port_entry = gtk.Entry(max=5) self.ssh_port_entry.set_width_chars(5) self.ssh_port_entry.connect("changed", self.validate) set_tooltip_text(self.ssh_port_entry, "SSH port") self.port_entry = gtk.Entry(max=5) self.port_entry.set_width_chars(5) self.port_entry.connect("changed", self.validate) set_tooltip_text(self.port_entry, "port/display") hbox.pack_start(self.username_entry) hbox.pack_start(self.username_label) hbox.pack_start(self.host_entry) hbox.pack_start(self.ssh_port_entry) hbox.pack_start(gtk.Label(":")) hbox.pack_start(self.port_entry) vbox.pack_start(hbox) # Password hbox = gtk.HBox(False, 0) hbox.set_spacing(20) self.password_entry = gtk.Entry(max=128) self.password_entry.set_width_chars(30) self.password_entry.set_text("") self.password_entry.set_visibility(False) self.password_entry.connect("changed", self.password_ok) self.password_entry.connect("changed", self.validate) self.password_label = gtk.Label("Password: "******"Save") set_tooltip_text(self.save_btn, "Save settings to a session file") self.save_btn.connect("clicked", self.save_clicked) hbox.pack_start(self.save_btn) #Load: self.load_btn = gtk.Button("Load") set_tooltip_text(self.load_btn, "Load settings from a session file") self.load_btn.connect("clicked", self.load_clicked) hbox.pack_start(self.load_btn) # Connect button: self.button = gtk.Button("Connect") self.button.connect("clicked", self.connect_clicked) connect_icon = self.get_icon("retry.png") if connect_icon: self.button.set_image(scaled_image(connect_icon, 24)) hbox.pack_start(self.button) def accel_close(*args): gtk.main_quit() add_close_accel(self.window, accel_close) vbox.show_all() self.window.vbox = vbox self.window.add(vbox)
def __init__(self): assert not WIN32 and not OSX gtk.Window.__init__(self) window_defaults(self) self.set_title("Start Xpra Session") self.set_position(WIN_POS_CENTER) self.set_size_request(640, 300) icon = get_pixbuf("xpra") if icon: self.set_icon(icon) self.connect("destroy", self.close) add_close_accel(self, self.close) vbox = gtk.VBox(False, 0) vbox.set_spacing(0) hbox = gtk.HBox(True, 10) self.seamless_btn = gtk.RadioButton(None, "Seamless Session") self.seamless_btn.connect("toggled", self.seamless_toggled) al = gtk.Alignment(xalign=1, yalign=0.5, xscale=0.0, yscale=0) al.add(self.seamless_btn) hbox.add(al) self.desktop_btn = gtk.RadioButton(self.seamless_btn, "Desktop Session") #since they're radio buttons, both get toggled, #so no need to connect to both signals: #self.desktop.connect("toggled", self.desktop_toggled) hbox.add(self.desktop_btn) self.seamless = True vbox.add(hbox) # Label: self.entry_label = gtk.Label("Command to run:") self.entry_label.modify_font(pango.FontDescription("sans 14")) self.entry_al = gtk.Alignment(xalign=0, yalign=0.5, xscale=0.0, yscale=0) self.entry_al.add(self.entry_label) vbox.add(self.entry_al) # input command directly as text (if pyxdg is not installed): self.entry = gtk.Entry() self.entry.set_max_length(255) self.entry.set_width_chars(32) self.entry.connect('activate', self.run_command) vbox.add(self.entry) # or use menus if we have xdg data: hbox = gtk.HBox(False, 20) vbox.add(hbox) self.category_box = hbox self.category_label = gtk.Label("Category:") self.category_combo = gtk.combo_box_new_text() hbox.add(self.category_label) hbox.add(self.category_combo) self.category_combo.connect("changed", self.category_changed) self.categories = {} hbox = gtk.HBox(False, 20) vbox.add(hbox) self.command_box = hbox self.command_label = gtk.Label("Command:") self.command_combo = gtk.combo_box_new_text() hbox.pack_start(self.command_label) hbox.pack_start(self.command_combo) self.command_combo.connect("changed", self.command_changed) self.commands = {} self.xsessions = None self.desktop_entry = None # start options: hbox = gtk.HBox(False, 20) vbox.add(hbox) self.attach_cb = gtk.CheckButton() self.attach_cb.set_label("attach immediately") self.attach_cb.set_active(True) al = gtk.Alignment(xalign=1, yalign=0.5, xscale=0.0, yscale=0) al.add(self.attach_cb) hbox.add(al) self.exit_with_children_cb = gtk.CheckButton() self.exit_with_children_cb.set_label("exit with children") hbox.add(self.exit_with_children_cb) self.exit_with_children_cb.set_active(True) #maybe add: #clipboard, opengl, sharing? # Action buttons: hbox = gtk.HBox(False, 20) vbox.add(hbox) def btn(label, tooltip, callback, icon_name=None): btn = gtk.Button(label) set_tooltip_text(btn, tooltip) btn.connect("clicked", callback) if icon_name: icon = get_pixbuf(icon_name) if icon: btn.set_image(scaled_image(icon, 24)) hbox.pack_start(btn) return btn self.cancel_btn = btn("Cancel", "", self.close, "quit.png") self.run_btn = btn("Start", "Start this command in an xpra session", self.run_command, "forward.png") self.run_btn.set_sensitive(False) vbox.show_all() self.add(vbox)
def __init__(self, run_callback=None, can_share=False): self.run_callback = run_callback self.window = gtk.Window() self.window.connect("destroy", self.close) self.window.set_default_size(400, 150) self.window.set_border_width(20) self.window.set_title("Start New Command") self.window.modify_bg(STATE_NORMAL, gdk.Color(red=65535, green=65535, blue=65535)) icon_pixbuf = self.get_icon("forward.png") if icon_pixbuf: self.window.set_icon(icon_pixbuf) self.window.set_position(WIN_POS_CENTER) vbox = gtk.VBox(False, 0) vbox.set_spacing(0) # Label: label = gtk.Label("Command to run:") label.modify_font(pango.FontDescription("sans 14")) al = gtk.Alignment(xalign=0, yalign=0.5, xscale=0.0, yscale=0) al.add(label) vbox.add(al) # Actual command: self.entry = gtk.Entry() self.entry.set_max_length(255) self.entry.set_width_chars(32) self.entry.connect('activate', self.run_command) vbox.add(self.entry) if can_share: self.share = gtk.CheckButton("Shared", use_underline=False) #Shared commands will also be shown to other clients self.share.set_active(True) vbox.add(self.share) else: self.share = None # Buttons: hbox = gtk.HBox(False, 20) vbox.pack_start(hbox) def btn(label, tooltip, callback, icon_name=None): btn = gtk.Button(label) btn.set_tooltip_text(tooltip) btn.connect("clicked", callback) if icon_name: icon = self.get_icon(icon_name) if icon: btn.set_image(scaled_image(icon, 24)) hbox.pack_start(btn) return btn btn("Run", "Run this command", self.run_command, "forward.png") btn("Cancel", "", self.close, "quit.png") def accel_close(*_args): self.close() add_close_accel(self.window, accel_close) vbox.show_all() self.window.vbox = vbox self.window.add(vbox)
def do_create_window(self): self.window = Gtk.Window() self.window.set_border_width(20) self.window.connect("delete-event", self.destroy) self.window.set_default_size(400, 260) self.window.set_title("Xpra Launcher") self.window.set_position(Gtk.WindowPosition.CENTER) self.window.set_wmclass("xpra-launcher-gui", "Xpra-Launcher-GUI") add_close_accel(self.window, self.destroy) icon = get_icon_pixbuf("connect.png") if icon: self.window.set_icon(icon) hb = Gtk.HeaderBar() hb.set_show_close_button(True) hb.props.title = "Session Launcher" self.window.set_titlebar(hb) hb.add(self.button("About", "help-about", about)) self.bug_tool = None def bug(*_args): if self.bug_tool is None: from xpra.client.gtk_base.bug_report import BugReport self.bug_tool = BugReport() self.bug_tool.init(show_about=False) self.bug_tool.show() hb.add(self.button("Bug Report", "bugs", bug)) if has_mdns(): self.mdns_gui = None def mdns(*_args): if self.mdns_gui is None: from xpra.client.gtk_base.mdns_gui import mdns_sessions self.mdns_gui = mdns_sessions(self.config) def close_mdns(): self.mdns_gui.destroy() self.mdns_gui = None self.mdns_gui.do_quit = close_mdns else: self.mdns_gui.present() hb.add(self.button("Browse Sessions", "mdns", mdns)) hb.show_all() vbox = Gtk.VBox(False, 0) vbox.set_spacing(15) # Title label = Gtk.Label("Connect to xpra server") label.modify_font(Pango.FontDescription("sans 14")) vbox.pack_start(label) # Mode: hbox = Gtk.HBox(False, 5) self.mode_combo = Gtk.ComboBoxText() for x in self.get_connection_modes(): self.mode_combo.append_text(x.upper()) self.mode_combo.connect("changed", self.mode_changed) hbox.pack_start(Gtk.Label("Mode: "), False, False) hbox.pack_start(self.mode_combo, False, False) align_hbox = Gtk.Alignment(xalign = .5) align_hbox.add(hbox) vbox.pack_start(align_hbox) # Username@Host:Port (ssh -> ssh, proxy) vbox_proxy = Gtk.VBox(False, 15) hbox = Gtk.HBox(False, 5) self.proxy_vbox = vbox_proxy self.proxy_username_entry = Gtk.Entry() self.proxy_username_entry.set_max_length(128) self.proxy_username_entry.set_width_chars(16) self.proxy_username_entry.connect("changed", self.validate) self.proxy_username_entry.connect("activate", self.connect_clicked) self.proxy_username_entry.set_tooltip_text("username") self.proxy_host_entry = Gtk.Entry() self.proxy_host_entry.set_max_length(128) self.proxy_host_entry.set_width_chars(24) self.proxy_host_entry.connect("changed", self.validate) self.proxy_host_entry.connect("activate", self.connect_clicked) self.proxy_host_entry.set_tooltip_text("hostname") self.proxy_port_entry = Gtk.Entry() self.proxy_port_entry.set_max_length(5) self.proxy_port_entry.set_width_chars(5) self.proxy_port_entry.connect("changed", self.validate) self.proxy_port_entry.connect("activate", self.connect_clicked) self.proxy_port_entry.set_tooltip_text("SSH port") hbox.pack_start(Gtk.Label("Proxy: "), False, False) hbox.pack_start(self.proxy_username_entry, True, True) hbox.pack_start(Gtk.Label("@"), False, False) hbox.pack_start(self.proxy_host_entry, True, True) hbox.pack_start(self.proxy_port_entry, False, False) vbox_proxy.pack_start(hbox) # Password hbox = Gtk.HBox(False, 5) self.proxy_password_hbox = hbox self.proxy_password_entry = Gtk.Entry() self.proxy_password_entry.set_max_length(128) self.proxy_password_entry.set_width_chars(30) self.proxy_password_entry.set_text("") self.proxy_password_entry.set_visibility(False) self.proxy_password_entry.connect("changed", self.password_ok) self.proxy_password_entry.connect("changed", self.validate) self.proxy_password_entry.connect("activate", self.connect_clicked) hbox.pack_start(Gtk.Label("Proxy Password"), False, False) hbox.pack_start(self.proxy_password_entry, True, True) vbox_proxy.pack_start(hbox) # Private key hbox = Gtk.HBox(False, 5) self.pkey_hbox = hbox self.proxy_key_label = Gtk.Label("Proxy private key path (PPK):") self.proxy_key_entry = Gtk.Entry() self.proxy_key_browse = Gtk.Button("Browse") self.proxy_key_browse.connect("clicked", self.proxy_key_browse_clicked) hbox.pack_start(self.proxy_key_label, False, False) hbox.pack_start(self.proxy_key_entry, True, True) hbox.pack_start(self.proxy_key_browse, False, False) vbox_proxy.pack_start(hbox) # Check boxes hbox = Gtk.HBox(False, 5) self.check_boxes_hbox = hbox self.password_scb = Gtk.CheckButton("Server password same as proxy") self.password_scb.set_mode(True) self.password_scb.set_active(True) self.password_scb.connect("toggled", self.validate) align_password_scb = Gtk.Alignment(xalign = 1.0) align_password_scb.add(self.password_scb) self.username_scb = Gtk.CheckButton("Server username same as proxy") self.username_scb.set_mode(True) self.username_scb.set_active(True) self.username_scb.connect("toggled", self.validate) align_username_scb = Gtk.Alignment(xalign = 0.0) align_username_scb.add(self.username_scb) hbox.pack_start(align_username_scb, True, True) hbox.pack_start(align_password_scb, True, True) vbox_proxy.pack_start(hbox) # condiditonal stuff that goes away for "normal" ssh vbox.pack_start(vbox_proxy) # Username@Host:Port (main) hbox = Gtk.HBox(False, 5) self.username_entry = Gtk.Entry() self.username_entry.set_max_length(128) self.username_entry.set_width_chars(16) self.username_entry.connect("changed", self.validate) self.username_entry.connect("activate", self.connect_clicked) self.username_entry.set_tooltip_text("username") self.host_entry = Gtk.Entry() self.host_entry.set_max_length(128) self.host_entry.set_width_chars(24) self.host_entry.connect("changed", self.validate) self.host_entry.connect("activate", self.connect_clicked) self.host_entry.set_tooltip_text("hostname") self.ssh_port_entry = Gtk.Entry() self.ssh_port_entry.set_max_length(5) self.ssh_port_entry.set_width_chars(5) self.ssh_port_entry.connect("changed", self.validate) self.ssh_port_entry.connect("activate", self.connect_clicked) self.ssh_port_entry.set_tooltip_text("SSH port") self.port_entry = Gtk.Entry() self.port_entry.set_max_length(5) self.port_entry.set_width_chars(5) self.port_entry.connect("changed", self.validate) self.port_entry.connect("activate", self.connect_clicked) self.port_entry.set_tooltip_text("port/display") hbox.pack_start(Gtk.Label("Server:"), False, False) hbox.pack_start(self.username_entry, True, True) hbox.pack_start(Gtk.Label("@"), False, False) hbox.pack_start(self.host_entry, True, True) hbox.pack_start(self.ssh_port_entry, False, False) hbox.pack_start(Gtk.Label(":"), False, False) hbox.pack_start(self.port_entry, False, False) vbox.pack_start(hbox) # Password hbox = Gtk.HBox(False, 5) self.password_hbox = hbox self.password_entry = Gtk.Entry() self.password_entry.set_max_length(128) self.password_entry.set_width_chars(30) self.password_entry.set_text("") self.password_entry.set_visibility(False) self.password_entry.connect("changed", self.password_ok) self.password_entry.connect("changed", self.validate) self.password_entry.connect("activate", self.connect_clicked) hbox.pack_start(Gtk.Label("Server Password:"******"Disable Strict Host Key Check") self.nostrict_host_check.set_active(False) al = Gtk.Alignment(xalign=0.5, yalign=0.5, xscale=0.0, yscale=0) al.add(self.nostrict_host_check) hbox.pack_start(al) vbox.pack_start(hbox) # Info Label self.info = Gtk.Label() self.info.set_line_wrap(True) self.info.set_size_request(360, -1) self.info.modify_fg(Gtk.StateType.NORMAL, red) vbox.pack_start(self.info) hbox = Gtk.HBox(False, 0) hbox.set_spacing(20) self.advanced_options_check = Gtk.CheckButton("Advanced Options") self.advanced_options_check.connect("toggled", self.advanced_options_toggled) self.advanced_options_check.set_active(False) al = Gtk.Alignment(xalign=0.5, yalign=0.5, xscale=0.0, yscale=0) al.add(self.advanced_options_check) hbox.pack_start(al) vbox.pack_start(hbox) self.advanced_box = Gtk.VBox() vbox.pack_start(self.advanced_box) # Encoding: hbox = Gtk.HBox(False, 20) hbox.set_spacing(20) hbox.pack_start(Gtk.Label("Encoding: ")) self.encoding_combo = Gtk.MenuButton() encodings = ["auto"]+[x for x in PREFERRED_ENCODING_ORDER] server_encodings = encodings es = make_encodingsmenu(self.get_current_encoding, self.set_new_encoding, encodings, server_encodings) self.encoding_combo.set_popup(es) hbox.pack_start(self.encoding_combo) self.advanced_box.pack_start(hbox) self.set_new_encoding(self.config.encoding) # Sharing: self.sharing = Gtk.CheckButton("Sharing") self.sharing.set_active(bool(self.config.sharing)) self.sharing.set_tooltip_text("allow multiple concurrent users to connect") al = Gtk.Alignment(xalign=0.5, yalign=0.5, xscale=0.0, yscale=0) al.add(self.sharing) self.advanced_box.pack_start(al) # Buttons: hbox = Gtk.HBox(False, 20) vbox.pack_start(hbox) #Save: self.save_btn = Gtk.Button("Save") self.save_btn.set_tooltip_text("Save settings to a session file") self.save_btn.connect("clicked", self.save_clicked) hbox.pack_start(self.save_btn) #Load: self.load_btn = Gtk.Button("Load") self.load_btn.set_tooltip_text("Load settings from a session file") self.load_btn.connect("clicked", self.load_clicked) hbox.pack_start(self.load_btn) # Connect button: self.connect_btn = Gtk.Button("Connect") self.connect_btn.connect("clicked", self.connect_clicked) connect_icon = get_icon_pixbuf("retry.png") if connect_icon: self.connect_btn.set_image(scaled_image(connect_icon, 24)) hbox.pack_start(self.connect_btn) vbox.show_all() self.advanced_options_toggled() self.window.vbox = vbox self.window.add(vbox)
def setup_window(self): self.window = gtk.Window() self.window.connect("destroy", self.close) self.window.set_default_size(400, 300) self.window.set_border_width(20) self.window.set_title("Xpra Bug Report") self.window.modify_bg(STATE_NORMAL, gdk.Color(red=65535, green=65535, blue=65535)) icon_pixbuf = self.get_icon("bugs.png") if icon_pixbuf: self.window.set_icon(icon_pixbuf) self.window.set_position(WIN_POS_CENTER) vbox = gtk.VBox(False, 0) vbox.set_spacing(15) # Title hbox = gtk.HBox(False, 0) icon_pixbuf = self.get_icon("xpra.png") if icon_pixbuf and self.show_about: logo_button = gtk.Button("") settings = logo_button.get_settings() settings.set_property('gtk-button-images', True) logo_button.connect("clicked", about) set_tooltip_text(logo_button, "About") image = gtk.Image() image.set_from_pixbuf(icon_pixbuf) logo_button.set_image(image) hbox.pack_start(logo_button, expand=False, fill=False) label = gtk.Label("Xpra Bug Report Tool") label.modify_font(pango.FontDescription("sans 14")) hbox.pack_start(label, expand=True, fill=True) vbox.pack_start(hbox) #the box containing all the input: ibox = gtk.VBox(False, 0) ibox.set_spacing(3) vbox.pack_start(ibox) # Description al = gtk.Alignment(xalign=0, yalign=0.5, xscale=0.0, yscale=0) al.add(gtk.Label("Please describe the problem:")) ibox.pack_start(al) #self.description = gtk.Entry(max=128) #self.description.set_width_chars(40) self.description = gtk.TextView() self.description.set_accepts_tab(True) self.description.set_justification(JUSTIFY_LEFT) self.description.set_border_width(2) self.description.set_size_request(300, 80) self.description.modify_bg( STATE_NORMAL, gdk.Color(red=32768, green=32768, blue=32768)) ibox.pack_start(self.description, expand=False, fill=False) # Toggles: al = gtk.Alignment(xalign=0, yalign=0.5, xscale=0.0, yscale=0) al.add(gtk.Label("Include:")) ibox.pack_start(al) #generic toggles: from xpra.gtk_common.keymap import get_gtk_keymap from xpra.codecs.loader import codec_versions, load_codecs load_codecs() try: from xpra.sound.gstreamer_util import get_info as get_sound_info except: get_sound_info = None if self.opengl_info: def get_gl_info(): return self.opengl_info else: try: from xpra.client.gl.gl_check import check_support def get_gl_info(): return check_support(force_enable=True) except: get_gl_info = None from xpra.net.net_util import get_info as get_net_info from xpra.platform.paths import get_info as get_path_info from xpra.version_util import get_version_info, get_platform_info, get_host_info def get_sys_info(): d = {} for k, v in { "version": get_version_info(), "platform": get_platform_info(), "host": get_host_info(), "paths": get_path_info(), "gtk": get_gtk_version_info(), "user": get_user_info(), "env": os.environ, }.items(): updict(d, k, v) return d get_screenshot, take_screenshot_fn = None, None #screenshot: may have OS-specific code try: from xpra.platform.gui import take_screenshot take_screenshot_fn = take_screenshot except: log("failed to load platfrom specific screenshot code", exc_info=True) if not take_screenshot_fn: #default: gtk screen capture try: from xpra.server.gtk_root_window_model import GTKRootWindowModel rwm = GTKRootWindowModel(gtk.gdk.get_default_root_window()) take_screenshot_fn = rwm.take_screenshot except: log("failed to load gtk screenshot code", exc_info=True) log("take_screenshot_fn=%s", take_screenshot_fn) if take_screenshot_fn: def get_screenshot(): #take_screenshot() returns: w, h, "png", rowstride, data return take_screenshot_fn()[4] self.toggles = ( ("system", "txt", "System", get_sys_info, "Xpra version, platform and host information"), ("network", "txt", "Network", get_net_info, "Compression, packet encoding and encryption"), ("encoding", "txt", "Encodings", codec_versions, "Picture encodings supported"), ("opengl", "txt", "OpenGL", get_gl_info, "OpenGL driver and features"), ("sound", "txt", "Sound", get_sound_info, "Sound codecs and GStreamer version information"), ("keyboard", "txt", "Keyboard Mapping", get_gtk_keymap, "Keyboard layout and key mapping"), ("xpra-info", "txt", "Server Info", self.xpra_info, "Full server information from 'xpra info'"), ("screenshot", "png", "Screenshot", get_screenshot, ""), ) for name, _, title, value_cb, tooltip in self.toggles: cb = gtk.CheckButton(title + [" (not available)", ""][bool(value_cb)]) cb.set_active(self.includes.get(name, True)) cb.set_sensitive(bool(value_cb)) set_tooltip_text(cb, tooltip) ibox.pack_start(cb) setattr(self, name, cb) # Buttons: hbox = gtk.HBox(False, 20) vbox.pack_start(hbox) def btn(label, tooltip, callback, icon_name=None): btn = gtk.Button(label) set_tooltip_text(btn, tooltip) btn.connect("clicked", callback) if icon_name: icon = self.get_icon(icon_name) if icon: btn.set_image(scaled_image(icon, 24)) hbox.pack_start(btn) return btn #Copy: btn("Copy to clipboard", "Copy all data to clipboard", self.copy_clicked, "clipboard.png") btn("Save", "Save Bug Report", self.save_clicked, "download.png") btn("Cancel", "", self.close, "quit.png") def accel_close(*args): self.close() add_close_accel(self.window, accel_close) vbox.show_all() self.window.vbox = vbox self.window.add(vbox)
def __init__(self, client, session_name, window_icon_pixbuf, conn, get_pixbuf): gtk.Window.__init__(self) self.client = client self.session_name = session_name self.connection = conn self.last_populate_time = 0 self.last_populate_statistics = 0 self.is_closed = False self.get_pixbuf = get_pixbuf if self.session_name == "Xpra": title = "Session Info" else: title = "%s: Session Info" % self.session_name self.set_title(title) self.set_destroy_with_parent(True) self.set_resizable(True) self.set_decorated(True) if window_icon_pixbuf: self.set_icon(window_icon_pixbuf) if is_gtk3(): self.set_position(gtk.WindowPosition.CENTER) else: self.set_position(gtk.WIN_POS_CENTER) # tables on the left in a vbox with buttons at the top: self.tab_box = gtk.VBox(False, 0) self.tab_button_box = gtk.HBox(True, 0) self.tabs = [] # pairs of button, table self.populate_cb = None self.tab_box.pack_start(self.tab_button_box, expand=False, fill=True, padding=0) # Package Table: tb = self.table_tab("package.png", "Software", self.populate_package) # title row: tb.attach(title_box(""), 0, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0) tb.attach(title_box("Client"), 1, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0) tb.attach(title_box("Server"), 2, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0) tb.inc() def make_os_str(sys_platform, platform_release, platform_platform, platform_linux_distribution): s = platform_name(sys_platform, platform_release) if ( platform_linux_distribution and len(platform_linux_distribution) == 3 and len(platform_linux_distribution[0]) > 0 ): s += "\n%s" % (" ".join(platform_linux_distribution)) elif platform_platform: s += "\n%s" % platform_platform return s LOCAL_PLATFORM_NAME = make_os_str( sys.platform, python_platform.release(), python_platform.platform(), python_platform.linux_distribution() ) SERVER_PLATFORM_NAME = make_os_str( self.client._remote_platform, self.client._remote_platform_release, self.client._remote_platform_platform, self.client._remote_platform_linux_distribution, ) tb.new_row("Operating System", label(LOCAL_PLATFORM_NAME), label(SERVER_PLATFORM_NAME)) scaps = self.client.server_capabilities from xpra.__init__ import __version__ tb.new_row("Xpra", label(__version__), label(self.client._remote_version or "unknown")) cl_rev, cl_ch, cl_date = "unknown", "", "" try: from xpra.build_info import BUILD_DATE as cl_date from xpra.src_info import REVISION as cl_rev, LOCAL_MODIFICATIONS as cl_ch except: pass def make_version_str(version): if version and type(version) in (tuple, list): version = ".".join([str(x) for x in version]) return version or "unknown" def server_info(*prop_names): for x in prop_names: v = scaps.get(x) if v is not None: return v return None def server_version_info(*prop_names): return make_version_str(server_info(*prop_names)) tb.new_row("Revision", label(cl_rev), label(make_version_str(self.client._remote_revision))) tb.new_row( "Local Changes", label(cl_ch), label(server_version_info("build.local_modifications", "local_modifications")), ) tb.new_row("Build date", label(cl_date), label(server_info("build_date", "build.date"))) def client_version_info(prop_name): info = "unknown" if hasattr(gtk, prop_name): info = make_version_str(getattr(gtk, prop_name)) return info if is_gtk3(): tb.new_row("PyGobject", label(gobject._version)) tb.new_row("Client GDK", label(gdk._version)) tb.new_row("GTK", label(gtk._version), label(server_version_info("gtk_version"))) else: tb.new_row( "PyGTK", label(client_version_info("pygtk_version")), label(server_version_info("pygtk.version", "pygtk_version")), ) tb.new_row( "GTK", label(client_version_info("gtk_version")), label(server_version_info("gtk.version", "gtk_version")), ) tb.new_row( "Python", label(python_platform.python_version()), label(server_version_info("server.python.version", "python_version")), ) cl_gst_v, cl_pygst_v = "", "" if HAS_SOUND: try: from xpra.sound.gstreamer_util import gst_version as cl_gst_v, pygst_version as cl_pygst_v except: pass tb.new_row( "GStreamer", label(make_version_str(cl_gst_v)), label(server_version_info("sound.gst.version", "gst_version")), ) tb.new_row( "pygst", label(make_version_str(cl_pygst_v)), label(server_version_info("sound.pygst.version", "pygst_version")), ) tb.new_row("OpenGL", label(make_version_str(self.client.opengl_props.get("opengl", "n/a"))), label("n/a")) tb.new_row("OpenGL Vendor", label(make_version_str(self.client.opengl_props.get("vendor", ""))), label("n/a")) tb.new_row("PyOpenGL", label(make_version_str(self.client.opengl_props.get("pyopengl", "n/a"))), label("n/a")) # Features Table: tb = self.table_tab("features.png", "Features", self.populate_features) randr_box = gtk.HBox(False, 20) self.server_randr_label = label() self.server_randr_icon = gtk.Image() randr_box.add(self.server_randr_icon) randr_box.add(self.server_randr_label) tb.new_row("RandR Support", randr_box) opengl_box = gtk.HBox(False, 20) self.client_opengl_label = label() self.client_opengl_label.set_line_wrap(True) self.client_opengl_icon = gtk.Image() opengl_box.add(self.client_opengl_icon) opengl_box.add(self.client_opengl_label) tb.new_row("Client OpenGL", opengl_box) self.opengl_buffering = label() tb.new_row("OpenGL Buffering", self.opengl_buffering) self.server_encodings_label = label() tb.new_row("Server Encodings", self.server_encodings_label) self.client_encodings_label = label() tb.new_row("Client Encodings", self.client_encodings_label) self.server_mmap_icon = gtk.Image() tb.new_row("Memory Mapped Transfers", self.server_mmap_icon) self.server_clipboard_icon = gtk.Image() tb.new_row("Clipboard", self.server_clipboard_icon) self.server_notifications_icon = gtk.Image() tb.new_row("Notification Forwarding", self.server_notifications_icon) self.server_bell_icon = gtk.Image() tb.new_row("Bell Forwarding", self.server_bell_icon) self.server_cursors_icon = gtk.Image() tb.new_row("Cursor Forwarding", self.server_cursors_icon) speaker_box = gtk.HBox(False, 20) self.server_speaker_icon = gtk.Image() speaker_box.add(self.server_speaker_icon) self.speaker_codec_label = label() speaker_box.add(self.speaker_codec_label) tb.new_row("Speaker Forwarding", speaker_box) self.server_speaker_codecs_label = label() tb.new_row("Server Codecs", self.server_speaker_codecs_label) self.client_speaker_codecs_label = label() tb.new_row("Client Codecs", self.client_speaker_codecs_label) microphone_box = gtk.HBox(False, 20) self.server_microphone_icon = gtk.Image() microphone_box.add(self.server_microphone_icon) self.microphone_codec_label = label() microphone_box.add(self.microphone_codec_label) tb.new_row("Microphone Forwarding", microphone_box) self.server_microphone_codecs_label = label() tb.new_row("Server Codecs", self.server_microphone_codecs_label) self.client_microphone_codecs_label = label() tb.new_row("Client Codecs", self.client_microphone_codecs_label) # Connection Table: tb = self.table_tab("connect.png", "Connection", self.populate_connection) tb.new_row("Server Endpoint", label(self.connection.target)) if self.client.server_display: tb.new_row("Server Display", label(self.client.server_display)) if "hostname" in scaps: tb.new_row("Server Hostname", label(scaps.get("hostname"))) if self.client.server_platform: tb.new_row("Server Platform", label(self.client.server_platform)) self.server_load_label = label() tb.new_row("Server Load", self.server_load_label, label_tooltip="Average over 1, 5 and 15 minutes") self.session_started_label = label() tb.new_row("Session Started", self.session_started_label) self.session_connected_label = label() tb.new_row("Session Connected", self.session_connected_label) self.input_packets_label = label() tb.new_row("Packets Received", self.input_packets_label) self.input_bytes_label = label() tb.new_row("Bytes Received", self.input_bytes_label) self.output_packets_label = label() tb.new_row("Packets Sent", self.output_packets_label) self.output_bytes_label = label() tb.new_row("Bytes Sent", self.output_bytes_label) self.compression_label = label() tb.new_row("Compression Level", self.compression_label) self.connection_type_label = label() tb.new_row("Connection Type", self.connection_type_label) self.input_encryption_label = label() tb.new_row("Input Encryption", self.input_encryption_label) self.output_encryption_label = label() tb.new_row("Output Encryption", self.output_encryption_label) self.speaker_label = label() self.speaker_details = label(font="monospace 10") tb.new_row("Speaker", self.speaker_label, self.speaker_details) self.microphone_label = label() tb.new_row("Microphone", self.microphone_label) # Details: tb = self.table_tab("browse.png", "Statistics", self.populate_statistics) tb.widget_xalign = 1.0 tb.attach(title_box(""), 0, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0) tb.attach(title_box("Latest"), 1, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0) tb.attach(title_box("Minimum"), 2, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0) tb.attach(title_box("Average"), 3, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0) tb.attach(title_box("90 percentile"), 4, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0) tb.attach(title_box("Maximum"), 5, xoptions=gtk.EXPAND | gtk.FILL, xpadding=0) tb.inc() def maths_labels(): return label(), label(), label(), label(), label() self.server_latency_labels = maths_labels() tb.add_row(label("Server Latency (ms)"), *self.server_latency_labels) self.client_latency_labels = maths_labels() tb.add_row(label("Client Latency (ms)"), *self.client_latency_labels) if self.client.windows_enabled: if self.client.server_info_request: self.batch_labels = maths_labels() tb.add_row(label("Batch Delay (ms)"), *self.batch_labels) self.damage_labels = maths_labels() tb.add_row(label("Damage Latency (ms)"), *self.damage_labels) self.quality_labels = maths_labels() tb.add_row(label("Encoding Quality (pct)"), *self.quality_labels) self.speed_labels = maths_labels() tb.add_row(label("Encoding Speed (pct)"), *self.speed_labels) self.decoding_labels = maths_labels() tb.add_row(label("Decoding Latency (ms)"), *self.decoding_labels) self.regions_per_second_labels = maths_labels() tb.add_row(label("Regions/s"), *self.regions_per_second_labels) self.regions_sizes_labels = maths_labels() tb.add_row(label("Pixels/region"), *self.regions_sizes_labels) self.pixels_per_second_labels = maths_labels() tb.add_row(label("Pixels/s"), *self.pixels_per_second_labels) self.windows_managed_label = label() tb.new_row("Regular Windows", self.windows_managed_label), self.transient_managed_label = label() tb.new_row("Transient Windows", self.transient_managed_label), self.trays_managed_label = label() tb.new_row("Trays Managed", self.trays_managed_label), if self.client.client_supports_opengl: self.opengl_label = label() tb.new_row("OpenGL Windows", self.opengl_label), self.graph_box = gtk.VBox(False, 10) self.add_tab("statistics.png", "Graphs", self.populate_graphs, self.graph_box) bandwidth_label = "Number of bytes measured by the networks sockets" if SHOW_PIXEL_STATS: bandwidth_label += ",\nand number of pixels rendered" self.bandwidth_graph = self.add_graph_button(bandwidth_label, self.save_graphs) self.latency_graph = self.add_graph_button( "The time it takes to send an echo packet and get the reply", self.save_graphs ) self.pixel_in_data = maxdeque(N_SAMPLES + 4) self.net_in_bytecount = maxdeque(N_SAMPLES + 4) self.net_out_bytecount = maxdeque(N_SAMPLES + 4) self.set_border_width(15) self.add(self.tab_box) if not is_gtk3(): self.set_geometry_hints(self.tab_box) def window_deleted(*args): self.is_closed = True self.connect("delete_event", window_deleted) self.show_tab(self.tabs[0][1]) self.set_size_request(-1, 480) self.populate() self.populate_all() gobject.timeout_add(1000, self.populate) gobject.timeout_add(100, self.populate_tab) self.connect("realize", self.populate_graphs) add_close_accel(self, self.destroy)
def __init__(self): self.exit_code = None Gtk.Window.__init__(self) self.set_border_width(20) self.set_title("Start Xpra Session") self.set_position(Gtk.WindowPosition.CENTER) self.set_size_request(640, 300) icon = get_icon_pixbuf("xpra.png") if icon: self.set_icon(icon) self.connect("delete-event", self.quit) add_close_accel(self, self.quit) vbox = Gtk.VBox(False, 0) vbox.set_spacing(0) # choose the session type: hbox = Gtk.HBox(True, 10) def ralx(btn, xalign=1): al = Gtk.Alignment(xalign=xalign, yalign=0.5, xscale=0.0, yscale=0) al.add(btn) hbox.add(al) self.seamless_btn = Gtk.RadioButton.new_with_label( None, "Seamless Session") self.seamless_btn.connect("toggled", self.mode_toggled) ralx(self.seamless_btn) self.desktop_btn = Gtk.RadioButton.new_with_label_from_widget( self.seamless_btn, "Desktop Session") self.desktop_btn.connect("toggled", self.mode_toggled) ralx(self.desktop_btn) self.shadow_btn = Gtk.RadioButton.new_with_label_from_widget( self.seamless_btn, "Shadow Session") self.shadow_btn.connect("toggled", self.mode_toggled) ralx(self.shadow_btn) self.seamless = True vbox.pack_start(hbox, False) options_box = Gtk.VBox(False, 10) vbox.pack_start(options_box, True, False, 20) # For Shadow mode only: self.display_box = Gtk.HBox(False, 20) options_box.pack_start(self.display_box, False, True, 20) self.display_label = Gtk.Label("Display:") self.display_entry = Gtk.Entry() self.display_entry.set_text("") self.display_entry.set_width_chars(10) self.display_entry.set_placeholder_text("optional") self.display_entry.set_max_length(10) self.display_box.pack_start(self.display_label, True) self.display_box.pack_start(self.display_entry, True, False) # Label: self.entry_label = Gtk.Label("Command to run:") self.entry_label.modify_font(Pango.FontDescription("sans 14")) self.entry_al = Gtk.Alignment(xalign=0, yalign=0.5, xscale=0.0, yscale=0) self.entry_al.add(self.entry_label) options_box.pack_start(self.entry_al, False) # input command directly as text (if pyxdg is not installed): self.entry = Gtk.Entry() self.entry.set_max_length(255) self.entry.set_width_chars(32) self.entry.connect('activate', self.run_command) options_box.pack_start(self.entry, False) # or use menus if we have xdg data: self.category_box = Gtk.HBox(False, 20) options_box.pack_start(self.category_box, False) self.category_label = Gtk.Label("Category:") self.category_combo = Gtk.ComboBoxText() self.category_box.add(self.category_label) self.category_box.add(self.category_combo) self.category_combo.connect("changed", self.category_changed) self.categories = {} self.command_box = Gtk.HBox(False, 20) options_box.pack_start(self.command_box, False) self.command_label = Gtk.Label("Command:") self.command_combo = Gtk.ComboBoxText() self.command_box.pack_start(self.command_label) self.command_box.pack_start(self.command_combo) self.command_combo.connect("changed", self.command_changed) self.commands = {} self.xsessions = None self.desktop_entry = None # start options: hbox = Gtk.HBox(False, 20) options_box.pack_start(hbox, False) self.attach_cb = Gtk.CheckButton() self.attach_cb.set_label("attach immediately") self.attach_cb.set_active(True) al = Gtk.Alignment(xalign=1, yalign=0.5, xscale=0.0, yscale=0) al.add(self.attach_cb) hbox.add(al) self.exit_with_children_cb = Gtk.CheckButton() self.exit_with_children_cb.set_label("exit with application") hbox.add(self.exit_with_children_cb) self.exit_with_children_cb.set_active(True) self.exit_with_client_cb = Gtk.CheckButton() self.exit_with_client_cb.set_label("exit with client") hbox.add(self.exit_with_client_cb) self.exit_with_client_cb.set_active(False) #maybe add: #clipboard, opengl, sharing? # Action buttons: hbox = Gtk.HBox(False, 20) vbox.pack_start(hbox, False, True, 20) def btn(label, tooltip, callback, icon_name=None): btn = Gtk.Button(label) btn.set_tooltip_text(tooltip) btn.connect("clicked", callback) icon = get_icon_pixbuf(icon_name) if icon: btn.set_image(scaled_image(icon, 24)) hbox.pack_start(btn) return btn self.cancel_btn = btn("Cancel", "", self.quit, "quit.png") self.run_btn = btn("Start", "Start this command in an xpra session", self.run_command, "forward.png") self.run_btn.set_sensitive(False) vbox.show_all() self.add(vbox)
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()
def create_window(self): self.window = gtk.Window() self.window.connect("destroy", self.destroy) self.window.set_default_size(400, 260) self.window.set_border_width(20) self.window.set_title("Xpra Launcher") self.window.modify_bg(STATE_NORMAL, gdk.Color(red=65535, green=65535, blue=65535)) icon_pixbuf = self.get_icon("xpra.png") if icon_pixbuf: self.window.set_icon(icon_pixbuf) self.window.set_position(WIN_POS_CENTER) vbox = gtk.VBox(False, 0) vbox.set_spacing(15) # Title hbox = gtk.HBox(False, 0) if icon_pixbuf: logo_button = gtk.Button("") settings = logo_button.get_settings() settings.set_property('gtk-button-images', True) logo_button.connect("clicked", about) logo_button.set_tooltip_text("About") image = gtk.Image() image.set_from_pixbuf(icon_pixbuf) logo_button.set_image(image) hbox.pack_start(logo_button, expand=False, fill=False) icon_pixbuf = self.get_icon("bugs.png") self.bug_tool = None if icon_pixbuf: bug_button = gtk.Button("") settings = bug_button.get_settings() settings.set_property('gtk-button-images', True) def bug(*args): if self.bug_tool == None: from xpra.client.gtk_base.bug_report import BugReport self.bug_tool = BugReport() self.bug_tool.init(show_about=False) self.bug_tool.show() bug_button.connect("clicked", bug) bug_button.set_tooltip_text("Bug Report") image = gtk.Image() image.set_from_pixbuf(icon_pixbuf) bug_button.set_image(image) hbox.pack_start(bug_button, expand=False, fill=False) label = gtk.Label("Connect to xpra server") label.modify_font(pango.FontDescription("sans 14")) hbox.pack_start(label, expand=True, fill=True) vbox.pack_start(hbox) # Mode: hbox = gtk.HBox(False, 20) hbox.set_spacing(20) hbox.pack_start(gtk.Label("Mode: ")) self.mode_combo = gtk.combo_box_new_text() for x in self.get_connection_modes(): self.mode_combo.append_text(x.upper()) self.mode_combo.connect("changed", self.mode_changed) hbox.pack_start(self.mode_combo) vbox.pack_start(hbox) # Username@Host:Port hbox = gtk.HBox(False, 0) hbox.set_spacing(5) self.username_entry = gtk.Entry() self.username_entry.set_max_length(128) self.username_entry.set_width_chars(16) self.username_entry.connect("changed", self.validate) self.username_entry.set_tooltip_text("username") self.username_label = gtk.Label("@") self.host_entry = gtk.Entry() self.host_entry.set_max_length(128) self.host_entry.set_width_chars(24) self.host_entry.connect("changed", self.validate) self.host_entry.set_tooltip_text("hostname") self.ssh_port_entry = gtk.Entry() self.ssh_port_entry.set_max_length(5) self.ssh_port_entry.set_width_chars(5) self.ssh_port_entry.connect("changed", self.validate) self.ssh_port_entry.set_tooltip_text("SSH port") self.port_entry = gtk.Entry() self.port_entry.set_max_length(5) self.port_entry.set_width_chars(5) self.port_entry.connect("changed", self.validate) self.port_entry.set_tooltip_text("port/display") hbox.pack_start(self.username_entry) hbox.pack_start(self.username_label) hbox.pack_start(self.host_entry) hbox.pack_start(self.ssh_port_entry) hbox.pack_start(gtk.Label(":")) hbox.pack_start(self.port_entry) vbox.pack_start(hbox) # Password hbox = gtk.HBox(False, 0) hbox.set_spacing(20) self.password_entry = gtk.Entry() self.password_entry.set_max_length(128) self.password_entry.set_width_chars(30) self.password_entry.set_text("") self.password_entry.set_visibility(False) self.password_entry.connect("changed", self.password_ok) self.password_entry.connect("changed", self.validate) self.password_label = gtk.Label("Password: "******"Disable Strict Host Key Check") self.nostrict_host_check.set_active(False) al = gtk.Alignment(xalign=0.5, yalign=0.5, xscale=0.0, yscale=0) al.add(self.nostrict_host_check) hbox.pack_start(al) vbox.pack_start(hbox) # Info Label self.info = gtk.Label() self.info.set_line_wrap(True) self.info.set_size_request(360, -1) self.info.modify_fg(STATE_NORMAL, red) vbox.pack_start(self.info) #hide encoding options by default self.encoding_combo = None self.encoding_options_check = None self.encoding_box = None if not PYTHON3: #not implemented for gtk3, where we can't use set_menu()... hbox = gtk.HBox(False, 0) hbox.set_spacing(20) self.encoding_options_check = gtk.CheckButton( "Advanced Encoding Options") self.encoding_options_check.connect("toggled", self.encoding_options_toggled) self.encoding_options_check.set_active(False) al = gtk.Alignment(xalign=0.5, yalign=0.5, xscale=0.0, yscale=0) al.add(self.encoding_options_check) hbox.pack_start(al) vbox.pack_start(hbox) self.encoding_box = gtk.VBox() vbox.pack_start(self.encoding_box) # Encoding: hbox = gtk.HBox(False, 20) hbox.set_spacing(20) hbox.pack_start(gtk.Label("Encoding: ")) self.encoding_combo = OptionMenu() def get_current_encoding(): return self.config.encoding def set_new_encoding(e): self.config.encoding = e encodings = ["auto"] + [ x for x in PREFERED_ENCODING_ORDER if x in self.client.get_encodings() ] server_encodings = encodings es = make_encodingsmenu(get_current_encoding, set_new_encoding, encodings, server_encodings) self.encoding_combo.set_menu(es) set_history_from_active(self.encoding_combo) hbox.pack_start(self.encoding_combo) self.encoding_box.pack_start(hbox) self.encoding_combo.connect("changed", self.encoding_changed) # Quality hbox = gtk.HBox(False, 20) hbox.set_spacing(20) self.quality_label = gtk.Label("Quality: ") hbox.pack_start(self.quality_label) self.quality_combo = OptionMenu() def set_min_quality(q): self.config.min_quality = q def set_quality(q): self.config.quality = q def get_min_quality(): return self.config.min_quality def get_quality(): return self.config.quality sq = make_min_auto_menu("Quality", MIN_QUALITY_OPTIONS, QUALITY_OPTIONS, get_min_quality, get_quality, set_min_quality, set_quality) self.quality_combo.set_menu(sq) set_history_from_active(self.quality_combo) hbox.pack_start(self.quality_combo) self.encoding_box.pack_start(hbox) # Speed hbox = gtk.HBox(False, 20) hbox.set_spacing(20) self.speed_label = gtk.Label("Speed: ") hbox.pack_start(self.speed_label) self.speed_combo = OptionMenu() def set_min_speed(s): self.config.min_speed = s def set_speed(s): self.config.speed = s def get_min_speed(): return self.config.min_speed def get_speed(): return self.config.speed ss = make_min_auto_menu("Speed", MIN_SPEED_OPTIONS, SPEED_OPTIONS, get_min_speed, get_speed, set_min_speed, set_speed) self.speed_combo.set_menu(ss) set_history_from_active(self.speed_combo) hbox.pack_start(self.speed_combo) self.encoding_box.pack_start(hbox) self.encoding_box.hide() # Buttons: hbox = gtk.HBox(False, 20) vbox.pack_start(hbox) #Save: self.save_btn = gtk.Button("Save") self.save_btn.set_tooltip_text("Save settings to a session file") self.save_btn.connect("clicked", self.save_clicked) hbox.pack_start(self.save_btn) #Load: self.load_btn = gtk.Button("Load") self.load_btn.set_tooltip_text("Load settings from a session file") self.load_btn.connect("clicked", self.load_clicked) hbox.pack_start(self.load_btn) # Connect button: self.button = gtk.Button("Connect") self.button.connect("clicked", self.connect_clicked) connect_icon = self.get_icon("retry.png") if connect_icon: self.button.set_image(scaled_image(connect_icon, 24)) hbox.pack_start(self.button) def accel_close(*args): gtk.main_quit() add_close_accel(self.window, accel_close) vbox.show_all() self.encoding_options_toggled() self.window.vbox = vbox self.window.add(vbox)
def __init__(self, options, title="Xpra Session Browser"): Gtk.Window.__init__(self) self.exit_code = 0 self.set_title(title) self.set_border_width(20) self.set_resizable(True) self.set_default_size(800, 220) self.set_decorated(True) self.set_size_request(800, 220) self.set_position(Gtk.WindowPosition.CENTER) self.set_wmclass("xpra-sessions-gui", "Xpra-Sessions-GUI") add_close_accel(self, self.quit) self.connect("delete_event", self.quit) icon = get_icon_pixbuf("browse.png") if icon: self.set_icon(icon) hb = Gtk.HeaderBar() hb.set_show_close_button(True) hb.props.title = "Xpra" 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) self.clients = {} self.clients_disconnecting = set() self.child_reaper = getChildReaper() self.vbox = Gtk.VBox(False, 20) self.add(self.vbox) title_label = Gtk.Label(title) title_label.modify_font(Pango.FontDescription("sans 14")) title_label.show() self.vbox.add(title_label) self.warning = Gtk.Label(" ") red = color_parse("red") self.warning.modify_fg(Gtk.StateType.NORMAL, red) self.warning.show() self.vbox.add(self.warning) self.password_box = Gtk.HBox(False, 10) self.password_label = Gtk.Label("Password:"******"" #log.info("options=%s (%s)", options, type(options)) self.local_info_cache = {} self.dotxpra = DotXpra(options.socket_dir, options.socket_dirs, username) self.poll_local_sessions() self.populate() GLib.timeout_add(5 * 1000, self.update) self.vbox.show() self.show()
def main(): with program_context("clicks", "Clicks"): w = TestForm() add_close_accel(w.window, Gtk.main_quit) GLib.idle_add(w.show_with_focus) Gtk.main()
def __init__(self, run_callback=None, can_share=False, xdg_menu=None): self.run_callback = run_callback self.xdg_menu = typedict(xdg_menu or {}) self.window = Gtk.Window() self.window.set_border_width(20) self.window.connect("delete-event", self.close) self.window.set_default_size(400, 150) self.window.set_title("Start New Command") icon_pixbuf = self.get_icon("forward.png") if icon_pixbuf: self.window.set_icon(icon_pixbuf) self.window.set_position(Gtk.WindowPosition.CENTER) vbox = Gtk.VBox(False, 0) vbox.set_spacing(0) self.entry = None if xdg_menu: # or use menus if we have xdg data: hbox = Gtk.HBox(False, 20) vbox.add(hbox) hbox.add(Gtk.Label("Category:")) self.category_combo = Gtk.ComboBoxText() hbox.add(self.category_combo) for name in sorted(xdg_menu.keys()): self.category_combo.append_text(name.decode("utf-8")) self.category_combo.set_active(0) self.category_combo.connect("changed", self.category_changed) hbox = Gtk.HBox(False, 20) vbox.add(hbox) self.command_combo = Gtk.ComboBoxText() hbox.pack_start(Gtk.Label("Command:")) hbox.pack_start(self.command_combo) self.command_combo.connect("changed", self.command_changed) #this will populate the command combo: self.category_changed() #always show the command as text so it can be edited: entry_label = Gtk.Label("Command to run:") entry_label.modify_font(Pango.FontDescription("sans 14")) entry_al = Gtk.Alignment(xalign=0, yalign=0.5, xscale=0.0, yscale=0) entry_al.add(entry_label) vbox.add(entry_al) # Actual command: self.entry = Gtk.Entry() self.entry.set_max_length(255) self.entry.set_width_chars(32) self.entry.connect('activate', self.run_command) vbox.add(self.entry) if can_share: self.share = Gtk.CheckButton("Shared", use_underline=False) #Shared commands will also be shown to other clients self.share.set_active(True) vbox.add(self.share) else: self.share = None # Buttons: hbox = Gtk.HBox(False, 20) vbox.pack_start(hbox) def btn(label, tooltip, callback, icon_name=None): btn = Gtk.Button(label) btn.set_tooltip_text(tooltip) btn.connect("clicked", callback) if icon_name: icon = self.get_icon(icon_name) if icon: btn.set_image(scaled_image(icon, 24)) hbox.pack_start(btn) return btn btn("Run", "Run this command", self.run_command, "forward.png") btn("Cancel", "", self.close, "quit.png") def accel_close(*_args): self.close() add_close_accel(self.window, accel_close) vbox.show_all() self.window.vbox = vbox self.window.add(vbox)
def setup_window(self): self.window = gtk.Window() self.window.connect("destroy", self.close) self.window.set_default_size(400, 300) self.window.set_border_width(20) self.window.set_title("Xpra Bug Report") self.window.modify_bg(STATE_NORMAL, gdk.Color(red=65535, green=65535, blue=65535)) icon_pixbuf = self.get_icon("bugs.png") if icon_pixbuf: self.window.set_icon(icon_pixbuf) self.window.set_position(WIN_POS_CENTER) vbox = gtk.VBox(False, 0) vbox.set_spacing(15) # Title hbox = gtk.HBox(False, 0) icon_pixbuf = self.get_icon("xpra.png") if icon_pixbuf and self.show_about: from xpra.gtk_common.about import about logo_button = gtk.Button("") settings = logo_button.get_settings() settings.set_property('gtk-button-images', True) logo_button.connect("clicked", about) logo_button.set_tooltip_text("About") image = gtk.Image() image.set_from_pixbuf(icon_pixbuf) logo_button.set_image(image) hbox.pack_start(logo_button, expand=False, fill=False) label = gtk.Label("Xpra Bug Report Tool") label.modify_font(pango.FontDescription("sans 14")) hbox.pack_start(label, expand=True, fill=True) vbox.pack_start(hbox) #the box containing all the input: ibox = gtk.VBox(False, 0) ibox.set_spacing(3) vbox.pack_start(ibox) # Description al = gtk.Alignment(xalign=0, yalign=0.5, xscale=0.0, yscale=0) al.add(gtk.Label("Please describe the problem:")) ibox.pack_start(al) #self.description = gtk.Entry(max=128) #self.description.set_width_chars(40) self.description = gtk.TextView() self.description.set_accepts_tab(True) self.description.set_justification(JUSTIFY_LEFT) self.description.set_border_width(2) self.description.set_size_request(300, 80) self.description.modify_bg(STATE_NORMAL, gdk.Color(red=32768, green=32768, blue=32768)) ibox.pack_start(self.description, expand=False, fill=False) # Toggles: al = gtk.Alignment(xalign=0, yalign=0.5, xscale=0.0, yscale=0) al.add(gtk.Label("Include:")) ibox.pack_start(al) #generic toggles: from xpra.gtk_common.keymap import get_gtk_keymap from xpra.codecs.loader import codec_versions, load_codecs load_codecs() try: from xpra.sound.wrapper import query_sound def get_sound_info(): return query_sound() except: get_sound_info = None if self.opengl_info: def get_gl_info(): return self.opengl_info else: try: from xpra.client.gl.gl_check import check_support def get_gl_info(): return check_support(force_enable=True) except: get_gl_info = None from xpra.net.net_util import get_info as get_net_info from xpra.platform.paths import get_info as get_path_info from xpra.platform.gui import get_info as get_gui_info from xpra.version_util import get_version_info, get_platform_info, get_host_info def get_sys_info(): from xpra.platform.info import get_user_info from xpra.scripts.config import read_xpra_defaults return { "argv" : sys.argv, "path" : sys.path, "exec_prefix" : sys.exec_prefix, "executable" : sys.executable, "version" : get_version_info(), "platform" : get_platform_info(), "host" : get_host_info(), "paths" : get_path_info(), "gtk" : get_gtk_version_info(), "gui" : get_gui_info(), "display" : get_display_info(), "user" : get_user_info(), "env" : os.environ, "config" : read_xpra_defaults(), } get_screenshot, take_screenshot_fn = None, None #screenshot: may have OS-specific code try: from xpra.platform.gui import take_screenshot take_screenshot_fn = take_screenshot except: log("failed to load platfrom specific screenshot code", exc_info=True) if not take_screenshot_fn: #try with Pillow: try: from PIL import ImageGrab #@UnresolvedImport from xpra.os_util import StringIOClass def pillow_imagegrab_screenshot(): img = ImageGrab.grab() out = StringIOClass() img.save(out, format="PNG") v = out.getvalue() out.close() return (img.width, img.height, "png", img.width*3, v) take_screenshot_fn = pillow_imagegrab_screenshot except Exception as e: log("cannot use Pillow's ImageGrab: %s", e) if not take_screenshot_fn: #default: gtk screen capture try: from xpra.server.shadow.gtk_root_window_model import GTKRootWindowModel rwm = GTKRootWindowModel(gtk.gdk.get_default_root_window()) take_screenshot_fn = rwm.take_screenshot except: log("failed to load gtk screenshot code", exc_info=True) log("take_screenshot_fn=%s", take_screenshot_fn) if take_screenshot_fn: def get_screenshot(): #take_screenshot() returns: w, h, "png", rowstride, data return take_screenshot_fn()[4] self.toggles = ( ("system", "txt", "System", get_sys_info, "Xpra version, platform and host information"), ("network", "txt", "Network", get_net_info, "Compression, packet encoding and encryption"), ("encoding", "txt", "Encodings", codec_versions, "Picture encodings supported"), ("opengl", "txt", "OpenGL", get_gl_info, "OpenGL driver and features"), ("sound", "txt", "Sound", get_sound_info, "Sound codecs and GStreamer version information"), ("keyboard", "txt", "Keyboard Mapping", get_gtk_keymap, "Keyboard layout and key mapping"), ("xpra-info", "txt", "Server Info", self.get_server_info, "Full server information from 'xpra info'"), ("screenshot", "png", "Screenshot", get_screenshot, ""), ) for name, _, title, value_cb, tooltip in self.toggles: cb = gtk.CheckButton(title+[" (not available)", ""][bool(value_cb)]) cb.set_active(self.includes.get(name, True)) cb.set_sensitive(bool(value_cb)) cb.set_tooltip_text(tooltip) ibox.pack_start(cb) setattr(self, name, cb) # Buttons: hbox = gtk.HBox(False, 20) vbox.pack_start(hbox) def btn(label, tooltip, callback, icon_name=None): btn = gtk.Button(label) btn.set_tooltip_text(tooltip) btn.connect("clicked", callback) if icon_name: icon = self.get_icon(icon_name) if icon: btn.set_image(scaled_image(icon, 24)) hbox.pack_start(btn) return btn if not is_gtk3(): #clipboard does not work in gtk3.. btn("Copy to clipboard", "Copy all data to clipboard", self.copy_clicked, "clipboard.png") btn("Save", "Save Bug Report", self.save_clicked, "download.png") btn("Cancel", "", self.close, "quit.png") def accel_close(*args): self.close() add_close_accel(self.window, accel_close) vbox.show_all() self.window.vbox = vbox self.window.add(vbox)
def __init__(self, title="Xpra"): 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(WIN_POS_CENTER) icon = get_pixbuf("xpra") if icon: self.set_icon(icon) add_close_accel(self, self.quit) add_window_accel(self, 'F1', self.show_about) self.connect("delete_event", self.quit) self.vbox = gtk.VBox(False, 10) self.add(self.vbox) #with most window managers, #the window's title bar already shows "Xpra" #title_label = gtk.Label(title) #title_label.modify_font(pango.FontDescription("sans 14")) #self.vbox.add(title_label) self.widgets = [] label_font = pango.FontDescription("sans 16") if has_client: icon = get_pixbuf("browse.png") self.browse_button = imagebutton( "Browse", icon, "Browse and connect to local sessions", clicked_callback=self.browse, icon_size=48, label_font=label_font) self.widgets.append(self.browse_button) icon = get_pixbuf("connect.png") self.connect_button = imagebutton( "Connect", icon, "Connect to a session", clicked_callback=self.show_launcher, icon_size=48, label_font=label_font) self.widgets.append(self.connect_button) if has_server: icon = get_pixbuf("server-connected.png") self.shadow_button = imagebutton( "Shadow", icon, "Start a shadow server", clicked_callback=self.start_shadow, icon_size=48, label_font=label_font) if not has_shadow: set_tooltip_text( self.shadow_button, "This build of Xpra does not support starting sessions") self.shadow_button.set_sensitive(False) self.widgets.append(self.shadow_button) icon = get_pixbuf("windows.png") self.start_button = imagebutton("Start", icon, "Start a session", clicked_callback=self.start, icon_size=48, label_font=label_font) #not all builds and platforms can start sessions: if OSX or WIN32: set_tooltip_text( self.start_button, "Starting sessions is not supported on %s" % sys.platform) self.start_button.set_sensitive(False) elif not has_server: set_tooltip_text( self.start_button, "This build of Xpra does not support starting sessions") self.start_button.set_sensitive(False) self.widgets.append(self.start_button) assert len(self.widgets) % 2 == 0 table = gtk.Table(len(self.widgets) // 2, 2, True) for i, widget in enumerate(self.widgets): table.attach(widget, i % 2, i % 2 + 1, i // 2, i // 2 + 1, xpadding=10, ypadding=10) self.vbox.add(table) self.vbox.show_all() self.set_size_request(640, 100 + 100 * len(self.widgets) // 2) def focus_in(window, event): log("focus_in(%s, %s)", window, event) def focus_out(window, event): log("focus_out(%s, %s)", window, event) self.reset_cursors() self.connect("focus-in-event", focus_in) self.connect("focus-out-event", focus_out)
def __init__(self, title="Xpra"): self.exit_code = 0 self.start_session = None Gtk.Window.__init__(self) hb = Gtk.HeaderBar() hb.set_show_close_button(True) hb.props.title = "Xpra" self.set_titlebar(hb) hb.add(self.button("About", "help-about", about)) try: from xpra.client.gtk_base.toolbox import ToolboxGUI except ImportError: pass else: def show(): w = None def hide(*_args): w.hide() ToolboxGUI.quit = hide w = ToolboxGUI() w.show() hb.add(self.button("Toolbox", "applications-utilities", show)) hb.show_all() self.set_title(title) self.set_border_width(10) self.set_resizable(True) self.set_decorated(True) self.set_position(Gtk.WindowPosition.CENTER) icon = get_pixbuf("xpra") if icon: self.set_icon(icon) add_close_accel(self, self.quit) add_window_accel(self, 'F1', self.show_about) self.connect("delete_event", self.quit) self.set_wmclass("xpra-gui", "Xpra-GUI") self.vbox = Gtk.VBox(False, 10) self.add(self.vbox) #with most window managers, #the window's title bar already shows "Xpra" #title_label = Gtk.Label(title) #title_label.modify_font(pango.FontDescription("sans 14")) #self.vbox.add(title_label) self.widgets = [] label_font = Pango.FontDescription("sans 16") if has_client: icon = get_pixbuf("browse.png") self.browse_button = imagebutton( "Browse", icon, "Browse and connect to local sessions", clicked_callback=self.browse, icon_size=48, label_font=label_font) self.widgets.append(self.browse_button) icon = get_pixbuf("connect.png") self.connect_button = imagebutton( "Connect", icon, "Connect to a session", clicked_callback=self.show_launcher, icon_size=48, label_font=label_font) self.widgets.append(self.connect_button) if has_server: icon = get_pixbuf("server-connected.png") self.shadow_button = imagebutton( "Shadow", icon, "Start a shadow server", clicked_callback=self.start_shadow, icon_size=48, label_font=label_font) if not has_shadow: self.shadow_button.set_tooltip_text( "This build of Xpra does not support starting sessions") self.shadow_button.set_sensitive(False) self.widgets.append(self.shadow_button) icon = get_pixbuf("windows.png") self.start_button = imagebutton("Start", icon, "Start a session", clicked_callback=self.start, icon_size=48, label_font=label_font) #not all builds and platforms can start sessions: if OSX or WIN32: self.start_button.set_tooltip_text( "Starting sessions is not supported on %s" % platform_name(sys.platform)) self.start_button.set_sensitive(False) elif not has_server: self.start_button.set_tooltip_text( "This build of Xpra does not support starting sessions") self.start_button.set_sensitive(False) self.widgets.append(self.start_button) assert len(self.widgets) % 2 == 0 table = Gtk.Table(len(self.widgets) // 2, 2, True) for i, widget in enumerate(self.widgets): table.attach(widget, i % 2, i % 2 + 1, i // 2, i // 2 + 1, xpadding=10, ypadding=10) self.vbox.add(table) self.vbox.show_all() self.set_size_request(640, 100 + 100 * len(self.widgets) // 2) def focus_in(window, event): log("focus_in(%s, %s)", window, event) def focus_out(window, event): log("focus_out(%s, %s)", window, event) self.reset_cursors() self.connect("focus-in-event", focus_in) self.connect("focus-out-event", focus_out)
def setup_window(self): self.window = gtk.Window() window_defaults(self.window) self.window.connect("destroy", self.close) self.window.set_default_size(400, 300) self.window.set_title("Xpra Bug Report") icon_pixbuf = self.get_icon("bugs.png") if icon_pixbuf: self.window.set_icon(icon_pixbuf) self.window.set_position(WIN_POS_CENTER) vbox = gtk.VBox(False, 0) vbox.set_spacing(15) # Title hbox = gtk.HBox(False, 0) icon_pixbuf = self.get_icon("xpra.png") if icon_pixbuf and self.show_about: from xpra.gtk_common.about import about logo_button = gtk.Button("") settings = logo_button.get_settings() settings.set_property('gtk-button-images', True) logo_button.connect("clicked", about) logo_button.set_tooltip_text("About") image = gtk.Image() image.set_from_pixbuf(icon_pixbuf) logo_button.set_image(image) hbox.pack_start(logo_button, expand=False, fill=False) label = gtk.Label("Xpra Bug Report Tool") label.modify_font(pango.FontDescription("sans 14")) hbox.pack_start(label, expand=True, fill=True) vbox.pack_start(hbox) #the box containing all the input: ibox = gtk.VBox(False, 0) ibox.set_spacing(3) vbox.pack_start(ibox) # Description al = gtk.Alignment(xalign=0, yalign=0.5, xscale=0.0, yscale=0) al.add(gtk.Label("Please describe the problem:")) ibox.pack_start(al) #self.description = gtk.Entry(max=128) #self.description.set_width_chars(40) self.description = gtk.TextView() self.description.set_accepts_tab(True) self.description.set_justification(JUSTIFY_LEFT) self.description.set_border_width(2) self.description.set_size_request(300, 80) #self.description.modify_bg(STATE_NORMAL, gdk.Color(red=32768, green=32768, blue=32768)) ibox.pack_start(self.description, expand=False, fill=False) # Toggles: al = gtk.Alignment(xalign=0, yalign=0.5, xscale=0.0, yscale=0) al.add(gtk.Label("Include:")) ibox.pack_start(al) #generic toggles: from xpra.gtk_common.keymap import get_gtk_keymap from xpra.codecs.loader import codec_versions, load_codecs load_codecs() try: from xpra.sound.wrapper import query_sound def get_sound_info(): return query_sound() except: get_sound_info = None def get_gl_info(): if self.opengl_info: return self.opengl_info try: from xpra.client.gl.gtk_base.gtkgl_check import check_support return check_support(force_enable=True) except Exception as e: return {"error": str(e)} from xpra.net.net_util import get_info as get_net_info from xpra.platform.paths import get_info as get_path_info from xpra.platform.gui import get_info as get_gui_info from xpra.version_util import get_version_info, get_platform_info, get_host_info def get_sys_info(): from xpra.platform.info import get_user_info from xpra.scripts.config import read_xpra_defaults return { "argv": sys.argv, "path": sys.path, "exec_prefix": sys.exec_prefix, "executable": sys.executable, "version": get_version_info(), "platform": get_platform_info(), "host": get_host_info(), "paths": get_path_info(), "gtk": get_gtk_version_info(), "gui": get_gui_info(), "display": get_display_info(), "user": get_user_info(), "env": os.environ, "config": read_xpra_defaults(), } get_screenshot, take_screenshot_fn = None, None #screenshot: may have OS-specific code try: from xpra.platform.gui import take_screenshot take_screenshot_fn = take_screenshot except: log("failed to load platfrom specific screenshot code", exc_info=True) if not take_screenshot_fn: #try with Pillow: try: from PIL import ImageGrab #@UnresolvedImport from xpra.os_util import StringIOClass def pillow_imagegrab_screenshot(): img = ImageGrab.grab() out = StringIOClass() img.save(out, format="PNG") v = out.getvalue() out.close() return (img.width, img.height, "png", img.width * 3, v) take_screenshot_fn = pillow_imagegrab_screenshot except Exception as e: log("cannot use Pillow's ImageGrab: %s", e) if not take_screenshot_fn: #default: gtk screen capture try: from xpra.server.shadow.gtk_root_window_model import GTKImageCapture rwm = GTKImageCapture(get_default_root_window()) take_screenshot_fn = rwm.take_screenshot except: log.warn("Warning: failed to load gtk screenshot code", exc_info=True) log("take_screenshot_fn=%s", take_screenshot_fn) if take_screenshot_fn: def get_screenshot(): #take_screenshot() returns: w, h, "png", rowstride, data return take_screenshot_fn()[4] self.toggles = ( ("system", "txt", "System", get_sys_info, "Xpra version, platform and host information"), ("network", "txt", "Network", get_net_info, "Compression, packet encoding and encryption"), ("encoding", "txt", "Encodings", codec_versions, "Picture encodings supported"), ("opengl", "txt", "OpenGL", get_gl_info, "OpenGL driver and features"), ("sound", "txt", "Sound", get_sound_info, "Sound codecs and GStreamer version information"), ("keyboard", "txt", "Keyboard Mapping", get_gtk_keymap, "Keyboard layout and key mapping"), ("xpra-info", "txt", "Server Info", self.get_server_info, "Full server information from 'xpra info'"), ("screenshot", "png", "Screenshot", get_screenshot, ""), ) for name, _, title, value_cb, tooltip in self.toggles: cb = gtk.CheckButton(title + [" (not available)", ""][bool(value_cb)]) cb.set_active(self.includes.get(name, True)) cb.set_sensitive(bool(value_cb)) cb.set_tooltip_text(tooltip) ibox.pack_start(cb) setattr(self, name, cb) # Buttons: hbox = gtk.HBox(False, 20) vbox.pack_start(hbox) def btn(label, tooltip, callback, icon_name=None): btn = gtk.Button(label) btn.set_tooltip_text(tooltip) btn.connect("clicked", callback) if icon_name: icon = self.get_icon(icon_name) if icon: btn.set_image(scaled_image(icon, 24)) hbox.pack_start(btn) return btn if not is_gtk3(): #clipboard does not work in gtk3.. btn("Copy to clipboard", "Copy all data to clipboard", self.copy_clicked, "clipboard.png") btn("Save", "Save Bug Report", self.save_clicked, "download.png") btn("Cancel", "", self.close, "quit.png") def accel_close(*_args): self.close() add_close_accel(self.window, accel_close) vbox.show_all() self.window.vbox = vbox self.window.add(vbox)
def __init__(self, options): self.set_options(options) self.exit_code = None self.options_window = None self.default_config = get_defaults() #log("default_config=%s", self.default_config) #log("options=%s (%s)", options, type(options)) super().__init__() self.set_border_width(20) self.set_title("Start Xpra Session") self.set_position(Gtk.WindowPosition.CENTER) self.set_size_request(640, 300) icon = get_icon_pixbuf("xpra.png") if icon: self.set_icon(icon) self.connect("delete-event", self.quit) add_close_accel(self, self.quit) vbox = Gtk.VBox(False, 0) vbox.set_spacing(10) # choose the session type: hbox = Gtk.HBox(True, 40) def rb(sibling=None, label="", cb=None, tooltip_text=None): btn = Gtk.RadioButton.new_with_label_from_widget(sibling, label) if cb: btn.connect("toggled", cb) if tooltip_text: btn.set_tooltip_text(tooltip_text) sf(btn, "sans 16") hbox.add(btn) return btn self.seamless_btn = rb( None, "Seamless Session", self.session_toggled, "Forward an application window(s) individually, seamlessly") self.desktop_btn = rb( self.seamless_btn, "Desktop Session", self.session_toggled, "Forward a full desktop environment, contained in a window") self.shadow_btn = rb( self.seamless_btn, "Shadow Session", self.session_toggled, "Forward an existing desktop session, shown in a window") vbox.pack_start(hbox, False) vbox.pack_start(Gtk.HSeparator(), True, False) options_box = Gtk.VBox(False, 10) vbox.pack_start(options_box, True, False, 20) # select host: host_box = Gtk.HBox(True, 20) options_box.pack_start(host_box, False) self.host_label = l("Host:") hbox = Gtk.HBox(True, 0) host_box.pack_start(self.host_label, True) host_box.pack_start(hbox, True, True) self.localhost_btn = rb(None, "Local System", self.host_toggled) self.remote_btn = rb(self.localhost_btn, "Remote") self.remote_btn.set_tooltip_text("Start sessions on a remote system") self.address_box = Gtk.HBox(False, 0) options_box.pack_start(xal(self.address_box), True, True) self.mode_combo = sf(Gtk.ComboBoxText()) self.address_box.pack_start(xal(self.mode_combo), False) for mode in ("SSH", "TCP", "SSL", "WS", "WSS"): self.mode_combo.append_text(mode) self.mode_combo.set_active(0) self.mode_combo.connect("changed", self.mode_changed) self.username_entry = sf(Gtk.Entry()) self.username_entry.set_width_chars(12) self.username_entry.set_placeholder_text("Username") self.username_entry.set_max_length(255) self.address_box.pack_start(xal(self.username_entry), False) self.address_box.pack_start(l("@"), False) self.host_entry = sf(Gtk.Entry()) self.host_entry.set_width_chars(24) self.host_entry.set_placeholder_text("Hostname or IP address") self.host_entry.set_max_length(255) self.address_box.pack_start(xal(self.host_entry), False) self.address_box.pack_start(Gtk.Label(":"), False) self.port_entry = sf(Gtk.Entry()) self.port_entry.set_text("22") self.port_entry.set_width_chars(5) self.port_entry.set_placeholder_text("Port") self.port_entry.set_max_length(5) self.address_box.pack_start(xal(self.port_entry, 0), False) self.display_box = Gtk.HBox(True, 20) options_box.pack_start(self.display_box, False, True, 20) self.display_label = l("Display:") self.display_entry = sf(Gtk.Entry()) self.display_entry.connect('changed', self.display_changed) self.display_entry.set_width_chars(10) self.display_entry.set_placeholder_text("optional") self.display_entry.set_max_length(10) self.display_entry.set_tooltip_text( "To use a specific X11 display number") self.display_combo = sf(Gtk.ComboBoxText()) self.display_box.pack_start(self.display_label, True) self.display_box.pack_start(self.display_entry, True, False) self.display_box.pack_start(self.display_combo, True, False) # Label: self.entry_box = Gtk.HBox(True, 20) options_box.pack_start(self.entry_box, False, True, 20) self.entry_label = l("Command:") self.entry = sf(Gtk.Entry()) self.entry.set_max_length(255) self.entry.set_width_chars(32) #self.entry.connect('activate', self.run_command) self.entry.connect('changed', self.entry_changed) self.entry_box.pack_start(self.entry_label, True) self.entry_box.pack_start(self.entry, True, False) # or use menus if we have xdg data: self.category_box = Gtk.HBox(True, 20) options_box.pack_start(self.category_box, False) self.category_label = l("Category:") self.category_combo = sf(Gtk.ComboBoxText()) self.category_box.pack_start(self.category_label, True) self.category_box.pack_start(self.category_combo, True, True) self.category_combo.connect("changed", self.category_changed) self.categories = {} self.command_box = Gtk.HBox(True, 20) options_box.pack_start(self.command_box, False) self.command_label = l("Command:") self.command_combo = sf(Gtk.ComboBoxText()) self.command_box.pack_start(self.command_label, True) self.command_box.pack_start(self.command_combo, True, True) self.command_combo.connect("changed", self.command_changed) self.commands = {} self.xsessions = None self.desktop_entry = None # start options: hbox = Gtk.HBox(False, 20) options_box.pack_start(hbox, False) self.exit_with_children_cb = sf(Gtk.CheckButton()) self.exit_with_children_cb.set_label("exit with application") hbox.add(xal(self.exit_with_children_cb, 0.5)) self.exit_with_children_cb.set_active(True) self.exit_with_client_cb = sf(Gtk.CheckButton()) self.exit_with_client_cb.set_label("exit with client") hbox.add(xal(self.exit_with_client_cb, 0.5)) self.exit_with_client_cb.set_active(False) # session options: hbox = Gtk.HBox(False, 12) hbox.pack_start(l("Options:"), True, False) for label_text, icon_name, tooltip_text, cb in ( ("Features", "features.png", "Session features", self.configure_features), ("Network", "connect.png", "Network options", self.configure_network), ("Display", "display.png", "Display settings", self.configure_display), ("Encodings", "encoding.png", "Picture compression", self.configure_encoding), ("Keyboard", "keyboard.png", "Keyboard layout and options", self.configure_keyboard), ("Audio", "speaker.png", "Audio forwarding options", self.configure_audio), ("Webcam", "webcam.png", "Webcam forwarding options", self.configure_webcam), ("Printing", "printer.png", "Printer forwarding options", self.configure_printing), ): icon = get_icon_pixbuf(icon_name) ib = imagebutton("", icon=icon, tooltip=label_text or tooltip_text, clicked_callback=cb, icon_size=32, label_font=Pango.FontDescription("sans 14")) hbox.pack_start(ib, True, False) options_box.pack_start(hbox, True, False) # Action buttons: hbox = Gtk.HBox(False, 20) vbox.pack_start(hbox, False, True, 20) def btn(label, tooltip, callback, default=False): ib = imagebutton(label, tooltip=tooltip, clicked_callback=callback, icon_size=32, default=default, label_font=Pango.FontDescription("sans 16")) hbox.pack_start(ib) return ib self.cancel_btn = btn("Cancel", "", self.quit) self.run_btn = btn("Start", "Start the xpra session", self.run_command) self.runattach_btn = btn("Start & Attach", "Start the xpra session and attach to it", self.runattach_command, True) self.runattach_btn.set_sensitive(False) vbox.show_all() self.display_combo.hide() self.add(vbox) #load encodings in the background: self.load_codecs_thread = start_thread(self.load_codecs, "load-codecs", daemon=True) #poll the list of X11 displays in the background: self.display_list = () if not OSX: self.load_displays_thread = start_thread(self.load_displays, "load-displays", daemon=True)
def create_window(self): self.window = gtk.Window() self.window.connect("destroy", self.destroy) self.window.set_default_size(400, 300) self.window.set_border_width(20) self.window.set_title("Xpra Launcher") self.window.modify_bg(STATE_NORMAL, gdk.Color(red=65535, green=65535, blue=65535)) icon_pixbuf = self.get_icon("xpra.png") if icon_pixbuf: self.window.set_icon(icon_pixbuf) self.window.set_position(WIN_POS_CENTER) vbox = gtk.VBox(False, 0) vbox.set_spacing(15) # Title hbox = gtk.HBox(False, 0) if icon_pixbuf: logo_button = gtk.Button("") settings = logo_button.get_settings() settings.set_property('gtk-button-images', True) logo_button.connect("clicked", about) logo_button.set_tooltip_text("About") image = gtk.Image() image.set_from_pixbuf(icon_pixbuf) logo_button.set_image(image) hbox.pack_start(logo_button, expand=False, fill=False) icon_pixbuf = self.get_icon("bugs.png") self.bug_tool = None if icon_pixbuf: bug_button = gtk.Button("") settings = bug_button.get_settings() settings.set_property('gtk-button-images', True) def bug(*args): if self.bug_tool==None: from xpra.client.gtk_base.bug_report import BugReport self.bug_tool = BugReport() self.bug_tool.init(show_about=False) self.bug_tool.show() bug_button.connect("clicked", bug) bug_button.set_tooltip_text("Bug Report") image = gtk.Image() image.set_from_pixbuf(icon_pixbuf) bug_button.set_image(image) hbox.pack_start(bug_button, expand=False, fill=False) label = gtk.Label("Connect to xpra server") label.modify_font(pango.FontDescription("sans 14")) hbox.pack_start(label, expand=True, fill=True) vbox.pack_start(hbox) # Mode: hbox = gtk.HBox(False, 20) hbox.set_spacing(20) hbox.pack_start(gtk.Label("Mode: ")) self.mode_combo = gtk.combo_box_new_text() #self.mode_combo.get_model().clear() self.mode_combo.append_text("TCP") if "AES" in ENCRYPTION_CIPHERS: self.mode_combo.append_text("TCP + AES") self.mode_combo.append_text("SSH") self.mode_combo.connect("changed", self.mode_changed) hbox.pack_start(self.mode_combo) vbox.pack_start(hbox) self.encoding_combo = None if not PYTHON3: #not implemented for gtk3, where we can't use set_menu()... # Encoding: hbox = gtk.HBox(False, 20) hbox.set_spacing(20) hbox.pack_start(gtk.Label("Encoding: ")) self.encoding_combo = OptionMenu() def get_current_encoding(): return self.config.encoding def set_new_encoding(e): self.config.encoding = e encodings = [x for x in PREFERED_ENCODING_ORDER if x in self.client.get_encodings()] server_encodings = encodings es = make_encodingsmenu(get_current_encoding, set_new_encoding, encodings, server_encodings) self.encoding_combo.set_menu(es) set_history_from_active(self.encoding_combo) hbox.pack_start(self.encoding_combo) vbox.pack_start(hbox) self.encoding_combo.connect("changed", self.encoding_changed) # Quality hbox = gtk.HBox(False, 20) hbox.set_spacing(20) self.quality_label = gtk.Label("Quality: ") hbox.pack_start(self.quality_label) self.quality_combo = OptionMenu() def set_min_quality(q): self.config.min_quality = q def set_quality(q): self.config.quality = q def get_min_quality(): return self.config.min_quality def get_quality(): return self.config.quality sq = make_min_auto_menu("Quality", MIN_QUALITY_OPTIONS, QUALITY_OPTIONS, get_min_quality, get_quality, set_min_quality, set_quality) self.quality_combo.set_menu(sq) set_history_from_active(self.quality_combo) hbox.pack_start(self.quality_combo) vbox.pack_start(hbox) # Speed hbox = gtk.HBox(False, 20) hbox.set_spacing(20) self.speed_label = gtk.Label("Speed: ") hbox.pack_start(self.speed_label) self.speed_combo = OptionMenu() def set_min_speed(s): self.config.min_speed = s def set_speed(s): self.config.speed = s def get_min_speed(): return self.config.min_speed def get_speed(): return self.config.speed ss = make_min_auto_menu("Speed", MIN_SPEED_OPTIONS, SPEED_OPTIONS, get_min_speed, get_speed, set_min_speed, set_speed) self.speed_combo.set_menu(ss) set_history_from_active(self.speed_combo) hbox.pack_start(self.speed_combo) vbox.pack_start(hbox) # Username@Host:Port hbox = gtk.HBox(False, 0) hbox.set_spacing(5) self.username_entry = gtk.Entry() self.username_entry.set_max_length(128) self.username_entry.set_width_chars(16) self.username_entry.connect("changed", self.validate) self.username_entry.set_tooltip_text("SSH username") self.username_label = gtk.Label("@") self.host_entry = gtk.Entry() self.host_entry.set_max_length(128) self.host_entry.set_width_chars(24) self.host_entry.connect("changed", self.validate) self.host_entry.set_tooltip_text("hostname") self.ssh_port_entry = gtk.Entry() self.ssh_port_entry.set_max_length(5) self.ssh_port_entry.set_width_chars(5) self.ssh_port_entry.connect("changed", self.validate) self.ssh_port_entry.set_tooltip_text("SSH port") self.port_entry = gtk.Entry() self.port_entry.set_max_length(5) self.port_entry.set_width_chars(5) self.port_entry.connect("changed", self.validate) self.port_entry.set_tooltip_text("port/display") hbox.pack_start(self.username_entry) hbox.pack_start(self.username_label) hbox.pack_start(self.host_entry) hbox.pack_start(self.ssh_port_entry) hbox.pack_start(gtk.Label(":")) hbox.pack_start(self.port_entry) vbox.pack_start(hbox) # Password hbox = gtk.HBox(False, 0) hbox.set_spacing(20) self.password_entry = gtk.Entry() self.password_entry.set_max_length(128) self.password_entry.set_width_chars(30) self.password_entry.set_text("") self.password_entry.set_visibility(False) self.password_entry.connect("changed", self.password_ok) self.password_entry.connect("changed", self.validate) self.password_label = gtk.Label("Password: "******"Save") self.save_btn.set_tooltip_text("Save settings to a session file") self.save_btn.connect("clicked", self.save_clicked) hbox.pack_start(self.save_btn) #Load: self.load_btn = gtk.Button("Load") self.load_btn.set_tooltip_text("Load settings from a session file") self.load_btn.connect("clicked", self.load_clicked) hbox.pack_start(self.load_btn) # Connect button: self.button = gtk.Button("Connect") self.button.connect("clicked", self.connect_clicked) connect_icon = self.get_icon("retry.png") if connect_icon: self.button.set_image(scaled_image(connect_icon, 24)) hbox.pack_start(self.button) def accel_close(*args): gtk.main_quit() add_close_accel(self.window, accel_close) vbox.show_all() self.window.vbox = vbox self.window.add(vbox)
def __init__(self, stack, nid, title, message, actions, image, timeout=5, show_timeout=False): log("Popup%s", (stack, nid, title, message, actions, image, timeout, show_timeout)) self.stack = stack self.nid = nid Gtk.Window.__init__(self) self.set_accept_focus(False) self.set_focus_on_map(False) self.set_size_request(stack.size_x, -1) self.set_decorated(False) self.set_deletable(False) self.set_property("skip-pager-hint", True) self.set_property("skip-taskbar-hint", True) self.connect("enter-notify-event", self.on_hover, True) self.connect("leave-notify-event", self.on_hover, False) self.set_opacity(0.2) self.set_keep_above(True) self.destroy_cb = stack.destroy_popup_cb self.popup_closed = stack.popup_closed self.action_cb = stack.popup_action main_box = Gtk.VBox() header_box = Gtk.HBox() self.header = Gtk.Label() self.header.set_markup("<b>%s</b>" % title) self.header.set_padding(3, 3) self.header.set_alignment(0, 0) header_box.pack_start(self.header, True, True, 5) icon = get_pixbuf("close.png") if icon: close_button = Gtk.Image() close_button.set_from_pixbuf(icon) close_button.set_padding(3, 3) close_window = Gtk.EventBox() close_window.set_visible_window(False) close_window.connect("button-press-event", self.user_closed) close_window.add(close_button) close_window.set_size_request(icon.get_width(), icon.get_height()) header_box.pack_end(close_window, False, False, 0) main_box.pack_start(header_box) body_box = Gtk.HBox() if image is not None: self.image = Gtk.Image() self.image.set_size_request(70, 70) self.image.set_alignment(0, 0) self.image.set_from_pixbuf(image) body_box.pack_start(self.image, False, False, 5) self.message = Gtk.Label() self.message.set_max_width_chars(80) self.message.set_size_request(stack.size_x - 90, -1) self.message.set_line_wrap(True) self.message.set_alignment(0, 0) self.message.set_padding(5, 10) self.message.set_text(message) self.counter = Gtk.Label() self.counter.set_alignment(1, 1) self.counter.set_padding(3, 3) self.timeout = timeout body_box.pack_start(self.message, True, False, 5) body_box.pack_end(self.counter, False, False, 5) main_box.pack_start(body_box, False, False, 5) if len(actions) >= 2: buttons_box = Gtk.HBox(True) while len(actions) >= 2: action_id, action_text = actions[:2] actions = actions[2:] button = self.action_button(action_id, action_text) buttons_box.add(button) alignment = Gtk.Alignment(xalign=1.0, yalign=0.5, xscale=0.0, yscale=0.0) alignment.add(buttons_box) main_box.pack_start(alignment) self.add(main_box) if stack.bg_color is not None: self.modify_bg(Gtk.StateType.NORMAL, stack.bg_color) if stack.fg_color is not None: self.message.modify_fg(Gtk.StateType.NORMAL, stack.fg_color) self.header.modify_fg(Gtk.StateType.NORMAL, stack.fg_color) self.counter.modify_fg(Gtk.StateType.NORMAL, stack.fg_color) self.show_timeout = show_timeout self.hover = False self.show_all() self.w = self.get_preferred_width()[0] self.h = self.get_preferred_height()[0] self.move(self.get_x(self.w), self.get_y(self.h)) self.wait_timer = None self.fade_out_timer = None self.fade_in_timer = GLib.timeout_add(100, self.fade_in) #ensure we dont show it in the taskbar: self.realize() self.get_window().set_skip_taskbar_hint(True) self.get_window().set_skip_pager_hint(True) add_close_accel(self, self.user_closed)
def __init__(self, client, session_name, window_icon_pixbuf, conn, get_pixbuf): gtk.Window.__init__(self) self.client = client self.session_name = session_name self.connection = conn self.last_populate_time = 0 self.last_populate_statistics = 0 self.is_closed = False self.get_pixbuf = get_pixbuf if not self.session_name or self.session_name=="Xpra": title = "Session Info" else: title = "%s: Session Info" % self.session_name self.set_title(title) self.set_destroy_with_parent(True) self.set_resizable(True) self.set_decorated(True) if window_icon_pixbuf: self.set_icon(window_icon_pixbuf) self.set_position(WIN_POS_CENTER) #tables on the left in a vbox with buttons at the top: self.tab_box = gtk.VBox(False, 0) self.tab_button_box = gtk.HBox(True, 0) self.tabs = [] #pairs of button, table self.populate_cb = None self.tab_box.pack_start(self.tab_button_box, expand=False, fill=True, padding=0) #Package Table: tb, _ = self.table_tab("package.png", "Software", self.populate_package) #title row: tb.attach(title_box(""), 0, xoptions=EXPAND|FILL, xpadding=0) tb.attach(title_box("Client"), 1, xoptions=EXPAND|FILL, xpadding=0) tb.attach(title_box("Server"), 2, xoptions=EXPAND|FILL, xpadding=0) tb.inc() def make_os_str(*args): s = os_info(*args) return "\n".join(s) distro = "" if hasattr(python_platform, "linux_distribution"): distro = python_platform.linux_distribution() LOCAL_PLATFORM_NAME = make_os_str(sys.platform, python_platform.release(), python_platform.platform(), distro) SERVER_PLATFORM_NAME = make_os_str(self.client._remote_platform, self.client._remote_platform_release, self.client._remote_platform_platform, self.client._remote_platform_linux_distribution) tb.new_row("Operating System", label(LOCAL_PLATFORM_NAME), label(SERVER_PLATFORM_NAME)) scaps = self.client.server_capabilities from xpra.__init__ import __version__ tb.new_row("Xpra", label(__version__), label(self.client._remote_version or "unknown")) cl_rev, cl_ch, cl_date = "unknown", "", "" try: from xpra.build_info import BUILD_DATE as cl_date, BUILD_TIME as cl_time from xpra.src_info import REVISION as cl_rev, LOCAL_MODIFICATIONS as cl_ch #@UnresolvedImport except: pass def make_version_str(version): if version and type(version) in (tuple, list): version = ".".join([str(x) for x in version]) return version or "unknown" def server_info(*prop_names): for x in prop_names: v = scaps.capsget(x) if v is not None: return v if self.client.server_last_info: v = self.client.server_last_info.get(x) if v is not None: return v return None def server_version_info(*prop_names): return make_version_str(server_info(*prop_names)) def make_revision_str(rev, changes): if not changes: return rev return "%s (%s changes)" % (rev, changes) def make_datetime(date, time): if not time: return date return "%s %s" % (date, time) tb.new_row("Revision", label(make_revision_str(cl_rev, cl_ch)), label(make_revision_str(self.client._remote_revision, server_version_info("build.local_modifications", "local_modifications")))) tb.new_row("Build date", label(make_datetime(cl_date, cl_time)), label(make_datetime(server_info("build_date", "build.date"), server_info("build.time")))) gtk_version_info = get_gtk_version_info() def client_vinfo(prop, fallback="unknown"): k = "%s.version" % prop return label(make_version_str(gtk_version_info.get(k, fallback))) def server_vinfo(prop): k = "%s.version" % prop fk = "%s_version" % prop return label(server_version_info(k, fk)) tb.new_row("Glib", client_vinfo("glib"), server_vinfo("glib")) tb.new_row("PyGlib", client_vinfo("pyglib"), server_vinfo("pyglib")) tb.new_row("Gobject", client_vinfo("gobject"), server_vinfo("gobject")) tb.new_row("PyGTK", client_vinfo("pygtk", ""), server_vinfo("pygtk")) tb.new_row("GTK", client_vinfo("gtk"), server_vinfo("gtk")) tb.new_row("GDK", client_vinfo("gdk"), server_vinfo("gdk")) tb.new_row("Cairo", client_vinfo("cairo"), server_vinfo("cairo")) tb.new_row("Pango", client_vinfo("pango"), server_vinfo("pango")) tb.new_row("Python", label(python_platform.python_version()), label(server_version_info("server.python.version", "python_version", "python.version"))) cl_gst_v, cl_pygst_v = "", "" try: from xpra.sound.gstreamer_util import gst_version as cl_gst_v, pygst_version as cl_pygst_v except Exception as e: log("cannot load gstreamer: %s", e) tb.new_row("GStreamer", label(make_version_str(cl_gst_v)), label(server_version_info("sound.gst.version", "gst_version"))) tb.new_row("pygst", label(make_version_str(cl_pygst_v)), label(server_version_info("sound.pygst.version", "pygst_version"))) tb.new_row("OpenGL", label(make_version_str(self.client.opengl_props.get("opengl", "n/a"))), label("n/a")) tb.new_row("OpenGL Vendor", label(make_version_str(self.client.opengl_props.get("vendor", ""))), label("n/a")) tb.new_row("PyOpenGL", label(make_version_str(self.client.opengl_props.get("pyopengl", "n/a"))), label("n/a")) # Features Table: vbox = self.vbox_tab("features.png", "Features", self.populate_features) #add top table: tb = TableBuilder(rows=1, columns=2) table = tb.get_table() al = gtk.Alignment(xalign=0.5, yalign=0.5, xscale=0.0, yscale=1.0) al.add(table) vbox.pack_start(al, expand=True, fill=False, padding=10) #top table contents: randr_box = gtk.HBox(False, 20) self.server_randr_label = label() self.server_randr_icon = gtk.Image() randr_box.add(self.server_randr_icon) randr_box.add(self.server_randr_label) tb.new_row("RandR Support", randr_box) opengl_box = gtk.HBox(False, 20) self.client_opengl_label = label() self.client_opengl_label.set_line_wrap(True) self.client_opengl_icon = gtk.Image() opengl_box.add(self.client_opengl_icon) opengl_box.add(self.client_opengl_label) tb.new_row("Client OpenGL", opengl_box) self.opengl_buffering = label() tb.new_row("OpenGL Buffering", self.opengl_buffering) self.server_mmap_icon = gtk.Image() tb.new_row("Memory Mapped Transfers", self.server_mmap_icon) self.server_clipboard_icon = gtk.Image() tb.new_row("Clipboard", self.server_clipboard_icon) self.server_notifications_icon = gtk.Image() tb.new_row("Notification Forwarding", self.server_notifications_icon) self.server_bell_icon = gtk.Image() tb.new_row("Bell Forwarding", self.server_bell_icon) self.server_cursors_icon = gtk.Image() tb.new_row("Cursor Forwarding", self.server_cursors_icon) speaker_box = gtk.HBox(False, 20) self.server_speaker_icon = gtk.Image() speaker_box.add(self.server_speaker_icon) self.speaker_codec_label = label() speaker_box.add(self.speaker_codec_label) tb.new_row("Speaker Forwarding", speaker_box) microphone_box = gtk.HBox(False, 20) self.server_microphone_icon = gtk.Image() microphone_box.add(self.server_microphone_icon) self.microphone_codec_label = label() microphone_box.add(self.microphone_codec_label) tb.new_row("Microphone Forwarding", microphone_box) #add bottom table: tb = TableBuilder(rows=1, columns=3) table = tb.get_table() vbox.pack_start(table, expand=True, fill=True, padding=20) #bottom table headings: tb.attach(title_box(""), 0, xoptions=EXPAND|FILL, xpadding=0) tb.attach(title_box("Client"), 1, xoptions=EXPAND|FILL, xpadding=0) tb.attach(title_box("Server"), 2, xoptions=EXPAND|FILL, xpadding=0) tb.inc() #bottom table contents: self.client_encodings_label = label() self.client_encodings_label.set_line_wrap(True) self.client_encodings_label.set_size_request(250, -1) self.server_encodings_label = label() self.server_encodings_label.set_line_wrap(True) self.server_encodings_label.set_size_request(250, -1) tb.new_row("Encodings", self.client_encodings_label, self.server_encodings_label) self.client_speaker_codecs_label = label() self.server_speaker_codecs_label = label() tb.new_row("Speaker Codecs", self.client_speaker_codecs_label, self.server_speaker_codecs_label) self.client_microphone_codecs_label = label() self.server_microphone_codecs_label = label() tb.new_row("Microphone Codecs", self.client_microphone_codecs_label, self.server_microphone_codecs_label) self.client_packet_encoders_label = label() self.server_packet_encoders_label = label() tb.new_row("Packet Encoders", self.client_packet_encoders_label, self.server_packet_encoders_label) self.client_packet_compressors_label = label() self.server_packet_compressors_label = label() tb.new_row("Packet Compressors", self.client_packet_compressors_label, self.server_packet_compressors_label) # Connection Table: tb, _ = self.table_tab("connect.png", "Connection", self.populate_connection) tb.new_row("Server Endpoint", label(self.connection.target)) if self.client.server_display: tb.new_row("Server Display", label(prettify_plug_name(self.client.server_display))) hostname = scaps.strget("hostname") if hostname: tb.new_row("Server Hostname", label(hostname)) if self.client.server_platform: tb.new_row("Server Platform", label(self.client.server_platform)) self.server_load_label = label() tb.new_row("Server Load", self.server_load_label, label_tooltip="Average over 1, 5 and 15 minutes") self.session_started_label = label() tb.new_row("Session Started", self.session_started_label) self.session_connected_label = label() tb.new_row("Session Connected", self.session_connected_label) self.input_packets_label = label() tb.new_row("Packets Received", self.input_packets_label) self.input_bytes_label = label() tb.new_row("Bytes Received", self.input_bytes_label) self.output_packets_label = label() tb.new_row("Packets Sent", self.output_packets_label) self.output_bytes_label = label() tb.new_row("Bytes Sent", self.output_bytes_label) self.compression_label = label() tb.new_row("Encoding + Compression", self.compression_label) self.connection_type_label = label() tb.new_row("Connection Type", self.connection_type_label) self.input_encryption_label = label() tb.new_row("Input Encryption", self.input_encryption_label) self.output_encryption_label = label() tb.new_row("Output Encryption", self.output_encryption_label) self.speaker_label = label() self.speaker_details = label(font="monospace 10") tb.new_row("Speaker", self.speaker_label, self.speaker_details) self.microphone_label = label() tb.new_row("Microphone", self.microphone_label) # Details: tb, stats_box = self.table_tab("browse.png", "Statistics", self.populate_statistics) tb.widget_xalign = 1.0 tb.attach(title_box(""), 0, xoptions=EXPAND|FILL, xpadding=0) tb.attach(title_box("Latest"), 1, xoptions=EXPAND|FILL, xpadding=0) tb.attach(title_box("Minimum"), 2, xoptions=EXPAND|FILL, xpadding=0) tb.attach(title_box("Average"), 3, xoptions=EXPAND|FILL, xpadding=0) tb.attach(title_box("90 percentile"), 4, xoptions=EXPAND|FILL, xpadding=0) tb.attach(title_box("Maximum"), 5, xoptions=EXPAND|FILL, xpadding=0) tb.inc() def maths_labels(): return label(), label(), label(), label(), label() self.server_latency_labels = maths_labels() tb.add_row(label("Server Latency (ms)", "The time it takes for the server to respond to pings"), *self.server_latency_labels) self.client_latency_labels = maths_labels() tb.add_row(label("Client Latency (ms)", "The time it takes for the client to respond to pings, as measured by the server"), *self.client_latency_labels) if self.client.windows_enabled: if self.client.server_info_request: self.batch_labels = maths_labels() tb.add_row(label("Batch Delay (ms)", "How long the server waits for new screen updates to accumulate before processing them"), *self.batch_labels) self.damage_labels = maths_labels() tb.add_row(label("Damage Latency (ms)", "The time it takes to compress a frame and pass it to the OS network layer"), *self.damage_labels) self.quality_labels = maths_labels() tb.add_row(label("Encoding Quality (pct)"), *self.quality_labels) self.speed_labels = maths_labels() tb.add_row(label("Encoding Speed (pct)"), *self.speed_labels) self.decoding_labels = maths_labels() tb.add_row(label("Decoding Latency (ms)", "How long it takes the client to decode a screen update"), *self.decoding_labels) self.regions_per_second_labels = maths_labels() tb.add_row(label("Regions/s", "The number of screen updates per second (includes both partial and full screen updates)"), *self.regions_per_second_labels) self.regions_sizes_labels = maths_labels() tb.add_row(label("Pixels/region", "The number of pixels per screen update"), *self.regions_sizes_labels) self.pixels_per_second_labels = maths_labels() tb.add_row(label("Pixels/s", "The number of pixels processed per second"), *self.pixels_per_second_labels) #Window count stats: wtb = TableBuilder() stats_box.add(wtb.get_table()) #title row: wtb.attach(title_box(""), 0, xoptions=EXPAND|FILL, xpadding=0) wtb.attach(title_box("Regular"), 1, xoptions=EXPAND|FILL, xpadding=0) wtb.attach(title_box("Transient"), 2, xoptions=EXPAND|FILL, xpadding=0) wtb.attach(title_box("Trays"), 3, xoptions=EXPAND|FILL, xpadding=0) if self.client.client_supports_opengl: wtb.attach(title_box("OpenGL"), 4, xoptions=EXPAND|FILL, xpadding=0) wtb.inc() wtb.attach(label("Windows:"), 0, xoptions=EXPAND|FILL, xpadding=0) self.windows_managed_label = label() wtb.attach(self.windows_managed_label, 1) self.transient_managed_label = label() wtb.attach(self.transient_managed_label, 2) self.trays_managed_label = label() wtb.attach(self.trays_managed_label, 3) if self.client.client_supports_opengl: self.opengl_label = label() wtb.attach(self.opengl_label, 4) #add encoder info: etb = TableBuilder() stats_box.add(etb.get_table()) self.encoder_info_box = gtk.HBox(spacing=4) etb.new_row("Window Encoders", self.encoder_info_box) if not is_gtk3(): #needs porting to cairo... self.graph_box = gtk.VBox(False, 10) self.add_tab("statistics.png", "Graphs", self.populate_graphs, self.graph_box) bandwidth_label = "Bandwidth used" if SHOW_PIXEL_STATS: bandwidth_label += ",\nand number of pixels rendered" self.bandwidth_graph = self.add_graph_button(bandwidth_label, self.save_graphs) self.connect("realize", self.populate_graphs) self.latency_graph = self.add_graph_button(None, self.save_graphs) self.pixel_in_data = deque(maxlen=N_SAMPLES+4) self.net_in_bytecount = deque(maxlen=N_SAMPLES+4) self.net_out_bytecount = deque(maxlen=N_SAMPLES+4) self.sound_in_bytecount = deque(maxlen=N_SAMPLES+4) self.sound_out_bytecount = deque(maxlen=N_SAMPLES+4) self.set_border_width(15) self.add(self.tab_box) if not is_gtk3(): self.set_geometry_hints(self.tab_box) def window_deleted(*args): self.is_closed = True self.connect('delete_event', window_deleted) self.show_tab(self.tabs[0][2]) self.set_size_request(-1, 480) self.init_counters() self.populate() self.populate_all() gobject.timeout_add(1000, self.populate) gobject.timeout_add(100, self.populate_tab) add_close_accel(self, self.destroy)
def __init__(self, client, window): Gtk.Window.__init__(self) add_close_accel(self, self.destroy) self._client = client self._window = window self.is_closed = False self.set_title("Window Information for %s" % window.get_title()) self.set_destroy_with_parent(True) self.set_resizable(True) self.set_decorated(True) self.set_transient_for(window) self.set_icon(client.get_pixbuf("information.png")) self.set_position(Gtk.WindowPosition.CENTER_ON_PARENT) def window_deleted(*_args): self.is_closed = True self.connect('delete_event', window_deleted) tb = TableBuilder(1, 2) self.wid_label = slabel() tb.new_row("Window ID", self.wid_label) self.title_label = slabel() self.title_label.set_line_wrap(True) self.title_label.set_size_request(320, -1) #self.title_label.set_justify(Gtk.Justification.LEFT) self.title_label.set_alignment(0, 0.5) tb.new_row("Title", self.title_label) self.or_image = Gtk.Image() tb.new_row("Override-Redirect", self.or_image) self.state_label = slabel() tb.new_row("State", self.state_label) self.attributes_label = slabel() tb.new_row("Attributes", self.attributes_label) self.focus_image = Gtk.Image() tb.new_row("Focus", self.focus_image) self.button_state_label = slabel() tb.new_row("Button State", self.button_state_label) #self.group_leader_label = slabel() #tb.new_row("Group Leader", self.group_leader_label) tb.new_row("") self.gravity_label = slabel() tb.new_row("Gravity", self.gravity_label) self.content_type_label = slabel() tb.new_row("Content Type", self.content_type_label) tb.new_row("", slabel()) self.pixel_depth_label = slabel() tb.new_row("Pixel Depth", self.pixel_depth_label) self.alpha_image = Gtk.Image() tb.new_row("Alpha Channel", self.alpha_image) self.opengl_image = Gtk.Image() tb.new_row("OpenGL", self.opengl_image) tb.new_row("") self.geometry_label = slabel() tb.new_row("Geometry", self.geometry_label) self.outer_geometry_label = slabel() tb.new_row("Outer Geometry", self.outer_geometry_label) self.inner_geometry_label = slabel() tb.new_row("Inner Geometry", self.inner_geometry_label) self.offsets_label = slabel() tb.new_row("Offsets", self.offsets_label) self.frame_extents_label = slabel() tb.new_row("Frame Extents", self.frame_extents_label) self.max_size_label = slabel() tb.new_row("Maximum Size", self.max_size_label) self.size_constraints_label = slabel() tb.new_row("Size Constraints", self.size_constraints_label) tb.new_row("") #backing: self.backing_properties = slabel() tb.new_row("Backing Properties", self.backing_properties) tb.new_row("") btn = Gtk.Button(label="Copy to clipboard") btn.connect("clicked", self.copy_to_clipboard) tb.new_row("", btn) vbox = Gtk.VBox() vbox.pack_start(tb.get_table(), True, True, 20) self.add(vbox)