]> git.mdlowis.com Git - proto/labwc.git/commitdiff
action: add WarpCursor action
authorOrfeas <38209077+0xfea5@users.noreply.github.com>
Sun, 22 Dec 2024 12:48:47 +0000 (14:48 +0200)
committerJohan Malm <johanmalm@users.noreply.github.com>
Thu, 26 Dec 2024 10:27:02 +0000 (10:27 +0000)
docs/labwc-actions.5.scd
include/labwc.h
src/action.c

index bc9929b92fd9150850a37856cf16d20757300913..f406b887af67d6100d8e933ffd13f2a62562fc47 100644 (file)
@@ -340,6 +340,19 @@ Actions are used in menus and keyboard/mouse bindings.
        decorations (including those for which the server-side titlebar has been
        hidden) are not eligible for shading.
 
+*<action name="WarpCursor" to="output" x="center" y="center" />*
+       Warp the cursor to a position relative to the active output or window.
+
+       *to* [output|window] Specifies the target area of the warp.
+       Default is "output"
+       *x* [center|value] Specifies the horizontal warp position within the target area.
+       "center": Moves the cursor to the horizontal center of the target area.
+       Positive or negative integers warp the cursor to a position offset by the specified
+       number of pixels from the left or right edge of the target area respectively.
+       Default is "center"
+       *y* [center|value] Equivalent for the vertical warp position within the target area.
+       Default is "center"
+
 *<action name="EnableTabletMouseEmulation" />*++
 *<action name="DisableTabletMouseEmulation" />*++
 *<action name="ToggleTabletMouseEmulation">*
index 6e5d7fdd164770d73328b5c33cdfcf01f7022580..f8c46637c49af042a6cc1e0c559f78ad07aa3071 100644 (file)
@@ -458,7 +458,6 @@ void desktop_focus_view_or_surface(struct seat *seat, struct view *view,
 
 void desktop_arrange_all_views(struct server *server);
 void desktop_focus_output(struct output *output);
-void warp_cursor(struct view *view);
 struct view *desktop_topmost_focusable_view(struct server *server);
 
 /**
index ce4f077f041e86b7b0336a4fd1267201e14f7a41..2a789b2ca9249dcfef18b12575d4eb58a9216d66 100644 (file)
@@ -121,7 +121,8 @@ enum action_type {
        ACTION_TYPE_TOGGLE_TABLET_MOUSE_EMULATION,
        ACTION_TYPE_TOGGLE_MAGNIFY,
        ACTION_TYPE_ZOOM_IN,
-       ACTION_TYPE_ZOOM_OUT
+       ACTION_TYPE_ZOOM_OUT,
+       ACTION_TYPE_WARP_CURSOR,
 };
 
 const char *action_names[] = {
@@ -186,6 +187,7 @@ const char *action_names[] = {
        "ToggleMagnify",
        "ZoomIn",
        "ZoomOut",
+       "WarpCursor",
        NULL
 };
 
@@ -475,6 +477,12 @@ action_arg_from_xml_node(struct action *action, const char *nodename, const char
                        goto cleanup;
                }
                break;
+       case ACTION_TYPE_WARP_CURSOR:
+               if (!strcmp(argument, "to") || !strcmp(argument, "x") || !strcmp(argument, "y")) {
+                       action_arg_add_str(action, argument, content);
+                       goto cleanup;
+               }
+               break;
        }
 
        wlr_log(WLR_ERROR, "Invalid argument for action %s: '%s'",
@@ -824,6 +832,43 @@ get_target_output(struct output *output, struct server *server,
        return target;
 }
 
+static void
+warp_cursor(struct view *view, struct output *output, const char *to, const char *x, const char *y)
+{
+       struct wlr_box target_area = {0};
+       int goto_x;
+       int goto_y;
+
+       if (!strcasecmp(to, "output") && output) {
+               target_area = output_usable_area_in_layout_coords(output);
+       } else if (!strcasecmp(to, "window") && view) {
+               target_area = view->current;
+       } else {
+               wlr_log(WLR_ERROR, "Invalid argument for action WarpCursor: 'to' (%s)", to);
+       }
+
+       if (!strcasecmp(x, "center")) {
+               goto_x = target_area.x + target_area.width / 2;
+       } else {
+               int offset_x = atoi(x);
+               goto_x = offset_x >= 0 ?
+                       target_area.x + offset_x :
+                       target_area.x + target_area.width + offset_x;
+       }
+
+       if (!strcasecmp(y, "center")) {
+               goto_y = target_area.y + target_area.height / 2;
+       } else {
+               int offset_y = atoi(y);
+               goto_y = offset_y >= 0 ?
+                       target_area.y + offset_y :
+                       target_area.y + target_area.height + offset_y;
+       }
+
+       wlr_cursor_warp(output->server->seat.cursor, NULL, goto_x, goto_y);
+       cursor_update_focus(output->server);
+}
+
 void
 actions_run(struct view *activator, struct server *server,
        struct wl_list *actions, struct cursor_context *cursor_ctx)
@@ -1287,6 +1332,16 @@ actions_run(struct view *activator, struct server *server,
                case ACTION_TYPE_ZOOM_OUT:
                        magnify_set_scale(server, MAGNIFY_DECREASE);
                        break;
+               case ACTION_TYPE_WARP_CURSOR:
+                       {
+                               const char *to = action_get_str(action, "to", "output");
+                               const char *x = action_get_str(action, "x", "center");
+                               const char *y = action_get_str(action, "y", "center");
+                               struct output *output = output_nearest_to_cursor(server);
+
+                               warp_cursor(view, output, to, x, y);
+                       }
+                       break;
                case ACTION_TYPE_INVALID:
                        wlr_log(WLR_ERROR, "Not executing unknown action");
                        break;