mirror of
https://github.com/labwc/labwc.git
synced 2026-03-20 05:34:12 -04:00
Rewrite action handling to allow multiple actions at once
This commit is contained in:
parent
a54ce40e1c
commit
0b45cce648
12 changed files with 276 additions and 140 deletions
264
src/action.c
264
src/action.c
|
|
@ -4,6 +4,78 @@
|
|||
#include "common/spawn.h"
|
||||
#include "labwc.h"
|
||||
#include "menu/menu.h"
|
||||
#include "action.h"
|
||||
|
||||
enum action_type {
|
||||
ACTION_TYPE_NONE = 0,
|
||||
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,
|
||||
ACTION_TYPE_FOCUS,
|
||||
ACTION_TYPE_ICONIFY,
|
||||
ACTION_TYPE_MOVE,
|
||||
ACTION_TYPE_RAISE,
|
||||
ACTION_TYPE_RESIZE,
|
||||
};
|
||||
|
||||
const char *action_names[] = {
|
||||
"NoOp",
|
||||
"Close",
|
||||
"Debug",
|
||||
"Execute",
|
||||
"Exit",
|
||||
"MoveToEdge",
|
||||
"SnapToEdge",
|
||||
"NextWindow",
|
||||
"PreviousWindow",
|
||||
"Reconfigure",
|
||||
"ShowMenu",
|
||||
"ToggleMaximize",
|
||||
"ToggleFullscreen",
|
||||
"ToggleDecorations",
|
||||
"Focus",
|
||||
"Iconify",
|
||||
"Move",
|
||||
"Raise",
|
||||
"Resize",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
static enum action_type
|
||||
action_type_from_str(const char *action_name)
|
||||
{
|
||||
for (size_t i=1; action_names[i] != NULL; i++) {
|
||||
if (!strcasecmp(action_name, action_names[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
wlr_log(WLR_ERROR, "Invalid action: %s", action_name);
|
||||
return ACTION_TYPE_NONE;
|
||||
}
|
||||
|
||||
struct action *
|
||||
action_create(const char *action_name)
|
||||
{
|
||||
if (!action_name) {
|
||||
wlr_log(WLR_ERROR, "action name not specified");
|
||||
return NULL;
|
||||
}
|
||||
struct action *action = calloc(1, sizeof(struct action));
|
||||
action->type = action_type_from_str(action_name);
|
||||
return action;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
show_menu(struct server *server, const char *menu)
|
||||
|
|
@ -26,85 +98,123 @@ activator_or_focused_view(struct view *activator, struct server *server)
|
|||
}
|
||||
|
||||
void
|
||||
action(struct view *activator, struct server *server, const char *action, const char *command, uint32_t resize_edges)
|
||||
action(struct view *activator, struct server *server, struct wl_list *actions, uint32_t resize_edges)
|
||||
{
|
||||
if (!action)
|
||||
if (!actions) {
|
||||
wlr_log(WLR_ERROR, "empty actions");
|
||||
return;
|
||||
if (!strcasecmp(action, "Close")) {
|
||||
struct view *view = activator_or_focused_view(activator, server);
|
||||
if (view) {
|
||||
view_close(view);
|
||||
}
|
||||
|
||||
struct view *view;
|
||||
struct action *action;
|
||||
wl_list_for_each(action, actions, link) {
|
||||
wlr_log(WLR_DEBUG, "Handling action %s (%u) with arg %s",
|
||||
action_names[action->type], action->type, action->arg);
|
||||
|
||||
/* Refetch view because it may have been changed due to the previous action */
|
||||
view = activator_or_focused_view(activator, server);
|
||||
|
||||
switch(action->type) {
|
||||
case ACTION_TYPE_CLOSE:;
|
||||
if (view) {
|
||||
view_close(view);
|
||||
}
|
||||
break;
|
||||
case ACTION_TYPE_DEBUG:;
|
||||
/* nothing */
|
||||
break;
|
||||
case ACTION_TYPE_EXECUTE:;
|
||||
{
|
||||
struct buf cmd;
|
||||
buf_init(&cmd);
|
||||
buf_add(&cmd, action->arg);
|
||||
buf_expand_shell_variables(&cmd);
|
||||
spawn_async_no_shell(cmd.buf);
|
||||
free(cmd.buf);
|
||||
}
|
||||
break;
|
||||
case ACTION_TYPE_EXIT:;
|
||||
wl_display_terminate(server->wl_display);
|
||||
break;
|
||||
case ACTION_TYPE_MOVE_TO_EDGE:;
|
||||
view_move_to_edge(view, action->arg);
|
||||
break;
|
||||
case ACTION_TYPE_SNAP_TO_EDGE:;
|
||||
view_snap_to_edge(view, action->arg);
|
||||
break;
|
||||
case ACTION_TYPE_NEXT_WINDOW:;
|
||||
server->cycle_view =
|
||||
desktop_cycle_view(server, server->cycle_view, LAB_CYCLE_DIR_FORWARD);
|
||||
osd_update(server);
|
||||
break;
|
||||
case ACTION_TYPE_PREVIOUS_WINDOW:;
|
||||
server->cycle_view =
|
||||
desktop_cycle_view(server, server->cycle_view, LAB_CYCLE_DIR_BACKWARD);
|
||||
osd_update(server);
|
||||
break;
|
||||
case ACTION_TYPE_RECONFIGURE:;
|
||||
/* Should be changed to signal() */
|
||||
spawn_async_no_shell("killall -SIGHUP labwc");
|
||||
break;
|
||||
case ACTION_TYPE_SHOW_MENU:;
|
||||
show_menu(server, action->arg);
|
||||
break;
|
||||
case ACTION_TYPE_TOGGLE_MAXIMIZE:;
|
||||
if (view) {
|
||||
view_toggle_maximize(view);
|
||||
}
|
||||
break;
|
||||
case ACTION_TYPE_TOGGLE_FULLSCREEN:;
|
||||
if (view) {
|
||||
view_toggle_fullscreen(view);
|
||||
}
|
||||
break;
|
||||
case ACTION_TYPE_TOGGLE_DECORATIONS:;
|
||||
if (view) {
|
||||
view_toggle_decorations(view);
|
||||
}
|
||||
break;
|
||||
case ACTION_TYPE_FOCUS:;
|
||||
view = desktop_view_at_cursor(server);
|
||||
if (view) {
|
||||
desktop_focus_and_activate_view(&server->seat, view);
|
||||
damage_all_outputs(server);
|
||||
}
|
||||
break;
|
||||
case ACTION_TYPE_ICONIFY:;
|
||||
if (view) {
|
||||
view_minimize(view, true);
|
||||
}
|
||||
break;
|
||||
case ACTION_TYPE_MOVE:;
|
||||
view = desktop_view_at_cursor(server);
|
||||
if (view) {
|
||||
interactive_begin(view, LAB_INPUT_STATE_MOVE, 0);
|
||||
}
|
||||
break;
|
||||
case ACTION_TYPE_RAISE:;
|
||||
if (view) {
|
||||
desktop_move_to_front(view);
|
||||
damage_all_outputs(server);
|
||||
}
|
||||
break;
|
||||
case ACTION_TYPE_RESIZE:;
|
||||
view = desktop_view_at_cursor(server);
|
||||
if (view) {
|
||||
interactive_begin(view, LAB_INPUT_STATE_RESIZE, resize_edges);
|
||||
}
|
||||
break;
|
||||
case ACTION_TYPE_NONE:;
|
||||
wlr_log(WLR_ERROR, "Not executing unknown action with arg %s", action->arg);
|
||||
break;
|
||||
default:;
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
wlr_log(WLR_ERROR, "Not executing invalid action (%u) with arg %s"
|
||||
"This is a BUG. Please report.", action->type, action->arg);
|
||||
}
|
||||
} else if (!strcasecmp(action, "Debug")) {
|
||||
/* nothing */
|
||||
} else if (!strcasecmp(action, "Execute")) {
|
||||
struct buf cmd;
|
||||
buf_init(&cmd);
|
||||
buf_add(&cmd, command);
|
||||
buf_expand_shell_variables(&cmd);
|
||||
spawn_async_no_shell(cmd.buf);
|
||||
free(cmd.buf);
|
||||
} else if (!strcasecmp(action, "Exit")) {
|
||||
wl_display_terminate(server->wl_display);
|
||||
} else if (!strcasecmp(action, "MoveToEdge")) {
|
||||
view_move_to_edge(activator_or_focused_view(activator, server), command);
|
||||
} else if (!strcasecmp(action, "SnapToEdge")) {
|
||||
view_snap_to_edge(activator_or_focused_view(activator, server), command);
|
||||
} else if (!strcasecmp(action, "NextWindow")) {
|
||||
server->cycle_view =
|
||||
desktop_cycle_view(server, server->cycle_view, LAB_CYCLE_DIR_FORWARD);
|
||||
osd_update(server);
|
||||
} else if (!strcasecmp(action, "PreviousWindow")) {
|
||||
server->cycle_view =
|
||||
desktop_cycle_view(server, server->cycle_view, LAB_CYCLE_DIR_BACKWARD);
|
||||
osd_update(server);
|
||||
} else if (!strcasecmp(action, "Reconfigure")) {
|
||||
spawn_async_no_shell("killall -SIGHUP labwc");
|
||||
} else if (!strcasecmp(action, "ShowMenu")) {
|
||||
show_menu(server, command);
|
||||
} else if (!strcasecmp(action, "ToggleMaximize")) {
|
||||
struct view *view = activator_or_focused_view(activator, server);
|
||||
if (view) {
|
||||
view_toggle_maximize(view);
|
||||
}
|
||||
} else if (!strcasecmp(action, "ToggleFullscreen")) {
|
||||
struct view *view = activator_or_focused_view(activator, server);
|
||||
if (view) {
|
||||
view_toggle_fullscreen(view);
|
||||
}
|
||||
} else if (!strcasecmp(action, "ToggleDecorations")) {
|
||||
struct view *view = activator_or_focused_view(activator, server);
|
||||
if (view) {
|
||||
view_toggle_decorations(view);
|
||||
}
|
||||
} else if (!strcasecmp(action, "Focus")) {
|
||||
struct view *view = desktop_view_at_cursor(server);
|
||||
if (view) {
|
||||
desktop_focus_and_activate_view(&server->seat, view);
|
||||
damage_all_outputs(server);
|
||||
}
|
||||
} else if (!strcasecmp(action, "Iconify")) {
|
||||
struct view *view = activator_or_focused_view(activator, server);
|
||||
if (view) {
|
||||
view_minimize(view, true);
|
||||
}
|
||||
} else if (!strcasecmp(action, "Move")) {
|
||||
struct view *view = desktop_view_at_cursor(server);
|
||||
if (view) {
|
||||
interactive_begin(view, LAB_INPUT_STATE_MOVE, 0);
|
||||
}
|
||||
} else if (!strcasecmp(action, "Raise")) {
|
||||
struct view *view = activator_or_focused_view(activator, server);
|
||||
if (view) {
|
||||
desktop_move_to_front(view);
|
||||
damage_all_outputs(server);
|
||||
}
|
||||
} else if (!strcasecmp(action, "Resize")) {
|
||||
struct view *view = desktop_view_at_cursor(server);
|
||||
if (view) {
|
||||
interactive_begin(view, LAB_INPUT_STATE_RESIZE, resize_edges);
|
||||
}
|
||||
} else {
|
||||
wlr_log(WLR_ERROR, "(%s) not supported", action);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue