mirror of
https://github.com/labwc/labwc.git
synced 2026-03-24 09:06:09 -04:00
xdg: add snapping.notifyClient option to control tiling events
This commit is contained in:
parent
9f51384b6a
commit
3162bbb3c2
7 changed files with 100 additions and 41 deletions
|
|
@ -236,16 +236,44 @@ this is for compatibility with Openbox.
|
||||||
|
|
||||||
## WINDOW SNAPPING
|
## WINDOW SNAPPING
|
||||||
|
|
||||||
The following two options relate to triggering window actions when moving
|
Windows may be "snapped" to an edge or user-defined region of an output when
|
||||||
windows using the mouse.
|
activated with SnapToEdge actions or, optionally, by dragging windows to the
|
||||||
|
edges of an output. Edge snapping causes a window to occupy half of its output,
|
||||||
|
extending outward from the snapped edge.
|
||||||
|
|
||||||
*<snapping><range>*
|
*<snapping><range>*
|
||||||
The distance in pixels from the edge of an output for window Move
|
If an interactive move ends with the cursor a maximum distance *range*,
|
||||||
operations to trigger SnapToEdge. A range of 0 disables window snapping.
|
(in pixels) from the edge of an output, the move will trigger a
|
||||||
Default is 1.
|
SnapToEdge action for that edge. A *range* of 0 disables snapping via
|
||||||
|
interactive moves. Default is 1.
|
||||||
|
|
||||||
*<snapping><topMaximize>* [yes|no]
|
*<snapping><topMaximize>* [yes|no]
|
||||||
Maximize window if Move operation ends on the top edge. Default is yes.
|
If *yes*, an interactive move that snaps a window to the top edge will
|
||||||
|
maximize the window. If *no*, snapping will behave as it does with other
|
||||||
|
edges, causing the window to occupy the top half of an output. Default
|
||||||
|
is yes.
|
||||||
|
|
||||||
|
*<snapping><notifyClient>* [always|region|edge|never]
|
||||||
|
Snapping windows can trigger corresponding tiling events for native
|
||||||
|
Wayland clients. Clients may use these events to alter their rendering
|
||||||
|
based on knowledge that some edges of the view are confined to edges of
|
||||||
|
a snapping region or output. For example, rounded corners may become
|
||||||
|
square when tiled, or media players may letter-box or pillar-box video
|
||||||
|
rather than imposing rigid aspect ratios on windows that will violate
|
||||||
|
the constraints of window snapping.
|
||||||
|
|
||||||
|
- When *always* is specified, any window that is snapped to either an
|
||||||
|
output edge or a user-defined region will receive a tiling event.
|
||||||
|
|
||||||
|
- When *region* is specified, only windows snapped to a user-defined
|
||||||
|
region will receive an event.
|
||||||
|
|
||||||
|
- When *edge* is specified, only windows snapped to an output edge will
|
||||||
|
receive an event.
|
||||||
|
|
||||||
|
- When *never* is specified, tiling events will never be triggered.
|
||||||
|
|
||||||
|
The default is "always".
|
||||||
|
|
||||||
## REGIONS
|
## REGIONS
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,10 +78,11 @@
|
||||||
<raiseOnFocus>no</raiseOnFocus>
|
<raiseOnFocus>no</raiseOnFocus>
|
||||||
</focus>
|
</focus>
|
||||||
|
|
||||||
<!-- Set range to 0 to disable window snapping completely -->
|
|
||||||
<snapping>
|
<snapping>
|
||||||
|
<!-- Set range to 0 to disable window snapping completely -->
|
||||||
<range>1</range>
|
<range>1</range>
|
||||||
<topMaximize>yes</topMaximize>
|
<topMaximize>yes</topMaximize>
|
||||||
|
<notifyClient>always</notifyClient>
|
||||||
</snapping>
|
</snapping>
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,14 @@ enum adaptive_sync_mode {
|
||||||
LAB_ADAPTIVE_SYNC_FULLSCREEN,
|
LAB_ADAPTIVE_SYNC_FULLSCREEN,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum tiling_events_mode {
|
||||||
|
LAB_TILING_EVENTS_NEVER = 0,
|
||||||
|
LAB_TILING_EVENTS_REGION = 1 << 0,
|
||||||
|
LAB_TILING_EVENTS_EDGE = 1 << 1,
|
||||||
|
LAB_TILING_EVENTS_ALWAYS =
|
||||||
|
(LAB_TILING_EVENTS_REGION | LAB_TILING_EVENTS_EDGE),
|
||||||
|
};
|
||||||
|
|
||||||
struct usable_area_override {
|
struct usable_area_override {
|
||||||
struct border margin;
|
struct border margin;
|
||||||
char *output;
|
char *output;
|
||||||
|
|
@ -114,6 +122,7 @@ struct rcxml {
|
||||||
/* window snapping */
|
/* window snapping */
|
||||||
int snap_edge_range;
|
int snap_edge_range;
|
||||||
bool snap_top_maximize;
|
bool snap_top_maximize;
|
||||||
|
enum tiling_events_mode snap_tiling_events_mode;
|
||||||
|
|
||||||
enum resize_indicator_mode resize_indicator;
|
enum resize_indicator_mode resize_indicator;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ struct view_impl {
|
||||||
void (*map)(struct view *view);
|
void (*map)(struct view *view);
|
||||||
void (*set_activated)(struct view *view, bool activated);
|
void (*set_activated)(struct view *view, bool activated);
|
||||||
void (*set_fullscreen)(struct view *view, bool fullscreen);
|
void (*set_fullscreen)(struct view *view, bool fullscreen);
|
||||||
void (*set_tiled)(struct view *view);
|
void (*notify_tiled)(struct view *view);
|
||||||
/*
|
/*
|
||||||
* client_request is true if the client unmapped its own
|
* client_request is true if the client unmapped its own
|
||||||
* surface; false if we are just minimizing the view. The two
|
* surface; false if we are just minimizing the view. The two
|
||||||
|
|
|
||||||
|
|
@ -835,6 +835,18 @@ entry(xmlNode *node, char *nodename, char *content)
|
||||||
rc.snap_edge_range = atoi(content);
|
rc.snap_edge_range = atoi(content);
|
||||||
} else if (!strcasecmp(nodename, "topMaximize.snapping")) {
|
} else if (!strcasecmp(nodename, "topMaximize.snapping")) {
|
||||||
set_bool(content, &rc.snap_top_maximize);
|
set_bool(content, &rc.snap_top_maximize);
|
||||||
|
} else if (!strcasecmp(nodename, "notifyClient.snapping")) {
|
||||||
|
if (!strcasecmp(content, "always")) {
|
||||||
|
rc.snap_tiling_events_mode = LAB_TILING_EVENTS_ALWAYS;
|
||||||
|
} else if (!strcasecmp(content, "region")) {
|
||||||
|
rc.snap_tiling_events_mode = LAB_TILING_EVENTS_REGION;
|
||||||
|
} else if (!strcasecmp(content, "edge")) {
|
||||||
|
rc.snap_tiling_events_mode = LAB_TILING_EVENTS_EDGE;
|
||||||
|
} else if (!strcasecmp(content, "never")) {
|
||||||
|
rc.snap_tiling_events_mode = LAB_TILING_EVENTS_NEVER;
|
||||||
|
} else {
|
||||||
|
wlr_log(WLR_ERROR, "ignoring invalid value for notifyClient");
|
||||||
|
}
|
||||||
|
|
||||||
/* <windowSwitcher show="" preview="" outlines="" /> */
|
/* <windowSwitcher show="" preview="" outlines="" /> */
|
||||||
} else if (!strcasecmp(nodename, "show.windowSwitcher")) {
|
} else if (!strcasecmp(nodename, "show.windowSwitcher")) {
|
||||||
|
|
@ -1092,6 +1104,7 @@ rcxml_init(void)
|
||||||
|
|
||||||
rc.snap_edge_range = 1;
|
rc.snap_edge_range = 1;
|
||||||
rc.snap_top_maximize = true;
|
rc.snap_top_maximize = true;
|
||||||
|
rc.snap_tiling_events_mode = LAB_TILING_EVENTS_ALWAYS;
|
||||||
|
|
||||||
rc.window_switcher.show = true;
|
rc.window_switcher.show = true;
|
||||||
rc.window_switcher.preview = true;
|
rc.window_switcher.preview = true;
|
||||||
|
|
|
||||||
26
src/view.c
26
src/view.c
|
|
@ -1043,6 +1043,15 @@ view_is_floating(struct view *view)
|
||||||
|| view_is_tiled(view));
|
|| view_is_tiled(view));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
view_notify_tiled(struct view *view)
|
||||||
|
{
|
||||||
|
assert(view);
|
||||||
|
if (view->impl->notify_tiled) {
|
||||||
|
view->impl->notify_tiled(view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Reset tiled state of view without changing geometry */
|
/* Reset tiled state of view without changing geometry */
|
||||||
void
|
void
|
||||||
view_set_untiled(struct view *view)
|
view_set_untiled(struct view *view)
|
||||||
|
|
@ -1051,10 +1060,7 @@ view_set_untiled(struct view *view)
|
||||||
view->tiled = VIEW_EDGE_INVALID;
|
view->tiled = VIEW_EDGE_INVALID;
|
||||||
view->tiled_region = NULL;
|
view->tiled_region = NULL;
|
||||||
zfree(view->tiled_region_evacuate);
|
zfree(view->tiled_region_evacuate);
|
||||||
|
view_notify_tiled(view);
|
||||||
if (view->impl->set_tiled) {
|
|
||||||
view->impl->set_tiled(view);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
@ -1775,11 +1781,7 @@ view_snap_to_edge(struct view *view, enum view_edge edge,
|
||||||
view_set_untiled(view);
|
view_set_untiled(view);
|
||||||
view_set_output(view, output);
|
view_set_output(view, output);
|
||||||
view->tiled = edge;
|
view->tiled = edge;
|
||||||
|
view_notify_tiled(view);
|
||||||
if (view->impl->set_tiled) {
|
|
||||||
view->impl->set_tiled(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
view_apply_tiled_geometry(view);
|
view_apply_tiled_geometry(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1813,11 +1815,7 @@ view_snap_to_region(struct view *view, struct region *region,
|
||||||
}
|
}
|
||||||
view_set_untiled(view);
|
view_set_untiled(view);
|
||||||
view->tiled_region = region;
|
view->tiled_region = region;
|
||||||
|
view_notify_tiled(view);
|
||||||
if (view->impl->set_tiled) {
|
|
||||||
view->impl->set_tiled(view);
|
|
||||||
}
|
|
||||||
|
|
||||||
view_apply_region_geometry(view);
|
view_apply_region_geometry(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
48
src/xdg.c
48
src/xdg.c
|
|
@ -424,32 +424,42 @@ xdg_toplevel_view_set_fullscreen(struct view *view, bool fullscreen)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
xdg_toplevel_view_set_tiled(struct view *view)
|
xdg_toplevel_view_notify_tiled(struct view *view)
|
||||||
{
|
{
|
||||||
enum wlr_edges edge;
|
/* Take no action if xdg-shell tiling is disabled */
|
||||||
|
if (rc.snap_tiling_events_mode == LAB_TILING_EVENTS_NEVER) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum wlr_edges edge = WLR_EDGE_NONE;
|
||||||
|
|
||||||
|
bool want_edge = rc.snap_tiling_events_mode & LAB_TILING_EVENTS_EDGE;
|
||||||
|
bool want_region = rc.snap_tiling_events_mode & LAB_TILING_EVENTS_REGION;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Edge-snapped view are considered tiled on the snapped edge and those
|
* Edge-snapped view are considered tiled on the snapped edge and those
|
||||||
* perpendicular to it.
|
* perpendicular to it.
|
||||||
*/
|
*/
|
||||||
switch (view->tiled) {
|
if (want_edge) {
|
||||||
case VIEW_EDGE_LEFT:
|
switch (view->tiled) {
|
||||||
edge = WLR_EDGE_LEFT | WLR_EDGE_TOP | WLR_EDGE_BOTTOM;
|
case VIEW_EDGE_LEFT:
|
||||||
break;
|
edge = WLR_EDGE_LEFT | WLR_EDGE_TOP | WLR_EDGE_BOTTOM;
|
||||||
case VIEW_EDGE_RIGHT:
|
break;
|
||||||
edge = WLR_EDGE_RIGHT | WLR_EDGE_TOP | WLR_EDGE_BOTTOM;
|
case VIEW_EDGE_RIGHT:
|
||||||
break;
|
edge = WLR_EDGE_RIGHT | WLR_EDGE_TOP | WLR_EDGE_BOTTOM;
|
||||||
case VIEW_EDGE_UP:
|
break;
|
||||||
edge = WLR_EDGE_TOP | WLR_EDGE_LEFT | WLR_EDGE_RIGHT;
|
case VIEW_EDGE_UP:
|
||||||
break;
|
edge = WLR_EDGE_TOP | WLR_EDGE_LEFT | WLR_EDGE_RIGHT;
|
||||||
case VIEW_EDGE_DOWN:
|
break;
|
||||||
edge = WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT;
|
case VIEW_EDGE_DOWN:
|
||||||
break;
|
edge = WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT;
|
||||||
default:
|
break;
|
||||||
edge = WLR_EDGE_NONE;
|
default:
|
||||||
|
edge = WLR_EDGE_NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (view->tiled_region) {
|
if (want_region && view->tiled_region) {
|
||||||
/* Region-snapped views are considered tiled on all edges */
|
/* Region-snapped views are considered tiled on all edges */
|
||||||
edge = WLR_EDGE_LEFT | WLR_EDGE_RIGHT |
|
edge = WLR_EDGE_LEFT | WLR_EDGE_RIGHT |
|
||||||
WLR_EDGE_TOP | WLR_EDGE_BOTTOM;
|
WLR_EDGE_TOP | WLR_EDGE_BOTTOM;
|
||||||
|
|
@ -629,7 +639,7 @@ static const struct view_impl xdg_toplevel_view_impl = {
|
||||||
.map = xdg_toplevel_view_map,
|
.map = xdg_toplevel_view_map,
|
||||||
.set_activated = xdg_toplevel_view_set_activated,
|
.set_activated = xdg_toplevel_view_set_activated,
|
||||||
.set_fullscreen = xdg_toplevel_view_set_fullscreen,
|
.set_fullscreen = xdg_toplevel_view_set_fullscreen,
|
||||||
.set_tiled = xdg_toplevel_view_set_tiled,
|
.notify_tiled = xdg_toplevel_view_notify_tiled,
|
||||||
.unmap = xdg_toplevel_view_unmap,
|
.unmap = xdg_toplevel_view_unmap,
|
||||||
.maximize = xdg_toplevel_view_maximize,
|
.maximize = xdg_toplevel_view_maximize,
|
||||||
.minimize = xdg_toplevel_view_minimize,
|
.minimize = xdg_toplevel_view_minimize,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue