diff --git a/README.md b/README.md index 1abf7b1c..1868589b 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ The extensible top panel for Pantheon. Wingpanel is an empty container that acce You'll need the following dependencies: +* libgtk4-layer-shell-dev >= 1.0.4 * libgala-dev >= 8.3.0 * libgee-0.8-dev * libglib2.0-dev diff --git a/meson.build b/meson.build index 57719c49..3ee0b666 100644 --- a/meson.build +++ b/meson.build @@ -24,6 +24,8 @@ i18n = import('i18n') gnome = import('gnome') pkg = import('pkgconfig') +gtkls_dep = dependency('gtk4-layer-shell-0', required: get_option('layer_shell')) +gala_dep = dependency('gala', version: '>= 8.3.0', required: not gtkls_dep.found()) glib_dep = dependency('glib-2.0', version: '>=2.32') gio_dep = dependency('gio-2.0') gio_unix_dep = dependency('gio-unix-2.0') @@ -35,19 +37,31 @@ granite_dep = dependency('granite-7', version: '>=7.6.0') posix_dep = vala.find_library('posix') wl_client_dep = dependency('wayland-client') -subdir('protocol') +if gala_dep.found() + add_project_arguments('-D', 'USE_GALA', language: 'vala') +endif +if gtkls_dep.found() + add_project_arguments('-D', 'USE_LAYER_SHELL', language: 'vala') +endif + subdir('data') subdir('lib') subdir('schemas') + +if gala_dep.found() + subdir('protocol') + subdir('wingpanel-interface') + + vapigen = find_program('vapigen', required: false) + if vapigen.found() + subdir('vapi') + endif +endif + subdir('src') -subdir('wingpanel-interface') if get_option('example') subdir('sample') endif subdir('po') -vapigen = find_program('vapigen', required: false) -if vapigen.found() - subdir('vapi') -endif gnome.post_install(glib_compile_schemas: true) diff --git a/meson_options.txt b/meson_options.txt index a57e35b6..114343ef 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1 +1,2 @@ +option('layer_shell', type: 'feature', value: 'auto', description: 'Build with wlr-layer-shell-unstable-v1 support') option('example', type: 'boolean', value: false, description: 'Build an example that shows how it works') diff --git a/src/PanelWindow.vala b/src/PanelWindow.vala index 88c23192..3f8f82db 100644 --- a/src/PanelWindow.vala +++ b/src/PanelWindow.vala @@ -29,14 +29,16 @@ public class Wingpanel.PanelWindow : Gtk.Window { private Services.PopoverManager popover_manager; private Widgets.Panel panel; +#if USE_GALA private Pantheon.Desktop.Shell? desktop_shell; private Pantheon.Desktop.Panel? desktop_panel; private bool initialized_background_manager = false; private Gtk.CssProvider? style_provider = null; +#endif construct { - popover_manager = new Services.PopoverManager (); + popover_manager = new Services.PopoverManager (this); panel = new Widgets.Panel (popover_manager); panel.realize.connect (on_realize); @@ -50,6 +52,7 @@ public class Wingpanel.PanelWindow : Gtk.Window { decorated = false; resizable = false; +#if USE_GALA popover_manager.notify["indicator-open"].connect (() => { if (!popover_manager.indicator_open) { Services.BackgroundManager.get_default ().restore_window (); @@ -60,6 +63,16 @@ public class Wingpanel.PanelWindow : Gtk.Window { }); Services.BackgroundManager.get_default ().background_state_changed.connect (update_background); +#endif + +#if USE_LAYER_SHELL + GtkLayerShell.init_for_window (this); + GtkLayerShell.set_layer (this, GtkLayerShell.Layer.TOP); + GtkLayerShell.auto_exclusive_zone_enable (this); + GtkLayerShell.set_anchor (this, GtkLayerShell.Edge.TOP, true); + GtkLayerShell.set_anchor (this, GtkLayerShell.Edge.LEFT, true); + GtkLayerShell.set_anchor (this, GtkLayerShell.Edge.RIGHT, true); +#endif } private void on_realize () { @@ -69,7 +82,9 @@ public class Wingpanel.PanelWindow : Gtk.Window { surface.enter_monitor.connect (on_enter_monitor); +#if USE_GALA init_wl (); +#endif } private static void on_compute_size (Gdk.ToplevelSize top_level_size) { @@ -83,10 +98,12 @@ public class Wingpanel.PanelWindow : Gtk.Window { }) ); +#if USE_GALA if (!initialized_background_manager) { Services.BackgroundManager.initialize (panel.get_height ()); initialized_background_manager = true; } +#endif } private void on_enter_monitor (Gdk.Monitor new_monitor) { @@ -101,6 +118,7 @@ public class Wingpanel.PanelWindow : Gtk.Window { panel.toggle_indicator (name); } +#if USE_GALA public void registry_handle_global (Wl.Registry wl_registry, uint32 name, string @interface, uint32 version) { if (@interface == "io_elementary_pantheon_shell_v1") { desktop_shell = wl_registry.bind (name, ref Pantheon.Desktop.Shell.iface, uint32.min (version, 1)); @@ -188,6 +206,7 @@ public class Wingpanel.PanelWindow : Gtk.Window { break; } } +#endif public override void measure ( Gtk.Orientation orientation, diff --git a/src/Services/PopoverManager.vala b/src/Services/PopoverManager.vala index 78bfe843..6f248e2f 100644 --- a/src/Services/PopoverManager.vala +++ b/src/Services/PopoverManager.vala @@ -19,6 +19,7 @@ public class Wingpanel.Services.PopoverManager : Object { public bool indicator_open { get; private set; default = false; } + public unowned Wingpanel.PanelWindow owner { get; construct; } private Gtk.Popover popover; @@ -57,16 +58,37 @@ public class Wingpanel.Services.PopoverManager : Object { popover.child = _current_indicator.indicator_widget; _current_indicator.display_widget.has_tooltip = false; popover.set_parent (_current_indicator); + _current_indicator.base_indicator.opened (); +#if USE_LAYER_SHELL + GtkLayerShell.set_keyboard_mode (owner, GtkLayerShell.KeyboardMode.ON_DEMAND); +#endif popover.popup (); _current_indicator.set_state_flags (CHECKED, true); - _current_indicator.base_indicator.opened (); + if (owner.is_active) { + _current_indicator.indicator_widget.child_focus (Gtk.DirectionType.TAB_FORWARD); + } else { + ulong handler_id = 0; + handler_id = owner.notify["is-active"].connect (() => { + if (owner.is_active && _current_indicator != null) { + _current_indicator.indicator_widget.child_focus (Gtk.DirectionType.TAB_FORWARD); + SignalHandler.disconnect (owner, handler_id); + } + }); + } } else { ((Widgets.IndicatorEntry)popover.parent).display_widget.has_tooltip = true; +#if USE_LAYER_SHELL + GtkLayerShell.set_keyboard_mode (owner, GtkLayerShell.KeyboardMode.NONE); +#endif popover.popdown (); } } } + public PopoverManager (Wingpanel.PanelWindow owner) { + Object (owner: owner); + } + construct { popover = new Gtk.Popover () { has_arrow = false, diff --git a/src/Widgets/Panel.vala b/src/Widgets/Panel.vala index 6999e9c3..5d46ef28 100644 --- a/src/Widgets/Panel.vala +++ b/src/Widgets/Panel.vala @@ -151,8 +151,10 @@ public class Wingpanel.Widgets.Panel : Granite.Bin { private void begin_drag (double x, double y) { popover_manager.current_indicator = null; +#if USE_GALA var background_manager = Services.BackgroundManager.get_default (); background_manager.begin_grab_focused_window ((int) x, (int) y); +#endif } private void cycle (Gtk.DirectionType direction) { diff --git a/src/meson.build b/src/meson.build index 876f50d4..c2dbfa2b 100644 --- a/src/meson.build +++ b/src/meson.build @@ -15,9 +15,14 @@ wingpanel_deps = [ granite_dep, gdk_wl_dep, posix_dep, - wl_client_dep, - pantheon_desktop_shell_dep + wl_client_dep ] +if gtkls_dep.found() + wingpanel_deps += [gtkls_dep] +endif +if gala_dep.found() + wingpanel_deps += [pantheon_desktop_shell_dep] +endif executable(meson.project_name(), css_gresource, diff --git a/wingpanel-interface/meson.build b/wingpanel-interface/meson.build index fcda54d6..84cf1a4b 100644 --- a/wingpanel-interface/meson.build +++ b/wingpanel-interface/meson.build @@ -81,7 +81,6 @@ endif mutter_typelib_dir = libmutter_dep.get_variable('typelibdir') -gala_dep = dependency('gala', version: '>= 8.3.0') m_dep = meson.get_compiler('c').find_library('m', required: false) shared_module(