Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions data/css/default.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
padding:1em;
}

.wf-panel .window-button label {
padding-right: 5px;
}

.wf-panel .window-button.activated {
background-color: #8883;
}
Expand Down
8 changes: 5 additions & 3 deletions src/panel/panel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,8 +364,9 @@ class WayfirePanel::impl
(panel_position.value() == PANEL_POSITION_LEFT) ||
(panel_position.value() == PANEL_POSITION_RIGHT);

box.set_hexpand(!vertical);
box.set_vexpand(vertical);
const bool in_center = (&box == &center_box);
box.set_hexpand(!vertical && !in_center);
box.set_vexpand(vertical && !in_center);
}

auto widget = widget_from_name(widget_name);
Expand Down Expand Up @@ -398,7 +399,8 @@ class WayfirePanel::impl

left_box.set_hexpand(has_window_list(left_widgets_opt.value()));
right_box.set_hexpand(has_window_list(right_widgets_opt.value()));
center_box.set_hexpand(has_window_list(center_widgets_opt.value()));
center_box.set_hexpand(false);
center_box.set_vexpand(false);
}

WfOption<std::string> left_widgets_opt{"panel/widgets_left"};
Expand Down
148 changes: 85 additions & 63 deletions src/panel/widgets/window-list/layout.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,31 @@
#include "gtkmm/enums.h"
#include "toplevel.hpp"
#include "window-list.hpp"

#include <algorithm>

namespace
{
struct button_width_t
{
int minimum;
int natural;
};

button_width_t measure_button(const Gtk::Widget& child, Gtk::Orientation orientation, int forsize,
int maximum_width)
{
int minimum, natural, minimum_baseline, natural_baseline;
child.measure(orientation, forsize,
minimum, natural, minimum_baseline, natural_baseline);

// Keep the existing square minimum and respect the button's CSS minimum.
minimum = std::max(minimum, std::max(forsize, 1));
natural = std::max(minimum, std::min(natural, maximum_width));
return {minimum, natural};
}
}

WayfireWindowListLayout::WayfireWindowListLayout(WayfireWindowList *window_list)
{
this->window_list = window_list;
Expand All @@ -10,80 +35,67 @@ void WayfireWindowListLayout::allocate_vfunc(const Gtk::Widget& widget,
int width, int height, int baseline)
{
Gtk::Widget& widget_not_const = const_cast<Gtk::Widget&>(widget);
int child_count = widget.get_children().size();
if (child_count <= 0)
auto children = widget_not_const.get_children();
if (children.empty())
{
return;
}

const bool vertical = window_list->is_vertical();

int per_child;
// TODO Come back some day with rotated text labels as a vertical option
bool no_labels = window_list->hide_label.value() || vertical;

if (vertical)
{
// Keep window buttons square on a vertical panel.
per_child = width;
} else if (window_list->hide_label)
{
// Use square buttons for no label mode
per_child = height;
} else
{
per_child = width / child_count;

// user preference is ignored if too small
int preference = std::max(height, user_size.value());

// At minimum use ratio of 1:1, at max use user preference
per_child = std::max(per_child, height);
per_child = std::min(per_child, preference);
}
// width & height need to switch based on orientation
int longside = vertical ? height : width;
int shortside = vertical ? width : height;

int index = 0;
auto alloc = Gtk::Allocation();
int per_child = 1;

if (vertical)
if (no_labels)
{
alloc.set_width(width);
alloc.set_height(per_child);
alloc.set_x(0);
per_child = shortside;
} else
{
alloc.set_height(height);
alloc.set_width(per_child);
alloc.set_y(0);
per_child = longside / children.size();
int preference = std::max(shortside, user_size.value());
// Can't be larger than user preference
per_child = std::min(per_child, preference);
// Can't be smaller than square
per_child = std::max(per_child, shortside);
}

for (auto child : widget_not_const.get_children())
// Allocate locations and sizes
int offset = 0;
for (auto child : children)
{
auto alloc = Gtk::Allocation();
int position = offset;
// If widget is being dragged, show its drag location
if (child == top_widget)
{
if (vertical)
{
alloc.set_y(top_position);
} else
{
alloc.set_x(top_position);
}

child->size_allocate(alloc, -1);
index++;
continue;
position = std::max(0, std::min(top_position, longside - per_child));
}

if (vertical)
{
alloc.set_y(per_child * index);
alloc.set_width(shortside);
alloc.set_height(per_child);
alloc.set_x(0);
alloc.set_y(position);
} else
{
alloc.set_x(per_child * index);
alloc.set_width(per_child);
alloc.set_height(shortside);
alloc.set_x(position);
alloc.set_y(0);
}

child->size_allocate(alloc, -1);
index++;
offset += per_child;
}

// Update hints
for (auto& t : window_list->toplevels)
{
if (t.second)
Expand All @@ -97,32 +109,45 @@ void WayfireWindowListLayout::measure_vfunc(const Gtk::Widget& widget,
Gtk::Orientation orientation, int for_size, int& minimum, int& natural,
int& minimum_baseline, int& natural_baseline) const
{
int child_count = widget.get_children().size();
const bool vertical = window_list->is_vertical();

// TODO Come back some day with rotated text labels as a vertical option
bool no_labels = window_list->hide_label || vertical;

if (window_list->is_vertical())
// Easy mode, labels are always square, so just count
if (no_labels)
{
if (orientation == Gtk::Orientation::VERTICAL)
if ((vertical && (orientation == Gtk::Orientation::VERTICAL)) ||
(!vertical && (orientation == Gtk::Orientation::HORIZONTAL)))
{
// Measure long side, widget count * icon size
int per_child = std::max(for_size, 1);

minimum = child_count * per_child;
minimum = widget.get_children().size() * per_child;
natural = minimum;
} else
{
// No specific size required
minimum = 1;
natural = 1;
}
} else
{
if (orientation == Gtk::Orientation::HORIZONTAL)
if ((vertical && (orientation == Gtk::Orientation::VERTICAL)) ||
(!vertical && (orientation == Gtk::Orientation::HORIZONTAL)))
{
// Use max of user preference and ratio 1:1
int per_child = std::max(for_size, user_size.value());

minimum = child_count * for_size;
natural = per_child * child_count;
// When measuring the long side, count up what every widget wants
// This is only a suggestion that bubbles up
minimum = 0;
natural = 0;
for (auto child : widget.get_children())
{
auto measured = measure_button(*child, orientation, for_size, user_size.value());
minimum += measured.minimum;
natural += measured.natural;
}
} else
{
// When measuring the short side, don't suggest a size at all
minimum = 1;
natural = 1;
}
Expand All @@ -135,10 +160,7 @@ void WayfireWindowListLayout::measure_vfunc(const Gtk::Widget& widget,
Gtk::SizeRequestMode WayfireWindowListLayout::get_request_mode_vfunc(
const Gtk::Widget& widget) const
{
if (window_list->is_vertical())
{
return Gtk::SizeRequestMode::HEIGHT_FOR_WIDTH;
}

return Gtk::SizeRequestMode::WIDTH_FOR_HEIGHT;
return (window_list->is_vertical() ?
Gtk::SizeRequestMode::HEIGHT_FOR_WIDTH :
Gtk::SizeRequestMode::WIDTH_FOR_HEIGHT);
}
2 changes: 1 addition & 1 deletion src/panel/widgets/window-list/window-list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ WayfireWindowList::WayfireWindowList(WayfireOutput *output)
set_layout_manager(layout);
user_size.set_callback([=]
{
this->queue_allocate();
this->queue_resize();
});
}

Expand Down
Loading