mirror of
https://github.com/swaywm/sway.git
synced 2024-11-26 18:01:29 +00:00
Implement criteria commands
Implements the following commands: * for_window [...] <cmdlist> * assign [...] <workspace>
This commit is contained in:
parent
38c44f2f27
commit
72767e1cc3
|
@ -93,12 +93,14 @@ void apply_seat_config(struct seat_config *seat_config) {
|
||||||
|
|
||||||
/* Keep alphabetized */
|
/* Keep alphabetized */
|
||||||
static struct cmd_handler handlers[] = {
|
static struct cmd_handler handlers[] = {
|
||||||
|
{ "assign", cmd_assign },
|
||||||
{ "bar", cmd_bar },
|
{ "bar", cmd_bar },
|
||||||
{ "bindcode", cmd_bindcode },
|
{ "bindcode", cmd_bindcode },
|
||||||
{ "bindsym", cmd_bindsym },
|
{ "bindsym", cmd_bindsym },
|
||||||
{ "exec", cmd_exec },
|
{ "exec", cmd_exec },
|
||||||
{ "exec_always", cmd_exec_always },
|
{ "exec_always", cmd_exec_always },
|
||||||
{ "focus_follows_mouse", cmd_focus_follows_mouse },
|
{ "focus_follows_mouse", cmd_focus_follows_mouse },
|
||||||
|
{ "for_window", cmd_for_window },
|
||||||
{ "fullscreen", cmd_fullscreen },
|
{ "fullscreen", cmd_fullscreen },
|
||||||
{ "include", cmd_include },
|
{ "include", cmd_include },
|
||||||
{ "input", cmd_input },
|
{ "input", cmd_input },
|
||||||
|
|
57
sway/commands/assign.c
Normal file
57
sway/commands/assign.c
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
#define _XOPEN_SOURCE 700
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "sway/commands.h"
|
||||||
|
#include "sway/criteria.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
struct cmd_results *cmd_assign(int argc, char **argv) {
|
||||||
|
struct cmd_results *error = NULL;
|
||||||
|
if ((error = checkarg(argc, "assign", EXPECTED_AT_LEAST, 2))) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *criteria = *argv++;
|
||||||
|
|
||||||
|
if (strncmp(*argv, "→", strlen("→")) == 0) {
|
||||||
|
if (argc < 3) {
|
||||||
|
return cmd_results_new(CMD_INVALID, "assign", "Missing workspace");
|
||||||
|
}
|
||||||
|
argv++;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *movecmd = "move container to workspace ";
|
||||||
|
int arglen = strlen(movecmd) + strlen(*argv) + 1;
|
||||||
|
char *cmdlist = calloc(1, arglen);
|
||||||
|
if (!cmdlist) {
|
||||||
|
return cmd_results_new(CMD_FAILURE, "assign", "Unable to allocate command list");
|
||||||
|
}
|
||||||
|
snprintf(cmdlist, arglen, "%s%s", movecmd, *argv);
|
||||||
|
|
||||||
|
struct criteria *crit = malloc(sizeof(struct criteria));
|
||||||
|
if (!crit) {
|
||||||
|
free(cmdlist);
|
||||||
|
return cmd_results_new(CMD_FAILURE, "assign", "Unable to allocate criteria");
|
||||||
|
}
|
||||||
|
crit->crit_raw = strdup(criteria);
|
||||||
|
crit->cmdlist = cmdlist;
|
||||||
|
crit->tokens = create_list();
|
||||||
|
char *err_str = extract_crit_tokens(crit->tokens, crit->crit_raw);
|
||||||
|
|
||||||
|
if (err_str) {
|
||||||
|
error = cmd_results_new(CMD_INVALID, "assign", err_str);
|
||||||
|
free(err_str);
|
||||||
|
free_criteria(crit);
|
||||||
|
} else if (crit->tokens->length == 0) {
|
||||||
|
error = cmd_results_new(CMD_INVALID, "assign", "Found no name/value pairs in criteria");
|
||||||
|
free_criteria(crit);
|
||||||
|
} else if (list_seq_find(config->criteria, criteria_cmp, crit) != -1) {
|
||||||
|
wlr_log(L_DEBUG, "assign: Duplicate, skipping.");
|
||||||
|
free_criteria(crit);
|
||||||
|
} else {
|
||||||
|
wlr_log(L_DEBUG, "assign: '%s' -> '%s' added", crit->crit_raw, crit->cmdlist);
|
||||||
|
list_add(config->criteria, crit);
|
||||||
|
}
|
||||||
|
return error ? error : cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||||
|
}
|
41
sway/commands/for_window.c
Normal file
41
sway/commands/for_window.c
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#define _XOPEN_SOURCE 500
|
||||||
|
#include <string.h>
|
||||||
|
#include "sway/commands.h"
|
||||||
|
#include "sway/criteria.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "stringop.h"
|
||||||
|
|
||||||
|
struct cmd_results *cmd_for_window(int argc, char **argv) {
|
||||||
|
struct cmd_results *error = NULL;
|
||||||
|
if ((error = checkarg(argc, "for_window", EXPECTED_AT_LEAST, 2))) {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
// add command to a criteria/command pair that is run against views when they appear.
|
||||||
|
char *criteria = argv[0], *cmdlist = join_args(argv + 1, argc - 1);
|
||||||
|
|
||||||
|
struct criteria *crit = malloc(sizeof(struct criteria));
|
||||||
|
if (!crit) {
|
||||||
|
return cmd_results_new(CMD_FAILURE, "for_window", "Unable to allocate criteria");
|
||||||
|
}
|
||||||
|
crit->crit_raw = strdup(criteria);
|
||||||
|
crit->cmdlist = cmdlist;
|
||||||
|
crit->tokens = create_list();
|
||||||
|
char *err_str = extract_crit_tokens(crit->tokens, crit->crit_raw);
|
||||||
|
|
||||||
|
if (err_str) {
|
||||||
|
error = cmd_results_new(CMD_INVALID, "for_window", err_str);
|
||||||
|
free(err_str);
|
||||||
|
free_criteria(crit);
|
||||||
|
} else if (crit->tokens->length == 0) {
|
||||||
|
error = cmd_results_new(CMD_INVALID, "for_window", "Found no name/value pairs in criteria");
|
||||||
|
free_criteria(crit);
|
||||||
|
} else if (list_seq_find(config->criteria, criteria_cmp, crit) != -1) {
|
||||||
|
wlr_log(L_DEBUG, "for_window: Duplicate, skipping.");
|
||||||
|
free_criteria(crit);
|
||||||
|
} else {
|
||||||
|
wlr_log(L_DEBUG, "for_window: '%s' -> '%s' added", crit->crit_raw, crit->cmdlist);
|
||||||
|
list_add(config->criteria, crit);
|
||||||
|
}
|
||||||
|
return error ? error : cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||||
|
}
|
|
@ -26,6 +26,7 @@ sway_sources = files(
|
||||||
'config/seat.c',
|
'config/seat.c',
|
||||||
'config/input.c',
|
'config/input.c',
|
||||||
|
|
||||||
|
'commands/assign.c',
|
||||||
'commands/bar.c',
|
'commands/bar.c',
|
||||||
'commands/bind.c',
|
'commands/bind.c',
|
||||||
'commands/default_orientation.c',
|
'commands/default_orientation.c',
|
||||||
|
@ -34,6 +35,7 @@ sway_sources = files(
|
||||||
'commands/exec_always.c',
|
'commands/exec_always.c',
|
||||||
'commands/focus.c',
|
'commands/focus.c',
|
||||||
'commands/focus_follows_mouse.c',
|
'commands/focus_follows_mouse.c',
|
||||||
|
'commands/for_window.c',
|
||||||
'commands/fullscreen.c',
|
'commands/fullscreen.c',
|
||||||
'commands/kill.c',
|
'commands/kill.c',
|
||||||
'commands/opacity.c',
|
'commands/opacity.c',
|
||||||
|
|
|
@ -2,8 +2,11 @@
|
||||||
#include <wayland-server.h>
|
#include <wayland-server.h>
|
||||||
#include <wlr/types/wlr_output_layout.h>
|
#include <wlr/types/wlr_output_layout.h>
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "sway/criteria.h"
|
||||||
|
#include "sway/commands.h"
|
||||||
#include "sway/ipc-server.h"
|
#include "sway/ipc-server.h"
|
||||||
#include "sway/output.h"
|
#include "sway/output.h"
|
||||||
|
#include "sway/input/seat.h"
|
||||||
#include "sway/tree/container.h"
|
#include "sway/tree/container.h"
|
||||||
#include "sway/tree/layout.h"
|
#include "sway/tree/layout.h"
|
||||||
#include "sway/tree/view.h"
|
#include "sway/tree/view.h"
|
||||||
|
@ -208,6 +211,28 @@ static void view_handle_container_reparent(struct wl_listener *listener,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void view_execute_criteria(struct sway_view *view) {
|
||||||
|
struct sway_seat *seat = input_manager_current_seat(input_manager);
|
||||||
|
struct sway_container *prior_workspace =
|
||||||
|
container_parent(view->swayc, C_WORKSPACE);
|
||||||
|
list_t *criteria = criteria_for(view->swayc);
|
||||||
|
for (int i = 0; i < criteria->length; i++) {
|
||||||
|
struct criteria *crit = criteria->items[i];
|
||||||
|
wlr_log(L_DEBUG, "for_window '%s' matches new view %p, cmd: '%s'",
|
||||||
|
crit->crit_raw, view, crit->cmdlist);
|
||||||
|
struct cmd_results *res = execute_command(crit->cmdlist, NULL);
|
||||||
|
if (res->status != CMD_SUCCESS) {
|
||||||
|
wlr_log(L_ERROR, "Command '%s' failed: %s", res->input, res->error);
|
||||||
|
}
|
||||||
|
free_cmd_results(res);
|
||||||
|
// view must be focused for commands to affect it,
|
||||||
|
// so always refocus in-between command lists
|
||||||
|
seat_set_focus(seat, view->swayc);
|
||||||
|
}
|
||||||
|
list_free(criteria);
|
||||||
|
seat_set_focus(seat, seat_get_focus_inactive(seat, prior_workspace));
|
||||||
|
}
|
||||||
|
|
||||||
void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
|
void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
|
||||||
if (!sway_assert(view->surface == NULL, "cannot map mapped view")) {
|
if (!sway_assert(view->surface == NULL, "cannot map mapped view")) {
|
||||||
return;
|
return;
|
||||||
|
@ -234,6 +259,8 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface) {
|
||||||
|
|
||||||
view_damage(view, true);
|
view_damage(view, true);
|
||||||
view_handle_container_reparent(&view->container_reparent, NULL);
|
view_handle_container_reparent(&view->container_reparent, NULL);
|
||||||
|
|
||||||
|
view_execute_criteria(view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void view_unmap(struct sway_view *view) {
|
void view_unmap(struct sway_view *view) {
|
||||||
|
|
Loading…
Reference in a new issue