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:
Andrew J. Hesford 2023-12-10 21:00:05 -05:00 committed by Johan Malm
parent ce3c5ab958
commit ef62d47ad1
8 changed files with 51 additions and 8 deletions

View file

@ -132,6 +132,13 @@ this is for compatibility with Openbox.
be used with labwc the preferred mode of the monitor is used instead.
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
*<windowSwitcher show="" preview="" outlines="">*

View file

@ -14,6 +14,10 @@
<reuseOutputMode>no</reuseOutputMode>
</core>
<placement>
<policy>center</policy>
</placement>
<!-- <font><theme> can be defined without an attribute to set all places -->
<theme>
<name></name>

View file

@ -20,6 +20,11 @@ enum window_switcher_field_content {
LAB_FIELD_TITLE,
};
enum view_placement_policy {
LAB_PLACE_CENTER = 0,
LAB_PLACE_CURSOR
};
struct usable_area_override {
struct border margin;
char *output;
@ -40,6 +45,7 @@ struct rcxml {
int gap;
bool adaptive_sync;
bool reuse_output_mode;
enum view_placement_policy placement_policy;
/* focus */
bool focus_follow_mouse;

View file

@ -393,6 +393,13 @@ void view_store_natural_geometry(struct view *view);
* within; if NULL, view is centered within usable area of its output
*/
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_set_untiled(struct view *view);
void view_maximize(struct view *view, enum view_axis axis,

View file

@ -703,6 +703,12 @@ entry(xmlNode *node, char *nodename, char *content)
set_bool(content, &rc.adaptive_sync);
} else if (!strcasecmp(nodename, "reuseOutputMode.core")) {
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")) {
rc.theme_name = xstrdup(content);
} else if (!strcmp(nodename, "cornerradius.theme")) {
@ -949,6 +955,8 @@ rcxml_init(void)
}
has_run = true;
rc.placement_policy = LAB_PLACE_CENTER;
rc.xdg_shell_server_side_deco = true;
rc.ssd_keep_border = true;
rc.corner_radius = 8;

View file

@ -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
view_apply_natural_geometry(struct view *view)
{

View file

@ -1,4 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
#include <assert.h>
#include "common/macros.h"
#include "common/mem.h"
@ -409,19 +410,18 @@ position_xdg_toplevel_view(struct view *view)
struct wlr_xdg_toplevel *parent_xdg_toplevel =
xdg_toplevel_from_view(view)->parent;
if (!parent_xdg_toplevel) {
view_center(view, NULL);
} else {
/*
* If child-toplevel-views, we center-align relative to their
* parents
*/
if (parent_xdg_toplevel) {
/* Child views are center-aligned relative to their parents */
struct view *parent = lookup_view_by_xdg_toplevel(
view->server, parent_xdg_toplevel);
assert(parent);
view_set_output(view, parent->output);
view_center(view, &parent->pending);
return;
}
/* All other views are placed according to a configured strategy */
view_place_initial(view);
}
static const char *

View file

@ -517,7 +517,7 @@ set_initial_position(struct view *view,
}
} else {
if (view_is_floating(view)) {
view_center(view, NULL);
view_place_initial(view);
} else {
/*
* View is maximized/fullscreen. Center the