mirror of
https://github.com/labwc/labwc.git
synced 2025-11-01 22:58:47 -04:00
feat: add Shade/Unshade/ToggleShade actions
This builds on the work of @Consolatis in #1018. Co-authored-by: Consolatis <35009135+Consolatis@users.noreply.github.com> Co-authored-by: Andrew J. Hesford <ajh@sideband.org>
This commit is contained in:
parent
722a802de0
commit
e05bedb140
19 changed files with 218 additions and 47 deletions
73
src/view.c
73
src/view.c
|
|
@ -384,6 +384,7 @@ view_resize_relative(struct view *view, int left, int right, int top, int bottom
|
|||
if (view->fullscreen || view->maximized != VIEW_AXIS_NONE) {
|
||||
return;
|
||||
}
|
||||
view_set_shade(view, false);
|
||||
struct wlr_box newgeo = view->pending;
|
||||
newgeo.x -= left;
|
||||
newgeo.width += left + right;
|
||||
|
|
@ -703,6 +704,18 @@ view_store_natural_geometry(struct view *view)
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
view_effective_height(struct view *view, bool use_pending)
|
||||
{
|
||||
assert(view);
|
||||
|
||||
if (view->shaded) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return use_pending ? view->pending.height : view->current.height;
|
||||
}
|
||||
|
||||
void
|
||||
view_center(struct view *view, const struct wlr_box *ref)
|
||||
{
|
||||
|
|
@ -1032,12 +1045,17 @@ view_maximize(struct view *view, enum view_axis axis,
|
|||
bool store_natural_geometry)
|
||||
{
|
||||
assert(view);
|
||||
|
||||
if (view->maximized == axis) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (view->fullscreen) {
|
||||
return;
|
||||
}
|
||||
|
||||
view_set_shade(view, false);
|
||||
|
||||
if (axis != VIEW_AXIS_NONE) {
|
||||
/*
|
||||
* Maximize via keybind or client request cancels
|
||||
|
|
@ -1087,6 +1105,12 @@ void
|
|||
view_toggle_decorations(struct view *view)
|
||||
{
|
||||
assert(view);
|
||||
|
||||
/* Reject decoration toggles when shaded */
|
||||
if (view->shaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rc.ssd_keep_border && view->ssd_enabled && view->ssd
|
||||
&& !view->ssd_titlebar_hidden) {
|
||||
/*
|
||||
|
|
@ -1209,6 +1233,7 @@ void
|
|||
view_toggle_fullscreen(struct view *view)
|
||||
{
|
||||
assert(view);
|
||||
|
||||
view_set_fullscreen(view, !view->fullscreen);
|
||||
}
|
||||
|
||||
|
|
@ -1216,6 +1241,11 @@ view_toggle_fullscreen(struct view *view)
|
|||
static void
|
||||
set_fullscreen(struct view *view, bool fullscreen)
|
||||
{
|
||||
/* When going fullscreen, unshade the window */
|
||||
if (fullscreen) {
|
||||
view_set_shade(view, false);
|
||||
}
|
||||
|
||||
/* Hide decorations when going fullscreen */
|
||||
if (fullscreen && view->ssd_enabled) {
|
||||
undecorate(view);
|
||||
|
|
@ -1561,7 +1591,8 @@ view_move_to_edge(struct view *view, enum view_edge direction, bool snap_to_wind
|
|||
destination_y = top;
|
||||
break;
|
||||
case VIEW_EDGE_DOWN:
|
||||
destination_y = bottom - view->pending.height;
|
||||
destination_y = bottom
|
||||
- view_effective_height(view, /* use_pending */ true);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
|
|
@ -1578,9 +1609,11 @@ view_move_to_edge(struct view *view, enum view_edge direction, bool snap_to_wind
|
|||
destination_x = MAX(destination_x, left);
|
||||
|
||||
/* If more than half the view is below usable region, align to bottom */
|
||||
midpoint = destination_y + view->pending.height / 2;
|
||||
midpoint = destination_y
|
||||
+ view_effective_height(view, /* use_pending */ true) / 2;
|
||||
if (destination_y >= top && midpoint > usable.y + usable.height) {
|
||||
destination_y = bottom - view->pending.height;
|
||||
destination_y = bottom
|
||||
- view_effective_height(view, /* use_pending */ true);
|
||||
}
|
||||
|
||||
/* Never allow the window to start above the usable edge */
|
||||
|
|
@ -1599,11 +1632,14 @@ view_grow_to_edge(struct view *view, enum view_edge direction)
|
|||
if (view->fullscreen || view->maximized != VIEW_AXIS_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!output_is_usable(view->output)) {
|
||||
wlr_log(WLR_ERROR, "view has no output, not growing view");
|
||||
return;
|
||||
}
|
||||
|
||||
view_set_shade(view, false);
|
||||
|
||||
struct wlr_box geo = view->pending;
|
||||
snap_grow_to_next_edge(view, direction, &geo);
|
||||
view_move_resize(view, geo);
|
||||
|
|
@ -1613,15 +1649,19 @@ void
|
|||
view_shrink_to_edge(struct view *view, enum view_edge direction)
|
||||
{
|
||||
assert(view);
|
||||
|
||||
/* TODO: allow shrink to edge if maximized along the other axis */
|
||||
if (view->fullscreen || view->maximized != VIEW_AXIS_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!output_is_usable(view->output)) {
|
||||
wlr_log(WLR_ERROR, "view has no output, not shrinking view");
|
||||
return;
|
||||
}
|
||||
|
||||
view_set_shade(view, false);
|
||||
|
||||
struct wlr_box geo = view->pending;
|
||||
snap_shrink_to_next_edge(view, direction, &geo);
|
||||
view_move_resize(view, geo);
|
||||
|
|
@ -1670,15 +1710,19 @@ view_snap_to_edge(struct view *view, enum view_edge edge,
|
|||
bool across_outputs, bool store_natural_geometry)
|
||||
{
|
||||
assert(view);
|
||||
|
||||
if (view->fullscreen) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct output *output = view->output;
|
||||
if (!output_is_usable(output)) {
|
||||
wlr_log(WLR_ERROR, "view has no output, not snapping to edge");
|
||||
return;
|
||||
}
|
||||
|
||||
view_set_shade(view, false);
|
||||
|
||||
if (across_outputs && view->tiled == edge && view->maximized == VIEW_AXIS_NONE) {
|
||||
/* We are already tiled for this edge; try to switch outputs */
|
||||
output = view_get_adjacent_output(view, edge);
|
||||
|
|
@ -1721,15 +1765,19 @@ view_snap_to_region(struct view *view, struct region *region,
|
|||
{
|
||||
assert(view);
|
||||
assert(region);
|
||||
|
||||
if (view->fullscreen) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* view_apply_region_geometry() needs a usable output */
|
||||
if (!output_is_usable(view->output)) {
|
||||
wlr_log(WLR_ERROR, "view has no output, not snapping to region");
|
||||
return;
|
||||
}
|
||||
|
||||
view_set_shade(view, false);
|
||||
|
||||
if (view->maximized != VIEW_AXIS_NONE) {
|
||||
/* Unmaximize + keep using existing natural_geometry */
|
||||
view_maximize(view, VIEW_AXIS_NONE,
|
||||
|
|
@ -1974,6 +2022,25 @@ view_connect_map(struct view *view, struct wlr_surface *surface)
|
|||
mappable_connect(&view->mappable, surface, handle_map, handle_unmap);
|
||||
}
|
||||
|
||||
void
|
||||
view_set_shade(struct view *view, bool shaded)
|
||||
{
|
||||
assert(view);
|
||||
|
||||
if (view->shaded == shaded) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Views without a title-bar or SSD cannot be shaded */
|
||||
if (shaded && (!view->ssd || view->ssd_titlebar_hidden)) {
|
||||
return;
|
||||
}
|
||||
|
||||
view->shaded = shaded;
|
||||
ssd_enable_shade(view->ssd, view->shaded);
|
||||
wlr_scene_node_set_enabled(view->scene_node, !view->shaded);
|
||||
}
|
||||
|
||||
void
|
||||
view_destroy(struct view *view)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue