mirror of
https://github.com/labwc/labwc.git
synced 2026-03-01 01:40:24 -05:00
feat: under-cursor window placement
With under-cursor placement, new top-level windows will be centered under the cursor rather than centered on the active view.
This commit is contained in:
parent
ce3c5ab958
commit
ef62d47ad1
8 changed files with 51 additions and 8 deletions
|
|
@ -132,6 +132,13 @@ this is for compatibility with Openbox.
|
||||||
be used with labwc the preferred mode of the monitor is used instead.
|
be used with labwc the preferred mode of the monitor is used instead.
|
||||||
Default is no.
|
Default is no.
|
||||||
|
|
||||||
|
## PLACEMENT
|
||||||
|
|
||||||
|
*<placement><policy>* [center|cursor]
|
||||||
|
Specify a placement policy for new windows. The "center" policy will
|
||||||
|
always place windows at the center of the active output. The "cursor"
|
||||||
|
policy will center new windows under the cursor. Default is "center".
|
||||||
|
|
||||||
## WINDOW SWITCHER
|
## WINDOW SWITCHER
|
||||||
|
|
||||||
*<windowSwitcher show="" preview="" outlines="">*
|
*<windowSwitcher show="" preview="" outlines="">*
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,10 @@
|
||||||
<reuseOutputMode>no</reuseOutputMode>
|
<reuseOutputMode>no</reuseOutputMode>
|
||||||
</core>
|
</core>
|
||||||
|
|
||||||
|
<placement>
|
||||||
|
<policy>center</policy>
|
||||||
|
</placement>
|
||||||
|
|
||||||
<!-- <font><theme> can be defined without an attribute to set all places -->
|
<!-- <font><theme> can be defined without an attribute to set all places -->
|
||||||
<theme>
|
<theme>
|
||||||
<name></name>
|
<name></name>
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,11 @@ enum window_switcher_field_content {
|
||||||
LAB_FIELD_TITLE,
|
LAB_FIELD_TITLE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum view_placement_policy {
|
||||||
|
LAB_PLACE_CENTER = 0,
|
||||||
|
LAB_PLACE_CURSOR
|
||||||
|
};
|
||||||
|
|
||||||
struct usable_area_override {
|
struct usable_area_override {
|
||||||
struct border margin;
|
struct border margin;
|
||||||
char *output;
|
char *output;
|
||||||
|
|
@ -40,6 +45,7 @@ struct rcxml {
|
||||||
int gap;
|
int gap;
|
||||||
bool adaptive_sync;
|
bool adaptive_sync;
|
||||||
bool reuse_output_mode;
|
bool reuse_output_mode;
|
||||||
|
enum view_placement_policy placement_policy;
|
||||||
|
|
||||||
/* focus */
|
/* focus */
|
||||||
bool focus_follow_mouse;
|
bool focus_follow_mouse;
|
||||||
|
|
|
||||||
|
|
@ -393,6 +393,13 @@ void view_store_natural_geometry(struct view *view);
|
||||||
* within; if NULL, view is centered within usable area of its output
|
* within; if NULL, view is centered within usable area of its output
|
||||||
*/
|
*/
|
||||||
void view_center(struct view *view, const struct wlr_box *ref);
|
void view_center(struct view *view, const struct wlr_box *ref);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* view_place_initial - apply initial placement strategy to view
|
||||||
|
* @view: view to be placed
|
||||||
|
*/
|
||||||
|
void view_place_initial(struct view *view);
|
||||||
|
|
||||||
void view_restore_to(struct view *view, struct wlr_box geometry);
|
void view_restore_to(struct view *view, struct wlr_box geometry);
|
||||||
void view_set_untiled(struct view *view);
|
void view_set_untiled(struct view *view);
|
||||||
void view_maximize(struct view *view, enum view_axis axis,
|
void view_maximize(struct view *view, enum view_axis axis,
|
||||||
|
|
|
||||||
|
|
@ -703,6 +703,12 @@ entry(xmlNode *node, char *nodename, char *content)
|
||||||
set_bool(content, &rc.adaptive_sync);
|
set_bool(content, &rc.adaptive_sync);
|
||||||
} else if (!strcasecmp(nodename, "reuseOutputMode.core")) {
|
} else if (!strcasecmp(nodename, "reuseOutputMode.core")) {
|
||||||
set_bool(content, &rc.reuse_output_mode);
|
set_bool(content, &rc.reuse_output_mode);
|
||||||
|
} else if (!strcmp(nodename, "policy.placement")) {
|
||||||
|
if (!strcmp(content, "cursor")) {
|
||||||
|
rc.placement_policy = LAB_PLACE_CURSOR;
|
||||||
|
} else {
|
||||||
|
rc.placement_policy = LAB_PLACE_CENTER;
|
||||||
|
}
|
||||||
} else if (!strcmp(nodename, "name.theme")) {
|
} else if (!strcmp(nodename, "name.theme")) {
|
||||||
rc.theme_name = xstrdup(content);
|
rc.theme_name = xstrdup(content);
|
||||||
} else if (!strcmp(nodename, "cornerradius.theme")) {
|
} else if (!strcmp(nodename, "cornerradius.theme")) {
|
||||||
|
|
@ -949,6 +955,8 @@ rcxml_init(void)
|
||||||
}
|
}
|
||||||
has_run = true;
|
has_run = true;
|
||||||
|
|
||||||
|
rc.placement_policy = LAB_PLACE_CENTER;
|
||||||
|
|
||||||
rc.xdg_shell_server_side_deco = true;
|
rc.xdg_shell_server_side_deco = true;
|
||||||
rc.ssd_keep_border = true;
|
rc.ssd_keep_border = true;
|
||||||
rc.corner_radius = 8;
|
rc.corner_radius = 8;
|
||||||
|
|
|
||||||
11
src/view.c
11
src/view.c
|
|
@ -678,6 +678,17 @@ view_center(struct view *view, const struct wlr_box *ref)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
view_place_initial(struct view *view)
|
||||||
|
{
|
||||||
|
if (rc.placement_policy == LAB_PLACE_CURSOR) {
|
||||||
|
view_move_to_cursor(view);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
view_center(view, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
view_apply_natural_geometry(struct view *view)
|
view_apply_natural_geometry(struct view *view)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
14
src/xdg.c
14
src/xdg.c
|
|
@ -1,4 +1,5 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "common/macros.h"
|
#include "common/macros.h"
|
||||||
#include "common/mem.h"
|
#include "common/mem.h"
|
||||||
|
|
@ -409,19 +410,18 @@ position_xdg_toplevel_view(struct view *view)
|
||||||
struct wlr_xdg_toplevel *parent_xdg_toplevel =
|
struct wlr_xdg_toplevel *parent_xdg_toplevel =
|
||||||
xdg_toplevel_from_view(view)->parent;
|
xdg_toplevel_from_view(view)->parent;
|
||||||
|
|
||||||
if (!parent_xdg_toplevel) {
|
if (parent_xdg_toplevel) {
|
||||||
view_center(view, NULL);
|
/* Child views are center-aligned relative to their parents */
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* If child-toplevel-views, we center-align relative to their
|
|
||||||
* parents
|
|
||||||
*/
|
|
||||||
struct view *parent = lookup_view_by_xdg_toplevel(
|
struct view *parent = lookup_view_by_xdg_toplevel(
|
||||||
view->server, parent_xdg_toplevel);
|
view->server, parent_xdg_toplevel);
|
||||||
assert(parent);
|
assert(parent);
|
||||||
view_set_output(view, parent->output);
|
view_set_output(view, parent->output);
|
||||||
view_center(view, &parent->pending);
|
view_center(view, &parent->pending);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* All other views are placed according to a configured strategy */
|
||||||
|
view_place_initial(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
|
|
|
||||||
|
|
@ -517,7 +517,7 @@ set_initial_position(struct view *view,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (view_is_floating(view)) {
|
if (view_is_floating(view)) {
|
||||||
view_center(view, NULL);
|
view_place_initial(view);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* View is maximized/fullscreen. Center the
|
* View is maximized/fullscreen. Center the
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue