diff options
Diffstat (limited to 'sway/desktop/xdg_shell_v6.c')
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 117 |
1 files changed, 117 insertions, 0 deletions
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 | } | ||