From f80ad2ea3033276d2b4d849b1015b6c08565e529 Mon Sep 17 00:00:00 2001 From: flodavid Date: Wed, 11 Mar 2026 18:55:05 +0100 Subject: [PATCH] Separate launcher and worskpace docks --- data/Application.css | 4 +++ src/BaseItem.vala | 2 ++ src/HorizontalMargin.vala | 30 ++++++++++++++++ src/ItemManager.vala | 27 ++------------ src/MainWindow.vala | 62 +++++++++++++++++++++++--------- src/WorkspaceManager.vala | 74 +++++++++++++++++++++++++++++++++++++++ src/meson.build | 2 ++ 7 files changed, 159 insertions(+), 42 deletions(-) create mode 100644 src/HorizontalMargin.vala create mode 100644 src/WorkspaceManager.vala diff --git a/data/Application.css b/data/Application.css index bfd5c8a1..3b6fba5c 100644 --- a/data/Application.css +++ b/data/Application.css @@ -40,6 +40,10 @@ bottom-margin { min-height: 9px; } +horizontal-margin { + min-width: 9px; +} + launcher { padding: 6px; padding-bottom: 0px; diff --git a/src/BaseItem.vala b/src/BaseItem.vala index 8fe6da6c..b347645b 100644 --- a/src/BaseItem.vala +++ b/src/BaseItem.vala @@ -300,6 +300,8 @@ public class Dock.BaseItem : Gtk.Box { public void calculate_dnd_move (BaseItem source, double x, double y) { var launcher_manager = ItemManager.get_default (); launcher_manager.move_launcher_after (source, (int) get_index ()); + var workspace_manager = WorkspaceManager.get_default (); + workspace_manager.move_launcher_after (source, (int) get_index ()); } private bool on_drop (Value val) { diff --git a/src/HorizontalMargin.vala b/src/HorizontalMargin.vala new file mode 100644 index 00000000..c94e2358 --- /dev/null +++ b/src/HorizontalMargin.vala @@ -0,0 +1,30 @@ +/* + * SPDX-License-Identifier: GPL-3.0 + * SPDX-FileCopyrightText: 2026 elementary, Inc. (https://elementary.io) + */ + +public class HorizontalMargin : Gtk.Widget { + private static GLib.List instances = new GLib.List (); + + class construct { + set_css_name ("horizontal-margin"); + } + + construct { + instances.append (this); + } + + ~HorizontalMargin () { + instances.remove (this); + } + + public new static int get_size () { + foreach (var instance in instances) { + if (instance.get_realized ()) { + return instance.get_width (); + } + } + + return 0; + } +} diff --git a/src/ItemManager.vala b/src/ItemManager.vala index a3e7e964..b9083e14 100644 --- a/src/ItemManager.vala +++ b/src/ItemManager.vala @@ -15,10 +15,6 @@ private DynamicWorkspaceIcon dynamic_workspace_item; -#if WORKSPACE_SWITCHER - private Gtk.Separator separator; -#endif - static construct { settings = new Settings ("io.elementary.dock"); } @@ -29,23 +25,9 @@ var background_item = new BackgroundItem (); var background_group = new ItemGroup (background_item.group_model, (obj) => (BackgroundItem) obj); -#if WORKSPACE_SWITCHER - dynamic_workspace_item = new DynamicWorkspaceIcon (); - - separator = new Gtk.Separator (VERTICAL) { - valign = START, - margin_top = Launcher.PADDING, - }; - settings.bind ("icon-size", separator, "height-request", GET); -#endif - append (app_group); append (background_group); -#if WORKSPACE_SWITCHER - append (separator); - append (new ItemGroup (WorkspaceSystem.get_default ().workspaces, (obj) => new WorkspaceIconGroup ((Workspace) obj))); - append (dynamic_workspace_item); -#endif + overflow = VISIBLE; var drop_target_file = new Gtk.DropTarget (typeof (File), COPY) { @@ -148,19 +130,14 @@ map.connect (() => { AppSystem.get_default ().load.begin (); background_item.load (); -#if WORKSPACE_SWITCHER - WorkspaceSystem.get_default ().load.begin (); -#endif }); } public void move_launcher_after (BaseItem source, int target_index) { if (source is Launcher) { AppSystem.get_default ().reorder_app (source.app, target_index); - } else if (source is WorkspaceIconGroup) { - WorkspaceSystem.get_default ().reorder_workspace (source.workspace, target_index); } else { - warning ("Tried to move neither launcher nor icon group"); + info ("Tried to move not a launcher"); } } diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 2d05ae08..0c7b9c8f 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -36,23 +36,47 @@ public class Dock.MainWindow : Gtk.ApplicationWindow { resizable = false; titlebar = new Gtk.Label ("") { visible = false }; - var dock_box = new Gtk.Box (VERTICAL, 0); - dock_box.append (new Container ()); - dock_box.append (new BottomMargin ()); + /* Launcher */ + var launcher_container = new Gtk.Box (VERTICAL, 0); + launcher_container.append (new Container ()); + launcher_container.append (new BottomMargin ()); + + // // Don't clip launchers to dock background https://github.com/elementary/dock/issues/275 + var launcher_overlay = new Gtk.Overlay () { + child = launcher_container + }; unowned var launcher_manager = ItemManager.get_default (); + launcher_overlay.add_overlay (launcher_manager); + + var launcher_size_group = new Gtk.SizeGroup (Gtk.SizeGroupMode.BOTH); + launcher_size_group.add_widget (launcher_container); + launcher_size_group.add_widget (launcher_manager); + + /* Workspace */ + + var workspace_manager = WorkspaceManager.get_default (); + var workspace_container = new Gtk.Box (VERTICAL, 0); + workspace_container.append (new Container ()); + workspace_container.append (new BottomMargin ()); - // Don't clip launchers to dock background https://github.com/elementary/dock/issues/275 - var overlay = new Gtk.Overlay () { - child = dock_box + var workspace_overlay = new Gtk.Overlay () { + child = workspace_container }; - overlay.add_overlay (launcher_manager); + workspace_overlay.add_overlay (workspace_manager); - var size_group = new Gtk.SizeGroup (Gtk.SizeGroupMode.BOTH); - size_group.add_widget (dock_box); - size_group.add_widget (launcher_manager); + var workspace_size_group = new Gtk.SizeGroup (Gtk.SizeGroupMode.BOTH); + workspace_size_group.add_widget (workspace_container); + workspace_size_group.add_widget (workspace_manager); - child = overlay; + /* Full dock */ + + var docks_box = new Gtk.Box (HORIZONTAL, 0); + docks_box.append (launcher_overlay); + docks_box.append (new HorizontalMargin ()); + docks_box.append (workspace_overlay); + + child = docks_box; remove_css_class ("background"); @@ -85,7 +109,6 @@ public class Dock.MainWindow : Gtk.ApplicationWindow { remove_css_class ("reduce-transparency"); } else { add_css_class ("reduce-transparency"); - } } @@ -113,7 +136,9 @@ public class Dock.MainWindow : Gtk.ApplicationWindow { // manually set shadow width since the additional margin we add to avoid icons clipping when // bouncing isn't added by default and instead counts to the frame var item_manager_width = ItemManager.get_default ().get_width (); - var shadow_size = (surface.width - item_manager_width) / 2; + var hztl_margin_width = HorizontalMargin.get_size (); + var workspace_manager_width = WorkspaceManager.get_default ().get_width (); + var shadow_size = (surface.width - item_manager_width - hztl_margin_width - workspace_manager_width) / 2; var top_margin = TOP_MARGIN + shadow_size - 1; size.set_shadow_width (shadow_size, shadow_size, top_margin, shadow_size); }); @@ -122,12 +147,14 @@ public class Dock.MainWindow : Gtk.ApplicationWindow { // manually set input region since container's shadow are is the content of the window // and it still gets window events var item_manager_width = ItemManager.get_default ().get_width (); - var shadow_size = (width - item_manager_width) / 2; + var hztl_margin_width = HorizontalMargin.get_size (); + var workspace_manager_width = WorkspaceManager.get_default ().get_width (); + var shadow_size = (width - item_manager_width - hztl_margin_width - workspace_manager_width) / 2; var top_margin = TOP_MARGIN + shadow_size; surface.set_input_region (new Cairo.Region.rectangle ({ shadow_size, top_margin, - item_manager_width, + item_manager_width + workspace_manager_width, height - top_margin })); @@ -148,6 +175,7 @@ public class Dock.MainWindow : Gtk.ApplicationWindow { if (panel != null) { panel.add_blur (0, 0, 0, BottomMargin.get_size (), border_radius); + } else { update_panel_x11 (); } @@ -159,8 +187,8 @@ public class Dock.MainWindow : Gtk.ApplicationWindow { unowned var wl_display = ((Gdk.Wayland.Display) display).get_wl_display (); var wl_registry = wl_display.get_registry (); wl_registry.add_listener ( - registry_listener, - this + registry_listener, + this ); if (wl_display.roundtrip () < 0) { diff --git a/src/WorkspaceManager.vala b/src/WorkspaceManager.vala new file mode 100644 index 00000000..0deb345e --- /dev/null +++ b/src/WorkspaceManager.vala @@ -0,0 +1,74 @@ +/* + * SPDX-License-Identifier: GPL-3.0 + * SPDX-FileCopyrightText: 2026 elementary, Inc. (https://elementary.io) + */ + + public class Dock.WorkspaceManager : Gtk.Box { + private static Settings settings; + + private static GLib.Once instance; + public static unowned WorkspaceManager get_default () { + return instance.once (() => { return new WorkspaceManager (); }); + } + + private DynamicWorkspaceIcon dynamic_workspace_item; + + static construct { + settings = new Settings ("io.elementary.dock"); + } + + construct { + dynamic_workspace_item = new DynamicWorkspaceIcon (); + + append (new ItemGroup (WorkspaceSystem.get_default ().workspaces, (obj) => new WorkspaceIconGroup ((Workspace) obj))); + append (dynamic_workspace_item); + + overflow = VISIBLE; + + var drop_target_file = new Gtk.DropTarget (typeof (File), COPY) { + preload = true + }; + add_controller (drop_target_file); + + double drop_x, drop_y; + drop_target_file.enter.connect ((x, y) => { + drop_x = x; + drop_y = y; + return COPY; + }); + + drop_target_file.notify["value"].connect (() => { + if (drop_target_file.get_value () == null) { + return; + } + + if (drop_target_file.get_value ().get_object () == null) { + return; + } + + if (!(drop_target_file.get_value ().get_object () is File)) { + return; + } + + var file = (File) drop_target_file.get_value ().get_object (); + var app_info = new DesktopAppInfo.from_filename (file.get_path ()); + + if (app_info == null) { + return; + } + }); + + map.connect (() => { + WorkspaceSystem.get_default ().load.begin (); + }); + } + + public void move_launcher_after (BaseItem source, int target_index) { + if (source is WorkspaceIconGroup) { + WorkspaceSystem.get_default ().reorder_workspace (source.workspace, target_index); + } else { + info ("Tried to move not an icon group"); + return; + } + } +} diff --git a/src/meson.build b/src/meson.build index 4e860dee..29379d9b 100644 --- a/src/meson.build +++ b/src/meson.build @@ -3,9 +3,11 @@ sources = [ 'BaseIconGroup.vala', 'BaseItem.vala', 'BottomMargin.vala', + 'HorizontalMargin.vala', 'ContainerItem.vala', 'ItemGroup.vala', 'ItemManager.vala', + 'WorkspaceManager.vala', 'MainWindow.vala', 'RenderNodeWalker.vala', 'AppSystem' / 'App.vala',