2021-09-24 21:45:48 +01:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-only
|
2022-06-21 18:48:05 +02:00
|
|
|
#define _POSIX_C_SOURCE 200809L
|
2022-06-10 19:42:34 +02:00
|
|
|
#include <assert.h>
|
2022-06-21 18:48:05 +02:00
|
|
|
#include <signal.h>
|
2022-06-10 19:42:34 +02:00
|
|
|
#include <string.h>
|
2020-09-25 19:42:40 +01:00
|
|
|
#include <strings.h>
|
2022-06-21 18:48:05 +02:00
|
|
|
#include <unistd.h>
|
2021-07-23 21:15:55 +01:00
|
|
|
#include <wlr/util/log.h>
|
2022-11-22 11:59:54 -05:00
|
|
|
#include "action.h"
|
2022-10-05 08:43:56 +02:00
|
|
|
#include "common/list.h"
|
2022-09-16 18:41:02 -04:00
|
|
|
#include "common/mem.h"
|
2020-09-28 20:41:41 +01:00
|
|
|
#include "common/spawn.h"
|
2022-02-12 19:43:32 +00:00
|
|
|
#include "debug.h"
|
2020-09-25 20:05:20 +01:00
|
|
|
#include "labwc.h"
|
2020-10-31 15:27:22 +00:00
|
|
|
#include "menu/menu.h"
|
2022-01-26 02:54:03 +01:00
|
|
|
#include "ssd.h"
|
2022-11-21 10:10:39 -05:00
|
|
|
#include "view.h"
|
2022-06-15 01:38:22 +02:00
|
|
|
#include "workspaces.h"
|
2022-01-05 09:11:24 +01:00
|
|
|
|
2022-11-22 11:59:54 -05:00
|
|
|
enum action_arg_type {
|
|
|
|
|
LAB_ACTION_ARG_STR = 0,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct action_arg {
|
|
|
|
|
struct wl_list link; /* struct action.args */
|
|
|
|
|
|
|
|
|
|
char *key; /* May be NULL if there is just one arg */
|
|
|
|
|
enum action_arg_type type;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct action_arg_str {
|
|
|
|
|
struct action_arg base;
|
|
|
|
|
char *value;
|
|
|
|
|
};
|
|
|
|
|
|
2022-01-05 09:11:24 +01:00
|
|
|
enum action_type {
|
2022-09-06 13:22:43 -04:00
|
|
|
ACTION_TYPE_INVALID = 0,
|
|
|
|
|
ACTION_TYPE_NONE,
|
2022-01-05 09:11:24 +01:00
|
|
|
ACTION_TYPE_CLOSE,
|
|
|
|
|
ACTION_TYPE_DEBUG,
|
|
|
|
|
ACTION_TYPE_EXECUTE,
|
|
|
|
|
ACTION_TYPE_EXIT,
|
|
|
|
|
ACTION_TYPE_MOVE_TO_EDGE,
|
|
|
|
|
ACTION_TYPE_SNAP_TO_EDGE,
|
|
|
|
|
ACTION_TYPE_NEXT_WINDOW,
|
|
|
|
|
ACTION_TYPE_PREVIOUS_WINDOW,
|
|
|
|
|
ACTION_TYPE_RECONFIGURE,
|
|
|
|
|
ACTION_TYPE_SHOW_MENU,
|
|
|
|
|
ACTION_TYPE_TOGGLE_MAXIMIZE,
|
|
|
|
|
ACTION_TYPE_TOGGLE_FULLSCREEN,
|
|
|
|
|
ACTION_TYPE_TOGGLE_DECORATIONS,
|
2022-04-09 01:16:09 +02:00
|
|
|
ACTION_TYPE_TOGGLE_ALWAYS_ON_TOP,
|
2022-01-05 09:11:24 +01:00
|
|
|
ACTION_TYPE_FOCUS,
|
|
|
|
|
ACTION_TYPE_ICONIFY,
|
|
|
|
|
ACTION_TYPE_MOVE,
|
|
|
|
|
ACTION_TYPE_RAISE,
|
|
|
|
|
ACTION_TYPE_RESIZE,
|
2022-06-15 01:38:22 +02:00
|
|
|
ACTION_TYPE_GO_TO_DESKTOP,
|
|
|
|
|
ACTION_TYPE_SEND_TO_DESKTOP,
|
2022-01-05 09:11:24 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const char *action_names[] = {
|
2022-09-06 13:22:43 -04:00
|
|
|
"INVALID",
|
|
|
|
|
"None",
|
2022-01-05 09:11:24 +01:00
|
|
|
"Close",
|
|
|
|
|
"Debug",
|
|
|
|
|
"Execute",
|
|
|
|
|
"Exit",
|
|
|
|
|
"MoveToEdge",
|
|
|
|
|
"SnapToEdge",
|
|
|
|
|
"NextWindow",
|
|
|
|
|
"PreviousWindow",
|
|
|
|
|
"Reconfigure",
|
|
|
|
|
"ShowMenu",
|
|
|
|
|
"ToggleMaximize",
|
|
|
|
|
"ToggleFullscreen",
|
|
|
|
|
"ToggleDecorations",
|
2022-04-09 01:16:09 +02:00
|
|
|
"ToggleAlwaysOnTop",
|
2022-01-05 09:11:24 +01:00
|
|
|
"Focus",
|
|
|
|
|
"Iconify",
|
|
|
|
|
"Move",
|
|
|
|
|
"Raise",
|
|
|
|
|
"Resize",
|
2022-06-15 01:38:22 +02:00
|
|
|
"GoToDesktop",
|
|
|
|
|
"SendToDesktop",
|
2022-01-05 09:11:24 +01:00
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
2022-06-10 19:42:34 +02:00
|
|
|
static char *
|
|
|
|
|
action_str_from_arg(struct action_arg *arg)
|
|
|
|
|
{
|
|
|
|
|
assert(arg->type == LAB_ACTION_ARG_STR);
|
|
|
|
|
return ((struct action_arg_str *)arg)->value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static struct action_arg *
|
|
|
|
|
action_get_first_arg(struct action *action)
|
|
|
|
|
{
|
|
|
|
|
struct action_arg *arg;
|
|
|
|
|
struct wl_list *item = action->args.next;
|
|
|
|
|
if (item == &action->args) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
return wl_container_of(item, arg, link);
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-05 09:11:24 +01:00
|
|
|
static enum action_type
|
|
|
|
|
action_type_from_str(const char *action_name)
|
|
|
|
|
{
|
2022-04-04 20:53:36 +01:00
|
|
|
for (size_t i = 1; action_names[i]; i++) {
|
2022-01-05 09:11:24 +01:00
|
|
|
if (!strcasecmp(action_name, action_names[i])) {
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
wlr_log(WLR_ERROR, "Invalid action: %s", action_name);
|
2022-09-06 13:22:43 -04:00
|
|
|
return ACTION_TYPE_INVALID;
|
2022-01-05 09:11:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct action *
|
|
|
|
|
action_create(const char *action_name)
|
|
|
|
|
{
|
|
|
|
|
if (!action_name) {
|
|
|
|
|
wlr_log(WLR_ERROR, "action name not specified");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
2022-09-18 15:22:26 -04:00
|
|
|
struct action *action = znew(*action);
|
2022-01-05 09:11:24 +01:00
|
|
|
action->type = action_type_from_str(action_name);
|
2022-06-10 19:42:34 +02:00
|
|
|
wl_list_init(&action->args);
|
2022-01-05 09:11:24 +01:00
|
|
|
return action;
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-24 02:33:17 +01:00
|
|
|
void action_list_free(struct wl_list *action_list)
|
|
|
|
|
{
|
2022-06-10 19:42:34 +02:00
|
|
|
struct action_arg *arg, *arg_tmp;
|
2022-01-23 13:46:46 +01:00
|
|
|
struct action *action, *action_tmp;
|
2022-06-10 19:42:34 +02:00
|
|
|
/* Free actions */
|
2022-01-23 13:46:46 +01:00
|
|
|
wl_list_for_each_safe(action, action_tmp, action_list, link) {
|
|
|
|
|
wl_list_remove(&action->link);
|
2022-06-10 19:42:34 +02:00
|
|
|
/* Free args */
|
|
|
|
|
wl_list_for_each_safe(arg, arg_tmp, &action->args, link) {
|
|
|
|
|
wl_list_remove(&arg->link);
|
|
|
|
|
zfree(arg->key);
|
|
|
|
|
if (arg->type == LAB_ACTION_ARG_STR) {
|
|
|
|
|
free(action_str_from_arg(arg));
|
|
|
|
|
}
|
|
|
|
|
zfree(arg);
|
|
|
|
|
}
|
2022-01-23 13:46:46 +01:00
|
|
|
zfree(action);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-31 15:27:22 +00:00
|
|
|
static void
|
2022-01-26 00:07:10 +01:00
|
|
|
show_menu(struct server *server, struct view *view, const char *menu_name)
|
2020-10-31 15:27:22 +00:00
|
|
|
{
|
2022-01-26 00:07:10 +01:00
|
|
|
bool force_menu_top_left = false;
|
2022-02-19 02:05:38 +01:00
|
|
|
struct menu *menu = menu_get_by_id(menu_name);
|
|
|
|
|
if (!menu) {
|
2022-01-26 00:07:10 +01:00
|
|
|
return;
|
|
|
|
|
}
|
2022-02-19 02:05:38 +01:00
|
|
|
if (!strcasecmp(menu_name, "client-menu")) {
|
|
|
|
|
if (!view) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-01-26 02:54:03 +01:00
|
|
|
enum ssd_part_type type = ssd_at(view, server->seat.cursor->x,
|
|
|
|
|
server->seat.cursor->y);
|
|
|
|
|
if (type == LAB_SSD_BUTTON_WINDOW_MENU) {
|
|
|
|
|
force_menu_top_left = true;
|
|
|
|
|
} else if (ssd_part_contains(LAB_SSD_PART_TITLEBAR, type)) {
|
|
|
|
|
force_menu_top_left = false;
|
|
|
|
|
} else {
|
|
|
|
|
force_menu_top_left = true;
|
|
|
|
|
}
|
2020-10-31 15:27:22 +00:00
|
|
|
}
|
2022-01-26 00:07:10 +01:00
|
|
|
|
|
|
|
|
int x, y;
|
|
|
|
|
if (force_menu_top_left) {
|
|
|
|
|
x = view->x;
|
|
|
|
|
y = view->y;
|
|
|
|
|
} else {
|
|
|
|
|
x = server->seat.cursor->x;
|
|
|
|
|
y = server->seat.cursor->y;
|
2020-10-31 15:27:22 +00:00
|
|
|
}
|
2022-06-09 17:10:36 +02:00
|
|
|
/* Replaced by next show_menu() or cleaned on view_destroy() */
|
|
|
|
|
menu->triggered_by_view = view;
|
2022-02-19 02:05:38 +01:00
|
|
|
menu_open(menu, x, y);
|
2020-10-31 15:27:22 +00:00
|
|
|
}
|
2020-06-18 20:18:01 +01:00
|
|
|
|
2021-12-03 16:37:53 +00:00
|
|
|
static struct view *
|
2022-09-14 23:09:36 -04:00
|
|
|
view_for_action(struct view *activator, struct server *server,
|
2022-09-15 08:31:37 -04:00
|
|
|
struct action *action, uint32_t *resize_edges)
|
2021-12-03 16:37:53 +00:00
|
|
|
{
|
2022-09-14 23:09:36 -04:00
|
|
|
/* View is explicitly specified for mousebinds */
|
|
|
|
|
if (activator) {
|
|
|
|
|
return activator;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Select view based on action type for keybinds */
|
|
|
|
|
switch (action->type) {
|
|
|
|
|
case ACTION_TYPE_FOCUS:
|
|
|
|
|
case ACTION_TYPE_MOVE:
|
2022-09-15 08:31:37 -04:00
|
|
|
case ACTION_TYPE_RESIZE: {
|
|
|
|
|
struct cursor_context ctx = get_cursor_context(server);
|
|
|
|
|
if (action->type == ACTION_TYPE_RESIZE) {
|
|
|
|
|
/* Select resize edges for the keybind case */
|
|
|
|
|
*resize_edges = cursor_get_resize_edges(
|
|
|
|
|
server->seat.cursor, &ctx);
|
|
|
|
|
}
|
|
|
|
|
return ctx.view;
|
|
|
|
|
}
|
2022-09-14 23:09:36 -04:00
|
|
|
default:
|
|
|
|
|
return desktop_focused_view(server);
|
|
|
|
|
}
|
2021-12-03 16:37:53 +00:00
|
|
|
}
|
|
|
|
|
|
2020-09-28 20:41:41 +01:00
|
|
|
void
|
2022-02-24 02:16:19 +01:00
|
|
|
actions_run(struct view *activator, struct server *server,
|
|
|
|
|
struct wl_list *actions, uint32_t resize_edges)
|
2020-06-18 20:18:01 +01:00
|
|
|
{
|
2022-01-05 09:11:24 +01:00
|
|
|
if (!actions) {
|
|
|
|
|
wlr_log(WLR_ERROR, "empty actions");
|
2020-06-18 20:18:01 +01:00
|
|
|
return;
|
2022-01-05 09:11:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct view *view;
|
|
|
|
|
struct action *action;
|
2022-06-10 19:42:34 +02:00
|
|
|
struct action_arg *arg;
|
2022-01-05 09:11:24 +01:00
|
|
|
wl_list_for_each(action, actions, link) {
|
2022-06-10 19:42:34 +02:00
|
|
|
wlr_log(WLR_DEBUG, "Handling action %s (%u)",
|
|
|
|
|
action_names[action->type], action->type);
|
|
|
|
|
|
|
|
|
|
/* Get arg now so we don't have to repeat every time we only need one */
|
|
|
|
|
arg = action_get_first_arg(action);
|
2022-01-05 09:11:24 +01:00
|
|
|
|
2022-04-04 20:53:36 +01:00
|
|
|
/*
|
|
|
|
|
* Refetch view because it may have been changed due to the
|
|
|
|
|
* previous action
|
|
|
|
|
*/
|
2022-09-15 08:31:37 -04:00
|
|
|
view = view_for_action(activator, server, action,
|
|
|
|
|
&resize_edges);
|
2022-01-05 09:11:24 +01:00
|
|
|
|
2022-01-05 21:23:01 +00:00
|
|
|
switch (action->type) {
|
|
|
|
|
case ACTION_TYPE_CLOSE:
|
2022-01-05 09:11:24 +01:00
|
|
|
if (view) {
|
|
|
|
|
view_close(view);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
case ACTION_TYPE_DEBUG:
|
2022-02-12 19:43:32 +00:00
|
|
|
debug_dump_scene(server);
|
2022-01-05 09:11:24 +01:00
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
case ACTION_TYPE_EXECUTE:
|
2022-06-10 19:42:34 +02:00
|
|
|
if (!arg) {
|
|
|
|
|
wlr_log(WLR_ERROR, "Missing argument for Execute");
|
|
|
|
|
break;
|
2022-01-05 09:11:24 +01:00
|
|
|
}
|
2022-06-10 19:42:34 +02:00
|
|
|
struct buf cmd;
|
|
|
|
|
buf_init(&cmd);
|
|
|
|
|
buf_add(&cmd, action_str_from_arg(arg));
|
|
|
|
|
buf_expand_shell_variables(&cmd);
|
|
|
|
|
spawn_async_no_shell(cmd.buf);
|
|
|
|
|
free(cmd.buf);
|
2022-01-05 09:11:24 +01:00
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
case ACTION_TYPE_EXIT:
|
2022-01-05 09:11:24 +01:00
|
|
|
wl_display_terminate(server->wl_display);
|
|
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
case ACTION_TYPE_MOVE_TO_EDGE:
|
2022-11-22 02:09:42 -05:00
|
|
|
if (!arg) {
|
2022-06-03 02:19:31 +02:00
|
|
|
wlr_log(WLR_ERROR, "Missing argument for MoveToEdge");
|
2022-11-22 02:09:42 -05:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (view) {
|
|
|
|
|
view_move_to_edge(view, action_str_from_arg(arg));
|
2022-06-03 02:19:31 +02:00
|
|
|
}
|
2022-01-05 09:11:24 +01:00
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
case ACTION_TYPE_SNAP_TO_EDGE:
|
2022-11-22 02:09:42 -05:00
|
|
|
if (!arg) {
|
|
|
|
|
wlr_log(WLR_ERROR, "Missing argument for SnapToEdge");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
if (view) {
|
2022-11-19 12:58:52 -05:00
|
|
|
view_snap_to_edge(view, action_str_from_arg(arg),
|
|
|
|
|
/*store_natural_geometry*/ true);
|
2022-06-03 02:19:31 +02:00
|
|
|
}
|
2022-01-05 09:11:24 +01:00
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
case ACTION_TYPE_NEXT_WINDOW:
|
2022-04-26 22:06:22 +02:00
|
|
|
server->osd_state.cycle_view = desktop_cycle_view(server,
|
|
|
|
|
server->osd_state.cycle_view, LAB_CYCLE_DIR_FORWARD);
|
2022-01-05 09:11:24 +01:00
|
|
|
osd_update(server);
|
|
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
case ACTION_TYPE_PREVIOUS_WINDOW:
|
2022-04-26 22:06:22 +02:00
|
|
|
server->osd_state.cycle_view = desktop_cycle_view(server,
|
|
|
|
|
server->osd_state.cycle_view, LAB_CYCLE_DIR_BACKWARD);
|
2022-01-05 09:11:24 +01:00
|
|
|
osd_update(server);
|
|
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
case ACTION_TYPE_RECONFIGURE:
|
2022-06-14 22:45:45 +01:00
|
|
|
kill(getpid(), SIGHUP);
|
2022-01-05 09:11:24 +01:00
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
case ACTION_TYPE_SHOW_MENU:
|
2022-06-10 19:42:34 +02:00
|
|
|
if (arg) {
|
|
|
|
|
show_menu(server, view, action_str_from_arg(arg));
|
|
|
|
|
} else {
|
|
|
|
|
wlr_log(WLR_ERROR, "Missing argument for ShowMenu");
|
|
|
|
|
}
|
2022-01-05 09:11:24 +01:00
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
case ACTION_TYPE_TOGGLE_MAXIMIZE:
|
2022-01-05 09:11:24 +01:00
|
|
|
if (view) {
|
|
|
|
|
view_toggle_maximize(view);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
case ACTION_TYPE_TOGGLE_FULLSCREEN:
|
2022-01-05 09:11:24 +01:00
|
|
|
if (view) {
|
|
|
|
|
view_toggle_fullscreen(view);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
case ACTION_TYPE_TOGGLE_DECORATIONS:
|
2022-01-05 09:11:24 +01:00
|
|
|
if (view) {
|
|
|
|
|
view_toggle_decorations(view);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2022-04-09 01:16:09 +02:00
|
|
|
case ACTION_TYPE_TOGGLE_ALWAYS_ON_TOP:
|
|
|
|
|
if (view) {
|
|
|
|
|
view_toggle_always_on_top(view);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
case ACTION_TYPE_FOCUS:
|
2022-01-05 09:11:24 +01:00
|
|
|
if (view) {
|
|
|
|
|
desktop_focus_and_activate_view(&server->seat, view);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
case ACTION_TYPE_ICONIFY:
|
2022-01-05 09:11:24 +01:00
|
|
|
if (view) {
|
|
|
|
|
view_minimize(view, true);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
case ACTION_TYPE_MOVE:
|
2022-01-05 09:11:24 +01:00
|
|
|
if (view) {
|
|
|
|
|
interactive_begin(view, LAB_INPUT_STATE_MOVE, 0);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
case ACTION_TYPE_RAISE:
|
2022-01-05 09:11:24 +01:00
|
|
|
if (view) {
|
|
|
|
|
desktop_move_to_front(view);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
case ACTION_TYPE_RESIZE:
|
2022-01-05 09:11:24 +01:00
|
|
|
if (view) {
|
2022-04-04 20:53:36 +01:00
|
|
|
interactive_begin(view, LAB_INPUT_STATE_RESIZE,
|
|
|
|
|
resize_edges);
|
2022-01-05 09:11:24 +01:00
|
|
|
}
|
|
|
|
|
break;
|
2022-06-15 01:38:22 +02:00
|
|
|
case ACTION_TYPE_GO_TO_DESKTOP:
|
2022-06-10 19:42:34 +02:00
|
|
|
if (!arg) {
|
|
|
|
|
wlr_log(WLR_ERROR, "Missing argument for GoToDesktop");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
struct workspace *target;
|
|
|
|
|
char *target_name = action_str_from_arg(arg);
|
|
|
|
|
target = workspaces_find(server->workspace_current, target_name);
|
|
|
|
|
if (target) {
|
|
|
|
|
workspaces_switch_to(target);
|
2022-06-15 01:38:22 +02:00
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case ACTION_TYPE_SEND_TO_DESKTOP:
|
2022-06-10 19:42:34 +02:00
|
|
|
if (!arg) {
|
|
|
|
|
wlr_log(WLR_ERROR, "Missing argument for SendToDesktop");
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-06-15 01:38:22 +02:00
|
|
|
if (view) {
|
|
|
|
|
struct workspace *target;
|
2022-06-10 19:42:34 +02:00
|
|
|
char *target_name = action_str_from_arg(arg);
|
|
|
|
|
target = workspaces_find(view->workspace, target_name);
|
2022-06-15 01:38:22 +02:00
|
|
|
if (target) {
|
2022-11-21 13:03:49 -05:00
|
|
|
view_move_to_workspace(view, target);
|
2022-06-15 01:38:22 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
case ACTION_TYPE_NONE:
|
2022-09-06 13:22:43 -04:00
|
|
|
break;
|
|
|
|
|
case ACTION_TYPE_INVALID:
|
2022-06-10 19:42:34 +02:00
|
|
|
wlr_log(WLR_ERROR, "Not executing unknown action");
|
2022-01-05 09:11:24 +01:00
|
|
|
break;
|
2022-01-05 21:23:01 +00:00
|
|
|
default:
|
2022-01-05 09:11:24 +01:00
|
|
|
/*
|
|
|
|
|
* If we get here it must be a BUG caused most likely by
|
|
|
|
|
* action_names and action_type being out of sync or by
|
|
|
|
|
* adding a new action without installing a handler here.
|
|
|
|
|
*/
|
2022-04-04 20:53:36 +01:00
|
|
|
wlr_log(WLR_ERROR,
|
2022-06-10 19:42:34 +02:00
|
|
|
"Not executing invalid action (%u)"
|
|
|
|
|
" This is a BUG. Please report.", action->type);
|
2021-12-01 02:38:53 +00:00
|
|
|
}
|
2020-06-18 20:18:01 +01:00
|
|
|
}
|
|
|
|
|
}
|
2022-06-10 19:42:34 +02:00
|
|
|
|
|
|
|
|
void
|
|
|
|
|
action_arg_add_str(struct action *action, char *key, const char *value)
|
|
|
|
|
{
|
|
|
|
|
assert(value && "Tried to add NULL action string argument");
|
2022-09-18 15:22:26 -04:00
|
|
|
struct action_arg_str *arg = znew(*arg);
|
2022-06-10 19:42:34 +02:00
|
|
|
arg->base.type = LAB_ACTION_ARG_STR;
|
|
|
|
|
if (key) {
|
2022-09-16 18:41:02 -04:00
|
|
|
arg->base.key = xstrdup(key);
|
2022-06-10 19:42:34 +02:00
|
|
|
}
|
2022-09-16 18:41:02 -04:00
|
|
|
arg->value = xstrdup(value);
|
2022-10-05 08:43:56 +02:00
|
|
|
wl_list_append(&action->args, &arg->base.link);
|
2022-06-10 19:42:34 +02:00
|
|
|
}
|