diff --git a/src/etc/xpra/conf.d/40_client.conf.in b/src/etc/xpra/conf.d/40_client.conf.in index 7279e24e29..a4a43f86c2 100644 --- a/src/etc/xpra/conf.d/40_client.conf.in +++ b/src/etc/xpra/conf.d/40_client.conf.in @@ -17,6 +17,10 @@ challenge-handlers=all # Client window title: title = @title@ on @hostname@ +# Use a header bar with controls: +#headerbar = no +headerbar = %(headerbar)s + # Icon used by the system tray: #tray-icon = /path/to/icon.png diff --git a/src/setup.py b/src/setup.py index 88bffa7ce5..351b7c21d4 100755 --- a/src/setup.py +++ b/src/setup.py @@ -852,6 +852,7 @@ def pretty_cmd(cmd): 'dbus_control' : bstr(dbus_ENABLED), 'mmap' : bstr(True), 'opengl' : "probe", + 'headerbar' : ["yes", "no"][OSX], } def convert_templates(subdirs): dirname = os.path.join(*(["etc", "xpra"] + subdirs)) diff --git a/src/xpra/client/client_window_base.py b/src/xpra/client/client_window_base.py index 741f6c583d..30b7752180 100644 --- a/src/xpra/client/client_window_base.py +++ b/src/xpra/client/client_window_base.py @@ -41,12 +41,14 @@ class ClientWindowBase(ClientWidgetBase): def __init__(self, client, group_leader, watcher_pid, wid, wx, wy, ww, wh, bw, bh, metadata, override_redirect, client_properties, - border, max_window_size, default_cursor_data, pixel_depth): + border, max_window_size, default_cursor_data, pixel_depth, + headerbar="no"): log("%s%s", type(self), (client, group_leader, watcher_pid, wid, wx, wy, ww, wh, bw, bh, metadata, override_redirect, client_properties, - border, max_window_size, default_cursor_data, pixel_depth)) + border, max_window_size, default_cursor_data, pixel_depth, + headerbar)) super().__init__(client, watcher_pid, wid, metadata.boolget("has-alpha")) self._override_redirect = override_redirect self.group_leader = group_leader @@ -76,6 +78,7 @@ def __init__(self, client, group_leader, watcher_pid, wid, self.pixel_depth = pixel_depth #0 for default self.window_offset = None #actual vs reported coordinates self.pending_refresh = [] + self.headerbar = headerbar self.init_window(metadata) self.setup_window(bw, bh) diff --git a/src/xpra/client/gtk3/gtk3_client_window.py b/src/xpra/client/gtk3/gtk3_client_window.py index 07b313152d..4578c3855f 100644 --- a/src/xpra/client/gtk3/gtk3_client_window.py +++ b/src/xpra/client/gtk3/gtk3_client_window.py @@ -10,6 +10,7 @@ from xpra.client.gtk_base.gtk_client_window_base import GTKClientWindowBase, HAS_X11_BINDINGS from xpra.client.gtk3.window_menu import WindowMenuHelper from xpra.gtk_common.gtk_util import WINDOW_NAME_TO_HINT, scaled_image +from xpra.scripts.config import TRUE_OPTIONS from xpra.util import envbool from xpra.os_util import bytestostr, is_gnome, OSX from xpra.log import Logger @@ -33,10 +34,9 @@ Gdk.WindowTypeHint.DND) -CUSTOM_TITLE_BAR = envbool("XPRA_CUSTOM_TITLE_BAR", not OSX) -WINDOW_ICON = CUSTOM_TITLE_BAR and envbool("XPRA_WINDOW_ICON", True) -WINDOW_XPRA_MENU = CUSTOM_TITLE_BAR and envbool("XPRA_WINDOW_XPRA_MENU", is_gnome()) -WINDOW_MENU = CUSTOM_TITLE_BAR and envbool("XPRA_WINDOW_MENU", True) +WINDOW_ICON = envbool("XPRA_WINDOW_ICON", True) +WINDOW_XPRA_MENU = envbool("XPRA_WINDOW_XPRA_MENU", is_gnome()) +WINDOW_MENU = envbool("XPRA_WINDOW_MENU", True) """ @@ -50,7 +50,11 @@ class GTK3ClientWindow(GTKClientWindowBase): def init_window(self, metadata): super().init_window(metadata) self.header_bar_image = None - if CUSTOM_TITLE_BAR and self.get_decorated() and not self.is_OR(): + hbl = (self.headerbar or "").lower().strip() + if not self.is_OR() and self.get_decorated() and ( + ((hbl in TRUE_OPTIONS) and not metadata.capsget("size-constraints")) + or hbl=="force" + ): self.add_header_bar() def _icon_size(self): diff --git a/src/xpra/client/mixins/window_manager.py b/src/xpra/client/mixins/window_manager.py index 7eb003ea0b..7f85909202 100644 --- a/src/xpra/client/mixins/window_manager.py +++ b/src/xpra/client/mixins/window_manager.py @@ -773,7 +773,8 @@ def make_new_window(self, wid, wx, wy, ww, wh, bw, bh, metadata, override_redire window = cwc(self, group_leader_window, watcher_pid, wid, wx, wy, ww, wh, bw, bh, metadata, override_redirect, client_properties, - border, self.max_window_size, self.default_cursor_data, self.pixel_depth) + border, self.max_window_size, self.default_cursor_data, self.pixel_depth, + self.headerbar) break except Exception: log.warn("failed to instantiate %s", cwc, exc_info=True) diff --git a/src/xpra/client/ui_client_base.py b/src/xpra/client/ui_client_base.py index 3c9e0cbfed..a2131402a0 100644 --- a/src/xpra/client/ui_client_base.py +++ b/src/xpra/client/ui_client_base.py @@ -128,6 +128,7 @@ def __init__(self): self.server_xdg_menu = None self.start_new_commands = [] self.start_child_new_commands = [] + self.headerbar = None #in WindowClient - should it be? #self.server_is_desktop = False @@ -169,6 +170,7 @@ def init(self, opts): self.readonly = opts.readonly self.client_supports_sharing = opts.sharing is True self.client_lock = opts.lock is True + self.headerbar = opts.headerbar def init_ui(self, opts): diff --git a/src/xpra/scripts/config.py b/src/xpra/scripts/config.py index 9f54b3f37e..be8750f1b9 100755 --- a/src/xpra/scripts/config.py +++ b/src/xpra/scripts/config.py @@ -542,6 +542,7 @@ def may_create_user_config(xpra_conf_filename=DEFAULT_XPRA_CONF_FILENAME): "open-url" : str, "file-transfer" : str, "printing" : str, + "headerbar" : str, "challenge-handlers": list, #ssl options: "ssl" : str, @@ -703,6 +704,7 @@ def may_create_user_config(xpra_conf_filename=DEFAULT_XPRA_CONF_FILENAME): "border", "window-close", "min-size", "max-size", "desktop-scaling", "file-transfer", "file-size-limit", "download-path", "open-command", "open-files", "printing", "open-url", + "headerbar", "challenge-handlers", "dbus-proxy", "remote-logging", @@ -949,6 +951,7 @@ def get_defaults(): "open-url" : "auto", "file-transfer" : "auto", "printing" : "yes", + "headerbar" : ["auto", "no"][OSX], "challenge-handlers": ["all"], #ssl options: "ssl" : "auto", diff --git a/src/xpra/scripts/parsing.py b/src/xpra/scripts/parsing.py index b165a3c857..f229078217 100755 --- a/src/xpra/scripts/parsing.py +++ b/src/xpra/scripts/parsing.py @@ -853,6 +853,10 @@ def ignore(defaults): group.add_option("--splash", action="store", metavar="yes|no", dest="splash", default=defaults.splash, help="Show a splash screen whilst loading the client. Default: %s." % defaults.splash) + legacy_bool_parse("headerbar") + group.add_option("--headerbar", action="store", metavar="yes|no", + dest="headerbar", default=defaults.headerbar, + help="Add a headerbar with menu to decorated windows. Default: %s." % defaults.headerbar) legacy_bool_parse("windows") group.add_option("--windows", action="store", metavar="yes|no", dest="windows", default=defaults.windows,