diff options
-rw-r--r-- | include/sway/container.h | 13 | ||||
-rw-r--r-- | include/sway/server.h | 6 | ||||
-rw-r--r-- | include/sway/view.h | 56 | ||||
-rw-r--r-- | sway/CMakeLists.txt | 1 | ||||
-rw-r--r-- | sway/config.c | 2 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 117 | ||||
-rw-r--r-- | sway/server.c | 5 | ||||
-rw-r--r-- | sway/tree/container.c | 58 |
8 files changed, 222 insertions, 36 deletions
diff --git a/include/sway/container.h b/include/sway/container.h index 09e29291..d46ffa63 100644 --- a/include/sway/container.h +++ b/include/sway/container.h | |||
@@ -11,6 +11,8 @@ typedef struct sway_container swayc_t; | |||
11 | extern swayc_t root_container; | 11 | extern swayc_t root_container; |
12 | extern swayc_t *current_focus; | 12 | extern swayc_t *current_focus; |
13 | 13 | ||
14 | struct sway_view; | ||
15 | |||
14 | /** | 16 | /** |
15 | * Different kinds of containers. | 17 | * Different kinds of containers. |
16 | * | 18 | * |
@@ -27,14 +29,6 @@ enum swayc_types { | |||
27 | C_TYPES, | 29 | C_TYPES, |
28 | }; | 30 | }; |
29 | 31 | ||
30 | enum swayc_view_types { | ||
31 | V_WL_SHELL, | ||
32 | V_XDG_SHELL_V6, | ||
33 | V_XWAYLAND, | ||
34 | // Keep last | ||
35 | V_TYPES, | ||
36 | }; | ||
37 | |||
38 | /** | 32 | /** |
39 | * Different ways to arrange a container. | 33 | * Different ways to arrange a container. |
40 | */ | 34 | */ |
@@ -76,6 +70,7 @@ struct sway_container { | |||
76 | 70 | ||
77 | union { | 71 | union { |
78 | struct sway_output *output; | 72 | struct sway_output *output; |
73 | struct sway_view *view; | ||
79 | } _handle; | 74 | } _handle; |
80 | 75 | ||
81 | /** | 76 | /** |
@@ -207,7 +202,7 @@ swayc_t *new_container(swayc_t *child, enum swayc_layouts layout); | |||
207 | * | 202 | * |
208 | * Pass in a sibling view, or a workspace to become this container's parent. | 203 | * Pass in a sibling view, or a workspace to become this container's parent. |
209 | */ | 204 | */ |
210 | swayc_t *new_view(swayc_t *sibling, wlc_handle handle); | 205 | swayc_t *new_view(swayc_t *sibling, struct sway_view *view); |
211 | /** | 206 | /** |
212 | * Allocates a new floating view in the active workspace. | 207 | * Allocates a new floating view in the active workspace. |
213 | */ | 208 | */ |
diff --git a/include/sway/server.h b/include/sway/server.h index 043c1a33..5a8a8d31 100644 --- a/include/sway/server.h +++ b/include/sway/server.h | |||
@@ -5,6 +5,7 @@ | |||
5 | #include <wlr/backend.h> | 5 | #include <wlr/backend.h> |
6 | #include <wlr/backend/session.h> | 6 | #include <wlr/backend/session.h> |
7 | #include <wlr/types/wlr_data_device_manager.h> | 7 | #include <wlr/types/wlr_data_device_manager.h> |
8 | #include <wlr/types/wlr_xdg_shell_v6.h> | ||
8 | #include <wlr/render.h> | 9 | #include <wlr/render.h> |
9 | // TODO WLR: make Xwayland optional | 10 | // TODO WLR: make Xwayland optional |
10 | #include <wlr/xwayland.h> | 11 | #include <wlr/xwayland.h> |
@@ -24,6 +25,9 @@ struct sway_server { | |||
24 | struct wl_listener output_add; | 25 | struct wl_listener output_add; |
25 | struct wl_listener output_remove; | 26 | struct wl_listener output_remove; |
26 | struct wl_listener output_frame; | 27 | struct wl_listener output_frame; |
28 | |||
29 | struct wlr_xdg_shell_v6 *xdg_shell_v6; | ||
30 | struct wl_listener xdg_shell_v6_surface; | ||
27 | }; | 31 | }; |
28 | 32 | ||
29 | struct sway_server server; | 33 | struct sway_server server; |
@@ -35,4 +39,6 @@ void server_run(struct sway_server *server); | |||
35 | void output_add_notify(struct wl_listener *listener, void *data); | 39 | void output_add_notify(struct wl_listener *listener, void *data); |
36 | void output_remove_notify(struct wl_listener *listener, void *data); | 40 | void output_remove_notify(struct wl_listener *listener, void *data); |
37 | 41 | ||
42 | void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data); | ||
43 | |||
38 | #endif | 44 | #endif |
diff --git a/include/sway/view.h b/include/sway/view.h new file mode 100644 index 00000000..979b20a8 --- /dev/null +++ b/include/sway/view.h | |||
@@ -0,0 +1,56 @@ | |||
1 | #ifndef _SWAY_VIEW_H | ||
2 | #define _SWAY_VIEW_H | ||
3 | #include <wayland-server.h> | ||
4 | #include <wlr/types/wlr_xdg_shell_v6.h> | ||
5 | |||
6 | struct sway_container; | ||
7 | struct sway_view; | ||
8 | |||
9 | struct sway_xdg_surface_v6 { | ||
10 | struct sway_view *view; | ||
11 | |||
12 | struct wl_listener commit; | ||
13 | struct wl_listener request_move; | ||
14 | struct wl_listener request_resize; | ||
15 | struct wl_listener request_maximize; | ||
16 | }; | ||
17 | |||
18 | enum sway_view_type { | ||
19 | SWAY_WL_SHELL_VIEW, | ||
20 | SWAY_XDG_SHELL_V6_VIEW, | ||
21 | SWAY_XWAYLAND_VIEW, | ||
22 | // Keep last | ||
23 | SWAY_VIEW_TYPES, | ||
24 | }; | ||
25 | |||
26 | enum sway_view_prop { | ||
27 | VIEW_PROP_TITLE, | ||
28 | VIEW_PROP_CLASS, | ||
29 | VIEW_PROP_INSTANCE, | ||
30 | VIEW_PROP_APP_ID, | ||
31 | }; | ||
32 | |||
33 | /** | ||
34 | * sway_view is a state container for surfaces that are arranged in the sway | ||
35 | * tree (shell surfaces). | ||
36 | */ | ||
37 | struct sway_view { | ||
38 | struct wl_listener destroy; | ||
39 | enum sway_view_type type; | ||
40 | struct sway_container *swayc; | ||
41 | |||
42 | union { | ||
43 | struct wlr_xdg_surface_v6 *wlr_xdg_surface_v6; | ||
44 | }; | ||
45 | |||
46 | union { | ||
47 | struct sway_xdg_surface_v6 *sway_xdg_surface_v6; | ||
48 | }; | ||
49 | |||
50 | struct { | ||
51 | const char *(*get_prop)(struct sway_view *view, | ||
52 | enum sway_view_prop prop); | ||
53 | } iface; | ||
54 | }; | ||
55 | |||
56 | #endif | ||
diff --git a/sway/CMakeLists.txt b/sway/CMakeLists.txt index 617a71f0..f9209189 100644 --- a/sway/CMakeLists.txt +++ b/sway/CMakeLists.txt | |||
@@ -19,6 +19,7 @@ file(GLOB cmds | |||
19 | 19 | ||
20 | add_executable(sway | 20 | add_executable(sway |
21 | desktop/output.c | 21 | desktop/output.c |
22 | desktop/xdg_shell_v6.c | ||
22 | 23 | ||
23 | tree/container.c | 24 | tree/container.c |
24 | tree/criteria.c | 25 | tree/criteria.c |
diff --git a/sway/config.c b/sway/config.c index 78ab8f3b..aa40c49a 100644 --- a/sway/config.c +++ b/sway/config.c | |||
@@ -932,6 +932,7 @@ void merge_output_config(struct output_config *dst, struct output_config *src) { | |||
932 | 932 | ||
933 | static void invoke_swaybar(struct bar_config *bar) { | 933 | static void invoke_swaybar(struct bar_config *bar) { |
934 | return; // TODO WLR | 934 | return; // TODO WLR |
935 | sway_log(L_DEBUG, "Invoking swaybar for bar id '%s'", bar->id); | ||
935 | // Pipe to communicate errors | 936 | // Pipe to communicate errors |
936 | int filedes[2]; | 937 | int filedes[2]; |
937 | if (pipe(filedes) == -1) { | 938 | if (pipe(filedes) == -1) { |
@@ -1059,7 +1060,6 @@ void load_swaybars() { | |||
1059 | if (bar->pid != 0) { | 1060 | if (bar->pid != 0) { |
1060 | terminate_swaybar(bar->pid); | 1061 | terminate_swaybar(bar->pid); |
1061 | } | 1062 | } |
1062 | sway_log(L_DEBUG, "Invoking swaybar for bar id '%s'", bar->id); | ||
1063 | invoke_swaybar(bar); | 1063 | invoke_swaybar(bar); |
1064 | } | 1064 | } |
1065 | 1065 | ||
diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c new file mode 100644 index 00000000..e29b46d7 --- /dev/null +++ b/sway/desktop/xdg_shell_v6.c | |||
@@ -0,0 +1,117 @@ | |||
1 | #include <stdlib.h> | ||
2 | #include <wayland-server.h> | ||
3 | #include <wlr/types/wlr_xdg_shell_v6.h> | ||
4 | #include "sway/commands.h" | ||
5 | #include "sway/container.h" | ||
6 | #include "sway/focus.h" | ||
7 | #include "sway/ipc-server.h" | ||
8 | #include "sway/server.h" | ||
9 | #include "sway/view.h" | ||
10 | #include "log.h" | ||
11 | |||
12 | // TODO: move elsewhere | ||
13 | static void temp_ws_cleanup() { | ||
14 | swayc_t *op, *ws; | ||
15 | int i = 0, j; | ||
16 | if (!root_container.children) | ||
17 | return; | ||
18 | while (i < root_container.children->length) { | ||
19 | op = root_container.children->items[i++]; | ||
20 | if (!op->children) | ||
21 | continue; | ||
22 | j = 0; | ||
23 | while (j < op->children->length) { | ||
24 | ws = op->children->items[j++]; | ||
25 | if (ws->children->length == 0 && ws->floating->length == 0 && ws != op->focused) { | ||
26 | if (destroy_workspace(ws)) { | ||
27 | j--; | ||
28 | } | ||
29 | } | ||
30 | } | ||
31 | } | ||
32 | } | ||
33 | |||
34 | // TODO: move elsewhere | ||
35 | static swayc_t *move_focus_to_tiling(swayc_t *focused) { | ||
36 | if (focused->is_floating) { | ||
37 | if (focused->parent->children->length == 0) { | ||
38 | return focused->parent; | ||
39 | } | ||
40 | // TODO find a better way of doing this | ||
41 | // Or to focused container | ||
42 | return get_focused_container(focused->parent->children->items[0]); | ||
43 | } | ||
44 | return focused; | ||
45 | } | ||
46 | |||
47 | static const char *get_prop(struct sway_view *view, enum sway_view_prop prop) { | ||
48 | if (!sway_assert(view->type == SWAY_XDG_SHELL_V6_VIEW, | ||
49 | "xdg get_prop for non-xdg view!")) { | ||
50 | return NULL; | ||
51 | } | ||
52 | switch (prop) { | ||
53 | case VIEW_PROP_TITLE: | ||
54 | return view->wlr_xdg_surface_v6->title; | ||
55 | case VIEW_PROP_APP_ID: | ||
56 | return view->wlr_xdg_surface_v6->app_id; | ||
57 | default: | ||
58 | return NULL; | ||
59 | } | ||
60 | } | ||
61 | |||
62 | void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { | ||
63 | struct sway_server *server = wl_container_of( | ||
64 | listener, server, xdg_shell_v6_surface); | ||
65 | struct wlr_xdg_surface_v6 *xdg_surface = data; | ||
66 | |||
67 | if (xdg_surface->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) { | ||
68 | // TODO: popups | ||
69 | return; | ||
70 | } | ||
71 | |||
72 | sway_log(L_DEBUG, "New xdg_shell_v6 toplevel title='%s' app_id='%s'", | ||
73 | xdg_surface->title, xdg_surface->app_id); | ||
74 | wlr_xdg_surface_v6_ping(xdg_surface); | ||
75 | |||
76 | struct sway_xdg_surface_v6 *sway_surface = | ||
77 | calloc(1, sizeof(struct sway_xdg_surface_v6)); | ||
78 | if (!sway_assert(sway_surface, "Failed to allocate surface!")) { | ||
79 | return; | ||
80 | } | ||
81 | |||
82 | struct sway_view *sway_view = calloc(1, sizeof(struct sway_view)); | ||
83 | if (!sway_assert(sway_view, "Failed to allocate view!")) { | ||
84 | return; | ||
85 | } | ||
86 | sway_view->type = SWAY_XDG_SHELL_V6_VIEW; | ||
87 | sway_view->iface.get_prop = get_prop; | ||
88 | sway_surface->view = sway_view; | ||
89 | |||
90 | // TODO: | ||
91 | // - Consolodate common logic between shells | ||
92 | // - Wire up listeners | ||
93 | // - Handle popups | ||
94 | // - Look up pid and open on appropriate workspace | ||
95 | // - Set new view to maximized so it behaves nicely | ||
96 | // - Criteria | ||
97 | |||
98 | suspend_workspace_cleanup = true; | ||
99 | //swayc_t *current_ws = swayc_active_workspace(); | ||
100 | swayc_t *prev_focus = get_focused_container(&root_container); | ||
101 | swayc_t *focused = move_focus_to_tiling(prev_focus); | ||
102 | |||
103 | // TODO: fix new_view | ||
104 | swayc_t *view = new_view(focused, sway_view); | ||
105 | ipc_event_window(view, "new"); | ||
106 | set_focused_container(view); | ||
107 | |||
108 | swayc_t *output = swayc_parent_by_type(view, C_OUTPUT); | ||
109 | arrange_windows(output, -1, -1); | ||
110 | |||
111 | swayc_t *workspace = swayc_parent_by_type(focused, C_WORKSPACE); | ||
112 | if (workspace && workspace->fullscreen) { | ||
113 | set_focused_container(workspace->fullscreen); | ||
114 | } | ||
115 | suspend_workspace_cleanup = false; | ||
116 | temp_ws_cleanup(); | ||
117 | } | ||
diff --git a/sway/server.c b/sway/server.c index a7f47af3..940f28b3 100644 --- a/sway/server.c +++ b/sway/server.c | |||
@@ -34,6 +34,11 @@ bool server_init(struct sway_server *server) { | |||
34 | wl_signal_add(&server->backend->events.output_remove, | 34 | wl_signal_add(&server->backend->events.output_remove, |
35 | &server->output_remove); | 35 | &server->output_remove); |
36 | 36 | ||
37 | server->xdg_shell_v6 = wlr_xdg_shell_v6_create(server->wl_display); | ||
38 | wl_signal_add(&server->xdg_shell_v6->events.new_surface, | ||
39 | &server->xdg_shell_v6_surface); | ||
40 | server->xdg_shell_v6_surface.notify = handle_xdg_shell_v6_surface; | ||
41 | |||
37 | server->socket = wl_display_add_socket_auto(server->wl_display); | 42 | server->socket = wl_display_add_socket_auto(server->wl_display); |
38 | if (!sway_assert(server->socket, "Unable to open wayland socket")) { | 43 | if (!sway_assert(server->socket, "Unable to open wayland socket")) { |
39 | wlr_backend_destroy(server->backend); | 44 | wlr_backend_destroy(server->backend); |
diff --git a/sway/tree/container.c b/sway/tree/container.c index 25bb858e..82c0d877 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include "sway/input_state.h" | 15 | #include "sway/input_state.h" |
16 | #include "sway/ipc-server.h" | 16 | #include "sway/ipc-server.h" |
17 | #include "sway/output.h" | 17 | #include "sway/output.h" |
18 | #include "sway/view.h" | ||
18 | #include "log.h" | 19 | #include "log.h" |
19 | #include "stringop.h" | 20 | #include "stringop.h" |
20 | 21 | ||
@@ -291,44 +292,49 @@ swayc_t *new_container(swayc_t *child, enum swayc_layouts layout) { | |||
291 | return cont; | 292 | return cont; |
292 | } | 293 | } |
293 | 294 | ||
294 | swayc_t *new_view(swayc_t *sibling, wlc_handle handle) { | 295 | swayc_t *new_view(swayc_t *sibling, struct sway_view *view) { |
295 | if (!ASSERT_NONNULL(sibling)) { | 296 | if (!ASSERT_NONNULL(sibling)) { |
296 | return NULL; | 297 | return NULL; |
297 | } | 298 | } |
298 | const char *title = wlc_view_get_title(handle); | 299 | const char *title = view->iface.get_prop(view, VIEW_PROP_TITLE); |
299 | swayc_t *view = new_swayc(C_VIEW); | 300 | swayc_t *swayc = new_swayc(C_VIEW); |
300 | sway_log(L_DEBUG, "Adding new view %" PRIuPTR ":%s to container %p %d", | 301 | sway_log(L_DEBUG, "Adding new view %p:%s to container %p %d", |
301 | handle, title, sibling, sibling ? sibling->type : 0); | 302 | swayc, title, sibling, sibling ? sibling->type : 0); |
302 | // Setup values | 303 | // Setup values |
303 | view->handle = handle; | 304 | swayc->_handle.view = view; |
304 | view->name = title ? strdup(title) : NULL; | 305 | |
305 | const char *class = wlc_view_get_class(handle); | 306 | swayc->name = title ? strdup(title) : NULL; |
306 | view->class = class ? strdup(class) : NULL; | 307 | |
307 | const char *instance = wlc_view_get_instance(handle); | 308 | const char *class = view->iface.get_prop(view, VIEW_PROP_CLASS); |
308 | view->instance = instance ? strdup(instance) : NULL; | 309 | swayc->class = class ? strdup(class) : NULL; |
309 | const char *app_id = wlc_view_get_app_id(handle); | 310 | |
310 | view->app_id = app_id ? strdup(app_id) : NULL; | 311 | const char *instance = view->iface.get_prop(view, VIEW_PROP_INSTANCE); |
311 | view->visible = true; | 312 | swayc->instance = instance ? strdup(instance) : NULL; |
312 | view->is_focused = true; | 313 | |
313 | view->sticky = false; | 314 | const char *app_id = view->iface.get_prop(view, VIEW_PROP_APP_ID); |
314 | view->width = 0; | 315 | swayc->app_id = app_id ? strdup(app_id) : NULL; |
315 | view->height = 0; | 316 | |
316 | view->desired_width = -1; | 317 | swayc->visible = true; |
317 | view->desired_height = -1; | 318 | swayc->is_focused = true; |
319 | swayc->sticky = false; | ||
320 | swayc->width = 0; | ||
321 | swayc->height = 0; | ||
322 | swayc->desired_width = -1; | ||
323 | swayc->desired_height = -1; | ||
318 | // setup border | 324 | // setup border |
319 | view->border_type = config->border; | 325 | swayc->border_type = config->border; |
320 | view->border_thickness = config->border_thickness; | 326 | swayc->border_thickness = config->border_thickness; |
321 | 327 | ||
322 | view->is_floating = false; | 328 | swayc->is_floating = false; |
323 | 329 | ||
324 | if (sibling->type == C_WORKSPACE) { | 330 | if (sibling->type == C_WORKSPACE) { |
325 | // Case of focused workspace, just create as child of it | 331 | // Case of focused workspace, just create as child of it |
326 | add_child(sibling, view); | 332 | add_child(sibling, swayc); |
327 | } else { | 333 | } else { |
328 | // Regular case, create as sibling of current container | 334 | // Regular case, create as sibling of current container |
329 | add_sibling(sibling, view); | 335 | add_sibling(sibling, swayc); |
330 | } | 336 | } |
331 | return view; | 337 | return swayc; |
332 | } | 338 | } |
333 | 339 | ||
334 | swayc_t *new_floating_view(wlc_handle handle) { | 340 | swayc_t *new_floating_view(wlc_handle handle) { |