From 1e9aaa54a85e98d6b46ca594b4f50770f71047ea Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 13 May 2018 08:16:36 +1000 Subject: Revert "Revert "Merge pull request #1943 from RyanDwyer/criteria-improvements"" This reverts commit 32a572cecfd0f6072a78ce0a381a2f8365f9010a. This reimplements the criteria overhaul in preparation for fixing a known bug. --- include/sway/tree/view.h | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'include/sway/tree') diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 17e579c8..bf86ca8c 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -21,11 +21,15 @@ enum sway_view_prop { VIEW_PROP_APP_ID, VIEW_PROP_CLASS, VIEW_PROP_INSTANCE, + VIEW_PROP_WINDOW_TYPE, + VIEW_PROP_WINDOW_ROLE, + VIEW_PROP_X11_WINDOW_ID, }; struct sway_view_impl { - const char *(*get_prop)(struct sway_view *view, + const char *(*get_string_prop)(struct sway_view *view, enum sway_view_prop prop); + uint32_t (*get_int_prop)(struct sway_view *view, enum sway_view_prop prop); void (*configure)(struct sway_view *view, double ox, double oy, int width, int height); void (*set_activated)(struct sway_view *view, bool activated); @@ -53,6 +57,8 @@ struct sway_view { enum sway_container_border border; int border_thickness; + list_t *executed_criteria; + union { struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6; struct wlr_xdg_surface *wlr_xdg_surface; @@ -109,6 +115,9 @@ struct sway_xwayland_view { struct wl_listener request_maximize; struct wl_listener request_configure; struct wl_listener request_fullscreen; + struct wl_listener set_title; + struct wl_listener set_class; + struct wl_listener set_window_type; struct wl_listener map; struct wl_listener unmap; struct wl_listener destroy; @@ -191,6 +200,10 @@ const char *view_get_class(struct sway_view *view); const char *view_get_instance(struct sway_view *view); +uint32_t view_get_x11_window_id(struct sway_view *view); + +uint32_t view_get_window_type(struct sway_view *view); + const char *view_get_type(struct sway_view *view); void view_configure(struct sway_view *view, double ox, double oy, int width, @@ -243,4 +256,10 @@ void view_child_destroy(struct sway_view_child *child); */ void view_update_title(struct sway_view *view, bool force); +/** + * Run any criteria that match the view and haven't been run on this view + * before. + */ +void view_execute_criteria(struct sway_view *view); + #endif -- cgit v1.2.3 From bffcb496cc002d9c8a41285eaabd908b322a9c99 Mon Sep 17 00:00:00 2001 From: Ryan Dwyer Date: Sun, 13 May 2018 08:17:46 +1000 Subject: Revert "Revert "Merge pull request #1953 from RyanDwyer/criteria-focused"" This reverts commit ac0e62584f6101277b76622a7274866cd50f615c. This reimplements the criteria __focused__ commit in preparation for fixing a known bug. --- include/sway/tree/view.h | 2 + sway/criteria.c | 204 +++++++++++++++++++++++++++++++++++++---------- sway/tree/view.c | 7 ++ 3 files changed, 171 insertions(+), 42 deletions(-) (limited to 'include/sway/tree') diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index bf86ca8c..7c07842b 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -202,6 +202,8 @@ const char *view_get_instance(struct sway_view *view); uint32_t view_get_x11_window_id(struct sway_view *view); +const char *view_get_window_role(struct sway_view *view); + uint32_t view_get_window_type(struct sway_view *view); const char *view_get_type(struct sway_view *view); diff --git a/sway/criteria.c b/sway/criteria.c index 7da790e6..294b2922 100644 --- a/sway/criteria.c +++ b/sway/criteria.c @@ -190,19 +190,128 @@ static bool generate_regex(pcre **regex, char *value) { return true; } +enum criteria_token { + T_APP_ID, + T_CLASS, + T_CON_ID, + T_CON_MARK, + T_FLOATING, + T_ID, + T_INSTANCE, + T_TILING, + T_TITLE, + T_URGENT, + T_WINDOW_ROLE, + T_WINDOW_TYPE, + T_WORKSPACE, + + T_INVALID, +}; + +static enum criteria_token token_from_name(char *name) { + if (strcmp(name, "app_id") == 0) { + return T_APP_ID; + } else if (strcmp(name, "class") == 0) { + return T_CLASS; + } else if (strcmp(name, "con_id") == 0) { + return T_CON_ID; + } else if (strcmp(name, "con_mark") == 0) { + return T_CON_MARK; + } else if (strcmp(name, "id") == 0) { + return T_ID; + } else if (strcmp(name, "instance") == 0) { + return T_INSTANCE; + } else if (strcmp(name, "title") == 0) { + return T_TITLE; + } else if (strcmp(name, "urgent") == 0) { + return T_URGENT; + } else if (strcmp(name, "window_role") == 0) { + return T_WINDOW_ROLE; + } else if (strcmp(name, "window_type") == 0) { + return T_WINDOW_TYPE; + } else if (strcmp(name, "workspace") == 0) { + return T_WORKSPACE; + } + return T_INVALID; +} + +/** + * Get a property of the focused view. + * + * Note that we are taking the focused view at the time of criteria parsing, not + * at the time of execution. This is because __focused__ only makes sense when + * using criteria via IPC. Using __focused__ in config is not useful because + * criteria is only executed once per view. + */ +static char *get_focused_prop(enum criteria_token token) { + struct sway_seat *seat = input_manager_current_seat(input_manager); + struct sway_container *focus = seat_get_focus(seat); + + if (!focus || focus->type != C_VIEW) { + return NULL; + } + struct sway_view *view = focus->sway_view; + const char *value = NULL; + + switch (token) { + case T_APP_ID: + value = view_get_app_id(view); + break; + case T_CLASS: + value = view_get_class(view); + break; + case T_INSTANCE: + value = view_get_instance(view); + break; + case T_TITLE: + value = view_get_class(view); + break; + case T_WINDOW_ROLE: + value = view_get_class(view); + break; + case T_WORKSPACE: + { + struct sway_container *ws = container_parent(focus, C_WORKSPACE); + if (ws) { + value = ws->name; + } + } + break; + case T_CON_ID: // These do not support __focused__ + case T_CON_MARK: + case T_FLOATING: + case T_ID: + case T_TILING: + case T_URGENT: + case T_WINDOW_TYPE: + case T_INVALID: + break; + } + if (value) { + return strdup(value); + } + return NULL; +} + static bool parse_token(struct criteria *criteria, char *name, char *value) { + enum criteria_token token = token_from_name(name); + if (token == T_INVALID) { + const char *fmt = "Token '%s' is not recognized"; + int len = strlen(fmt) + strlen(name) - 1; + error = malloc(len); + snprintf(error, len, fmt, name); + return false; + } + + char *effective_value = NULL; + if (value && strcmp(value, "__focused__") == 0) { + effective_value = get_focused_prop(token); + } else if (value) { + effective_value = strdup(value); + } + // Require value, unless token is floating or tiled - if (!value && (strcmp(name, "title") == 0 - || strcmp(name, "app_id") == 0 - || strcmp(name, "class") == 0 - || strcmp(name, "instance") == 0 - || strcmp(name, "con_id") == 0 - || strcmp(name, "con_mark") == 0 - || strcmp(name, "window_role") == 0 - || strcmp(name, "window_type") == 0 - || strcmp(name, "id") == 0 - || strcmp(name, "urgent") == 0 - || strcmp(name, "workspace") == 0)) { + if (!effective_value && token != T_FLOATING && token != T_TILING) { const char *fmt = "Token '%s' requires a value"; int len = strlen(fmt) + strlen(name) - 1; error = malloc(len); @@ -210,53 +319,64 @@ static bool parse_token(struct criteria *criteria, char *name, char *value) { return false; } - if (strcmp(name, "title") == 0) { - generate_regex(&criteria->title, value); - } else if (strcmp(name, "app_id") == 0) { - generate_regex(&criteria->app_id, value); - } else if (strcmp(name, "class") == 0) { - generate_regex(&criteria->class, value); - } else if (strcmp(name, "instance") == 0) { - generate_regex(&criteria->instance, value); - } else if (strcmp(name, "con_id") == 0) { - char *endptr; - criteria->con_id = strtoul(value, &endptr, 10); + char *endptr = NULL; + switch (token) { + case T_TITLE: + generate_regex(&criteria->title, effective_value); + break; + case T_APP_ID: + generate_regex(&criteria->app_id, effective_value); + break; + case T_CLASS: + generate_regex(&criteria->class, effective_value); + break; + case T_INSTANCE: + generate_regex(&criteria->instance, effective_value); + break; + case T_CON_ID: + criteria->con_id = strtoul(effective_value, &endptr, 10); if (*endptr != 0) { error = strdup("The value for 'con_id' should be numeric"); } - } else if (strcmp(name, "con_mark") == 0) { - generate_regex(&criteria->con_mark, value); - } else if (strcmp(name, "window_role") == 0) { - generate_regex(&criteria->window_role, value); - } else if (strcmp(name, "window_type") == 0) { + break; + case T_CON_MARK: + generate_regex(&criteria->con_mark, effective_value); + break; + case T_WINDOW_ROLE: + generate_regex(&criteria->window_role, effective_value); + break; + case T_WINDOW_TYPE: // TODO: This is a string but will be stored as an enum or integer - } else if (strcmp(name, "id") == 0) { - char *endptr; - criteria->id = strtoul(value, &endptr, 10); + break; + case T_ID: + criteria->id = strtoul(effective_value, &endptr, 10); if (*endptr != 0) { error = strdup("The value for 'id' should be numeric"); } - } else if (strcmp(name, "floating") == 0) { + break; + case T_FLOATING: criteria->floating = true; - } else if (strcmp(name, "tiling") == 0) { + break; + case T_TILING: criteria->tiling = true; - } else if (strcmp(name, "urgent") == 0) { - if (strcmp(value, "latest") == 0) { + break; + case T_URGENT: + if (strcmp(effective_value, "latest") == 0) { criteria->urgent = 'l'; - } else if (strcmp(value, "oldest") == 0) { + } else if (strcmp(effective_value, "oldest") == 0) { criteria->urgent = 'o'; } else { error = strdup("The value for 'urgent' must be 'latest' or 'oldest'"); } - } else if (strcmp(name, "workspace") == 0) { - criteria->workspace = strdup(value); - } else { - const char *fmt = "Token '%s' is not recognized"; - int len = strlen(fmt) + strlen(name) - 1; - error = malloc(len); - snprintf(error, len, fmt, name); + break; + case T_WORKSPACE: + criteria->workspace = strdup(effective_value); + break; + case T_INVALID: + break; } + free(effective_value); if (error) { return false; diff --git a/sway/tree/view.c b/sway/tree/view.c index 8fc45f52..f872bef6 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -81,6 +81,13 @@ uint32_t view_get_x11_window_id(struct sway_view *view) { return 0; } +const char *view_get_window_role(struct sway_view *view) { + if (view->impl->get_string_prop) { + return view->impl->get_string_prop(view, VIEW_PROP_WINDOW_ROLE); + } + return NULL; +} + uint32_t view_get_window_type(struct sway_view *view) { if (view->impl->get_int_prop) { return view->impl->get_int_prop(view, VIEW_PROP_WINDOW_TYPE); -- cgit v1.2.3 From 95a10dd4f35c6ffc14d23fa3a19a784e85a31724 Mon Sep 17 00:00:00 2001 From: emersion Date: Sun, 29 Apr 2018 09:40:58 +0100 Subject: Kill wl_shell --- include/sway/server.h | 1 - include/sway/tree/view.h | 15 ----- sway/commands/fullscreen.c | 1 - sway/desktop/output.c | 1 - sway/desktop/wl_shell.c | 165 --------------------------------------------- sway/meson.build | 1 - sway/server.c | 10 +-- sway/tree/container.c | 6 -- sway/tree/view.c | 2 - 9 files changed, 2 insertions(+), 200 deletions(-) delete mode 100644 sway/desktop/wl_shell.c (limited to 'include/sway/tree') diff --git a/include/sway/server.h b/include/sway/server.h index d04ea896..c95ee0f3 100644 --- a/include/sway/server.h +++ b/include/sway/server.h @@ -58,6 +58,5 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data); void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data); void handle_xdg_shell_surface(struct wl_listener *listener, void *data); void handle_xwayland_surface(struct wl_listener *listener, void *data); -void handle_wl_shell_surface(struct wl_listener *listener, void *data); #endif diff --git a/include/sway/tree/view.h b/include/sway/tree/view.h index 7c07842b..9af13004 100644 --- a/include/sway/tree/view.h +++ b/include/sway/tree/view.h @@ -10,7 +10,6 @@ struct sway_container; enum sway_view_type { - SWAY_VIEW_WL_SHELL, SWAY_VIEW_XDG_SHELL_V6, SWAY_VIEW_XDG_SHELL, SWAY_VIEW_XWAYLAND, @@ -139,20 +138,6 @@ struct sway_xwayland_unmanaged { struct wl_listener destroy; }; -struct sway_wl_shell_view { - struct sway_view view; - - struct wl_listener commit; - struct wl_listener request_move; - struct wl_listener request_resize; - struct wl_listener request_maximize; - struct wl_listener request_fullscreen; - struct wl_listener set_state; - struct wl_listener destroy; - - int pending_width, pending_height; -}; - struct sway_view_child; struct sway_view_child_impl { diff --git a/sway/commands/fullscreen.c b/sway/commands/fullscreen.c index 8692e92d..ec9ec276 100644 --- a/sway/commands/fullscreen.c +++ b/sway/commands/fullscreen.c @@ -1,4 +1,3 @@ -#include #include "log.h" #include "sway/commands.h" #include "sway/config.h" diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 974cd56c..3f89f5cc 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include "log.h" #include "sway/config.h" diff --git a/sway/desktop/wl_shell.c b/sway/desktop/wl_shell.c deleted file mode 100644 index cb3774f7..00000000 --- a/sway/desktop/wl_shell.c +++ /dev/null @@ -1,165 +0,0 @@ -#define _POSIX_C_SOURCE 199309L -#include -#include -#include -#include -#include "sway/tree/container.h" -#include "sway/tree/layout.h" -#include "sway/server.h" -#include "sway/tree/view.h" -#include "sway/input/seat.h" -#include "sway/input/input-manager.h" -#include "log.h" - -static struct sway_wl_shell_view *wl_shell_view_from_view( - struct sway_view *view) { - if (!sway_assert(view->type == SWAY_VIEW_WL_SHELL, - "Expected wl_shell view")) { - return NULL; - } - return (struct sway_wl_shell_view *)view; -} - -static const char *get_string_prop(struct sway_view *view, enum sway_view_prop prop) { - if (wl_shell_view_from_view(view) == NULL) { - return NULL; - } - switch (prop) { - case VIEW_PROP_TITLE: - return view->wlr_wl_shell_surface->title; - case VIEW_PROP_CLASS: - return view->wlr_wl_shell_surface->class; - default: - return NULL; - } -} - -static void configure(struct sway_view *view, double ox, double oy, int width, - int height) { - struct sway_wl_shell_view *wl_shell_view = wl_shell_view_from_view(view); - if (wl_shell_view == NULL) { - return; - } - wl_shell_view->pending_width = width; - wl_shell_view->pending_height = height; - wlr_wl_shell_surface_configure(view->wlr_wl_shell_surface, 0, width, height); -} - -static void _close(struct sway_view *view) { - if (wl_shell_view_from_view(view) == NULL) { - return; - } - - wl_client_destroy(view->wlr_wl_shell_surface->client); -} - -static void destroy(struct sway_view *view) { - struct sway_wl_shell_view *wl_shell_view = wl_shell_view_from_view(view); - if (wl_shell_view == NULL) { - return; - } - wl_list_remove(&wl_shell_view->commit.link); - wl_list_remove(&wl_shell_view->destroy.link); - wl_list_remove(&wl_shell_view->request_fullscreen.link); - wl_list_remove(&wl_shell_view->set_state.link); - free(wl_shell_view); -} - -static void set_fullscreen(struct sway_view *view, bool fullscreen) { - // TODO -} - -static const struct sway_view_impl view_impl = { - .get_string_prop = get_string_prop, - .configure = configure, - .close = _close, - .destroy = destroy, - .set_fullscreen = set_fullscreen, -}; - -static void handle_commit(struct wl_listener *listener, void *data) { - struct sway_wl_shell_view *wl_shell_view = - wl_container_of(listener, wl_shell_view, commit); - struct sway_view *view = &wl_shell_view->view; - // NOTE: We intentionally discard the view's desired width here - // TODO: Let floating views do whatever - view_update_size(view, wl_shell_view->pending_width, - wl_shell_view->pending_height); - view_damage_from(view); -} - -static void handle_destroy(struct wl_listener *listener, void *data) { - struct sway_wl_shell_view *wl_shell_view = - wl_container_of(listener, wl_shell_view, destroy); - view_destroy(&wl_shell_view->view); -} - -static void handle_request_fullscreen(struct wl_listener *listener, void *data) { - struct sway_wl_shell_view *wl_shell_view = - wl_container_of(listener, wl_shell_view, request_fullscreen); - view_set_fullscreen(&wl_shell_view->view, true); -} - -static void handle_set_state(struct wl_listener *listener, void *data) { - struct sway_wl_shell_view *wl_shell_view = - wl_container_of(listener, wl_shell_view, set_state); - struct sway_view *view = &wl_shell_view->view; - struct wlr_wl_shell_surface *surface = view->wlr_wl_shell_surface; - if (view->is_fullscreen && - surface->state != WLR_WL_SHELL_SURFACE_STATE_FULLSCREEN) { - view_set_fullscreen(view, false); - } -} - -void handle_wl_shell_surface(struct wl_listener *listener, void *data) { - struct sway_server *server = wl_container_of(listener, server, - wl_shell_surface); - struct wlr_wl_shell_surface *shell_surface = data; - - if (shell_surface->state == WLR_WL_SHELL_SURFACE_STATE_POPUP) { - // popups don't get views - wlr_log(L_DEBUG, "New wl_shell popup"); - return; - } - - // TODO: make transient windows floating - - wlr_log(L_DEBUG, "New wl_shell toplevel title='%s' app_id='%s'", - shell_surface->title, shell_surface->class); - wlr_wl_shell_surface_ping(shell_surface); - - struct sway_wl_shell_view *wl_shell_view = - calloc(1, sizeof(struct sway_wl_shell_view)); - if (!sway_assert(wl_shell_view, "Failed to allocate view")) { - return; - } - - view_init(&wl_shell_view->view, SWAY_VIEW_WL_SHELL, &view_impl); - wl_shell_view->view.wlr_wl_shell_surface = shell_surface; - - // TODO: - // - Wire up listeners - // - Look up pid and open on appropriate workspace - // - Set new view to maximized so it behaves nicely - // - Criteria - - wl_shell_view->commit.notify = handle_commit; - wl_signal_add(&shell_surface->surface->events.commit, - &wl_shell_view->commit); - - wl_shell_view->destroy.notify = handle_destroy; - wl_signal_add(&shell_surface->events.destroy, &wl_shell_view->destroy); - - wl_shell_view->request_fullscreen.notify = handle_request_fullscreen; - wl_signal_add(&shell_surface->events.request_fullscreen, - &wl_shell_view->request_fullscreen); - - wl_shell_view->set_state.notify = handle_set_state; - wl_signal_add(&shell_surface->events.set_state, &wl_shell_view->set_state); - - view_map(&wl_shell_view->view, shell_surface->surface); - - if (shell_surface->state == WLR_WL_SHELL_SURFACE_STATE_FULLSCREEN) { - view_set_fullscreen(&wl_shell_view->view, true); - } -} diff --git a/sway/meson.build b/sway/meson.build index 570d4783..67c2a422 100644 --- a/sway/meson.build +++ b/sway/meson.build @@ -12,7 +12,6 @@ sway_sources = files( 'desktop/desktop.c', 'desktop/layer_shell.c', 'desktop/output.c', - 'desktop/wl_shell.c', 'desktop/xdg_shell_v6.c', 'desktop/xdg_shell.c', 'desktop/xwayland.c', diff --git a/sway/server.c b/sway/server.c index 6147a39d..050ddf56 100644 --- a/sway/server.c +++ b/sway/server.c @@ -8,15 +8,14 @@ #include #include #include -#include +#include #include +#include #include #include #include #include #include -#include -#include #include // TODO WLR: make Xwayland optional #include @@ -88,11 +87,6 @@ bool server_init(struct sway_server *server) { &server->xdg_shell_surface); server->xdg_shell_surface.notify = handle_xdg_shell_surface; - server->wl_shell = wlr_wl_shell_create(server->wl_display); - wl_signal_add(&server->wl_shell->events.new_surface, - &server->wl_shell_surface); - server->wl_shell_surface.notify = handle_wl_shell_surface; - // TODO make xwayland optional server->xwayland = wlr_xwayland_create(server->wl_display, server->compositor, true); diff --git a/sway/tree/container.c b/sway/tree/container.c index 9f7294db..a17b20f7 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include "cairo.h" @@ -446,11 +445,6 @@ struct sway_container *container_at(struct sway_container *parent, _surface = wlr_surface_surface_at(sview->surface, view_sx, view_sy, &_sx, &_sy); break; - case SWAY_VIEW_WL_SHELL: - _surface = wlr_wl_shell_surface_surface_at( - sview->wlr_wl_shell_surface, - view_sx, view_sy, &_sx, &_sy); - break; case SWAY_VIEW_XDG_SHELL_V6: // the top left corner of the sway container is the // coordinate of the top left corner of the window geometry diff --git a/sway/tree/view.c b/sway/tree/view.c index 41dee1c4..e0e3c110 100644 --- a/sway/tree/view.c +++ b/sway/tree/view.c @@ -97,8 +97,6 @@ uint32_t view_get_window_type(struct sway_view *view) { const char *view_get_type(struct sway_view *view) { switch(view->type) { - case SWAY_VIEW_WL_SHELL: - return "wl_shell"; case SWAY_VIEW_XDG_SHELL_V6: return "xdg_shell_v6"; case SWAY_VIEW_XDG_SHELL: -- cgit v1.2.3