Skip to content
48 changes: 46 additions & 2 deletions src/ItemManager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#if WORKSPACE_SWITCHER
private Gtk.Separator separator;
private DynamicWorkspaceIcon dynamic_workspace_item;
private Gtk.Revealer workspaces_scrollbar_revealer;
#endif

static construct {
Expand All @@ -20,6 +21,12 @@
construct {
var app_group = new ItemGroup (AppSystem.get_default ().apps, (obj) => new Launcher ((App) obj));

var app_group_scrolled = new Gtk.ScrolledWindow () {
child = app_group,
vscrollbar_policy = NEVER,
propagate_natural_width = true
};

var background_item = new BackgroundItem ();
var background_group = new ItemGroup (background_item.group_model, (obj) => (BackgroundItem) obj);

Expand All @@ -33,14 +40,47 @@
separator_box.append (new TopMargin ());
separator_box.append (separator);

var workspace_group_scrolled = new Gtk.ScrolledWindow () {
child = new ItemGroup (WorkspaceSystem.get_default ().workspaces, (obj) => new WorkspaceIconGroup ((Workspace) obj)),
hscrollbar_policy = EXTERNAL,
vscrollbar_policy = NEVER,
propagate_natural_width = true
};

/*
* Gtk.ScrolledWindow with scrollbar policy set to ALWAYS or AUTOMATIC reserves ~30px of space for scrollbar
* And it doesn't matter if the scrollbar is shown or not, the space is always reserved.
* Essentially, by default workspace_group_scrolled's minimum size is 30px, to avoid this
* we set scrollbar policy to EXTERNAL and handle scrollbar ourselves.
*/

var workspaces_scrollbar = new Gtk.Scrollbar (HORIZONTAL, workspace_group_scrolled.hadjustment) {
vexpand = false,
valign = END
};

workspaces_scrollbar_revealer = new Gtk.Revealer () {
child = workspaces_scrollbar,
vexpand = false,
valign = END
};

update_workspaces_scrollbar_revealer (workspace_group_scrolled.hadjustment);
workspace_group_scrolled.hadjustment.changed.connect (update_workspaces_scrollbar_revealer);

var scrollbar_overlay = new Gtk.Overlay () {
child = workspace_group_scrolled
};
scrollbar_overlay.add_overlay (workspaces_scrollbar_revealer);

dynamic_workspace_item = new DynamicWorkspaceIcon ();
#endif

append (app_group);
append (app_group_scrolled);
append (background_group);
#if WORKSPACE_SWITCHER
append (separator_box);
append (new ItemGroup (WorkspaceSystem.get_default ().workspaces, (obj) => new WorkspaceIconGroup ((Workspace) obj)));
append (scrollbar_overlay);
append (dynamic_workspace_item);
#endif
overflow = VISIBLE;
Expand Down Expand Up @@ -160,4 +200,8 @@
warning ("Tried to move neither launcher nor icon group");
}
}

private void update_workspaces_scrollbar_revealer (Gtk.Adjustment adjustment) {
workspaces_scrollbar_revealer.reveal_child = adjustment.upper - adjustment.lower > adjustment.page_size;
}
}
30 changes: 30 additions & 0 deletions src/MainWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -188,4 +188,34 @@ public class Dock.MainWindow : Gtk.ApplicationWindow {
xdisplay.change_property (window, prop, X.XA_STRING, 8, 0, (uchar[]) value, value.length);
}
}

public override void measure (
Gtk.Orientation orientation,
int for_size,
out int minimum,
out int natural,
out int minimum_baseline,
out int natural_baseline
) {
if (orientation != HORIZONTAL) {
base.measure (orientation, for_size, out minimum, out natural, out minimum_baseline, out natural_baseline);
return;
}

minimum = minimum_baseline = natural_baseline = -1;

var monitor_width = int.MAX;
unowned var surface = get_surface ();
if (surface != null) {
unowned var monitor = Gdk.Display.get_default ().get_monitor_at_surface (surface);
if (monitor != null) {
monitor_width = monitor.geometry.width;
}
}

int item_manager_natural_width;
item_manager.measure (HORIZONTAL, -1, null, out item_manager_natural_width, null, null);

natural = int.min (item_manager_natural_width, monitor_width - 2 * BottomMargin.get_size ());
}
}