]> git.mdlowis.com Git - proto/labwc.git/commitdiff
feat: under-cursor window placement
authorAndrew J. Hesford <ajh@sideband.org>
Mon, 11 Dec 2023 02:00:05 +0000 (21:00 -0500)
committerJohan Malm <johanmalm@users.noreply.github.com>
Tue, 26 Dec 2023 19:20:06 +0000 (19:20 +0000)
With under-cursor placement, new top-level windows will be centered
under the cursor rather than centered on the active view.

docs/labwc-config.5.scd
docs/rc.xml.all
include/config/rcxml.h
include/view.h
src/config/rcxml.c
src/view.c
src/xdg.c
src/xwayland.c

index 08c7aef60b28f1354bf11cbc8737c672b3f98d9a..c37dddc2fea58543455391edc19cfa52a94272ba 100644 (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="">*
index 7c59660a5c0706a9032d83f9ced6cbfd7b86ad9c..96439dc9e3c7e0dda61d88ee81a5eb5fecf97ccb 100644 (file)
     <reuseOutputMode>no</reuseOutputMode>
   </core>
 
+  <placement>
+    <policy>center</policy>
+  </placement>
+
   <!-- <font><theme> can be defined without an attribute to set all places -->
   <theme>
     <name></name>
index 62cc5a15f2fd18e03dcf607e5a53cecb2407272c..b6a116dafa4989f50906a10f236df09e54917817 100644 (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;
index a3dd9cb069cea6b23b310d48c4d8ec54820d7adf..bef7afea1bf689430f85740b8413aa5afbee250b 100644 (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,
index efd6122f04af835863dbd214b83ec819cfa3270e..5ff069eff3153831d36ca861ff350ce5cbe5cbdf 100644 (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;
index 58d77e100f4a56e38cac74c87fad8136aea390ff..232e1dca05bb638550b8c0fad45becdc12e84937 100644 (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)
 {
index 713eccd1bdc2fa3995db51de6cecbbfe16918358..638e111beaff6cc930b83897a21681f703f7704b 100644 (file)
--- a/src/xdg.c
+++ b/src/xdg.c
@@ -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 *
index 0c44b7c768b89a7eb8a8509da149564f28aaa038..86f7a1ae87ac1cb4848cd93cb0ab336b222d4c98 100644 (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