aboutsummaryrefslogtreecommitdiffstats
path: root/sway/desktop/xwayland.c
diff options
context:
space:
mode:
authorLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-05-09 14:23:20 +1000
committerLibravatar Ryan Dwyer <ryandwyer1@gmail.com>2018-05-11 09:38:53 +1000
commit3b0c26d149dfe5e05df338692db8255a01f0998d (patch)
treec39e377cb96297df8547311a0aa4cfe8fa85b517 /sway/desktop/xwayland.c
parentMerge pull request #1948 from RyanDwyer/focus-parent-border (diff)
downloadsway-3b0c26d149dfe5e05df338692db8255a01f0998d.tar.gz
sway-3b0c26d149dfe5e05df338692db8255a01f0998d.tar.zst
sway-3b0c26d149dfe5e05df338692db8255a01f0998d.zip
Overhaul criteria implementation
The criteria struct now uses properties for each token type rather than the list_t list of tokens. The reason for this is that different token types have different data types: pcre, string and number to name a few. This solution should be more flexible moving forward. A bonus of this is that criteria is now easier to understand when looking at the struct definition. The criteria parser has been rewritten because the previous one didn't support valueless pairs (eg. [class="foo" floating]). Criteria now has types. Types at the moment are CT_COMMAND, CT_ASSIGN_WORKSPACE and CT_ASSIGN_OUTPUT. i3 uses types as well. Previously the assign command was creating a criteria with 'move to workspace <name>' as its command, but this caused the window to appear briefly on the focused workspace before being moved to the assigned workspace. It now creates the view directly in the assigned workspace. Each view will only execute a given criteria once. This is achieved by storing a list of executed criteria in the view. This is the same strategy used by i3. Escaping now works properly. Previously you could do things like [class="Fire\"fox"] and the stored value would be 'Fire\"fox', but it should be (and now is) 'Fire"fox'. The public functions in criteria.c are now all prefixed with criteria_. Xwayland views now listen to the set_title, set_class and set_window_type events and criteria will be run when these happen. XDG shell has none of these events so it continues to update the title in handle_commit. Each view type's get_prop function has been split into get_string_prop and get_int_prop because some properties like the X11 window ID and window type are numeric. The following new criteria tokens are now supported: * id (X11 window ID) * instance * tiling * workspace
Diffstat (limited to 'sway/desktop/xwayland.c')
-rw-r--r--sway/desktop/xwayland.c69
1 files changed, 66 insertions, 3 deletions
diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c
index 8f935760..554c070e 100644
--- a/sway/desktop/xwayland.c
+++ b/sway/desktop/xwayland.c
@@ -126,7 +126,7 @@ static struct sway_xwayland_view *xwayland_view_from_view(
126 return (struct sway_xwayland_view *)view; 126 return (struct sway_xwayland_view *)view;
127} 127}
128 128
129static const char *get_prop(struct sway_view *view, enum sway_view_prop prop) { 129static const char *get_string_prop(struct sway_view *view, enum sway_view_prop prop) {
130 if (xwayland_view_from_view(view) == NULL) { 130 if (xwayland_view_from_view(view) == NULL) {
131 return NULL; 131 return NULL;
132 } 132 }
@@ -135,11 +135,27 @@ static const char *get_prop(struct sway_view *view, enum sway_view_prop prop) {
135 return view->wlr_xwayland_surface->title; 135 return view->wlr_xwayland_surface->title;
136 case VIEW_PROP_CLASS: 136 case VIEW_PROP_CLASS:
137 return view->wlr_xwayland_surface->class; 137 return view->wlr_xwayland_surface->class;
138 case VIEW_PROP_INSTANCE:
139 return view->wlr_xwayland_surface->instance;
138 default: 140 default:
139 return NULL; 141 return NULL;
140 } 142 }
141} 143}
142 144
145static uint32_t get_int_prop(struct sway_view *view, enum sway_view_prop prop) {
146 if (xwayland_view_from_view(view) == NULL) {
147 return 0;
148 }
149 switch (prop) {
150 case VIEW_PROP_X11_WINDOW_ID:
151 return view->wlr_xwayland_surface->window_id;
152 case VIEW_PROP_WINDOW_TYPE:
153 return *view->wlr_xwayland_surface->window_type;
154 default:
155 return 0;
156 }
157}
158
143static void configure(struct sway_view *view, double ox, double oy, int width, 159static void configure(struct sway_view *view, double ox, double oy, int width,
144 int height) { 160 int height) {
145 struct sway_xwayland_view *xwayland_view = xwayland_view_from_view(view); 161 struct sway_xwayland_view *xwayland_view = xwayland_view_from_view(view);
@@ -200,13 +216,17 @@ static void destroy(struct sway_view *view) {
200 wl_list_remove(&xwayland_view->destroy.link); 216 wl_list_remove(&xwayland_view->destroy.link);
201 wl_list_remove(&xwayland_view->request_configure.link); 217 wl_list_remove(&xwayland_view->request_configure.link);
202 wl_list_remove(&xwayland_view->request_fullscreen.link); 218 wl_list_remove(&xwayland_view->request_fullscreen.link);
219 wl_list_remove(&xwayland_view->set_title.link);
220 wl_list_remove(&xwayland_view->set_class.link);
221 wl_list_remove(&xwayland_view->set_window_type.link);
203 wl_list_remove(&xwayland_view->map.link); 222 wl_list_remove(&xwayland_view->map.link);
204 wl_list_remove(&xwayland_view->unmap.link); 223 wl_list_remove(&xwayland_view->unmap.link);
205 free(xwayland_view); 224 free(xwayland_view);
206} 225}
207 226
208static const struct sway_view_impl view_impl = { 227static const struct sway_view_impl view_impl = {
209 .get_prop = get_prop, 228 .get_string_prop = get_string_prop,
229 .get_int_prop = get_int_prop,
210 .configure = configure, 230 .configure = configure,
211 .set_activated = set_activated, 231 .set_activated = set_activated,
212 .set_fullscreen = set_fullscreen, 232 .set_fullscreen = set_fullscreen,
@@ -223,7 +243,6 @@ static void handle_commit(struct wl_listener *listener, void *data) {
223 view_update_size(view, xwayland_view->pending_width, 243 view_update_size(view, xwayland_view->pending_width,
224 xwayland_view->pending_height); 244 xwayland_view->pending_height);
225 view_damage_from(view); 245 view_damage_from(view);
226 view_update_title(view, false);
227} 246}
228 247
229static void handle_unmap(struct wl_listener *listener, void *data) { 248static void handle_unmap(struct wl_listener *listener, void *data) {
@@ -285,6 +304,40 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
285 view_set_fullscreen(view, xsurface->fullscreen); 304 view_set_fullscreen(view, xsurface->fullscreen);
286} 305}
287 306
307static void handle_set_title(struct wl_listener *listener, void *data) {
308 struct sway_xwayland_view *xwayland_view =
309 wl_container_of(listener, xwayland_view, set_title);
310 struct sway_view *view = &xwayland_view->view;
311 struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
312 if (!xsurface->mapped) {
313 return;
314 }
315 view_update_title(view, false);
316 view_execute_criteria(view);
317}
318
319static void handle_set_class(struct wl_listener *listener, void *data) {
320 struct sway_xwayland_view *xwayland_view =
321 wl_container_of(listener, xwayland_view, set_class);
322 struct sway_view *view = &xwayland_view->view;
323 struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
324 if (!xsurface->mapped) {
325 return;
326 }
327 view_execute_criteria(view);
328}
329
330static void handle_set_window_type(struct wl_listener *listener, void *data) {
331 struct sway_xwayland_view *xwayland_view =
332 wl_container_of(listener, xwayland_view, set_window_type);
333 struct sway_view *view = &xwayland_view->view;
334 struct wlr_xwayland_surface *xsurface = view->wlr_xwayland_surface;
335 if (!xsurface->mapped) {
336 return;
337 }
338 view_execute_criteria(view);
339}
340
288void handle_xwayland_surface(struct wl_listener *listener, void *data) { 341void handle_xwayland_surface(struct wl_listener *listener, void *data) {
289 struct sway_server *server = wl_container_of(listener, server, 342 struct sway_server *server = wl_container_of(listener, server,
290 xwayland_surface); 343 xwayland_surface);
@@ -323,6 +376,16 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
323 &xwayland_view->request_fullscreen); 376 &xwayland_view->request_fullscreen);
324 xwayland_view->request_fullscreen.notify = handle_request_fullscreen; 377 xwayland_view->request_fullscreen.notify = handle_request_fullscreen;
325 378
379 wl_signal_add(&xsurface->events.set_title, &xwayland_view->set_title);
380 xwayland_view->set_title.notify = handle_set_title;
381
382 wl_signal_add(&xsurface->events.set_class, &xwayland_view->set_class);
383 xwayland_view->set_class.notify = handle_set_class;
384
385 wl_signal_add(&xsurface->events.set_window_type,
386 &xwayland_view->set_window_type);
387 xwayland_view->set_window_type.notify = handle_set_window_type;
388
326 wl_signal_add(&xsurface->events.unmap, &xwayland_view->unmap); 389 wl_signal_add(&xsurface->events.unmap, &xwayland_view->unmap);
327 xwayland_view->unmap.notify = handle_unmap; 390 xwayland_view->unmap.notify = handle_unmap;
328 391