diff options
author | Drew DeVault <sir@cmpwn.com> | 2018-02-27 20:17:08 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-02-27 20:17:08 -0500 |
commit | 8a97d3a4941f2f46021ff83b98d684676f53e8c1 (patch) | |
tree | c3d61812289a8de405c601f7657d371bbe378f89 | |
parent | Utilize wlr_xwayland_surface_is_unmanaged (diff) | |
parent | ipc new window event (diff) | |
download | sway-8a97d3a4941f2f46021ff83b98d684676f53e8c1.tar.gz sway-8a97d3a4941f2f46021ff83b98d684676f53e8c1.tar.zst sway-8a97d3a4941f2f46021ff83b98d684676f53e8c1.zip |
Merge pull request #1611 from acrisci/ipc-new-window
Ipc new window
-rw-r--r-- | include/sway/ipc-server.h | 3 | ||||
-rw-r--r-- | sway/ipc-server.c | 90 | ||||
-rw-r--r-- | sway/tree/container.c | 12 |
3 files changed, 102 insertions, 3 deletions
diff --git a/include/sway/ipc-server.h b/include/sway/ipc-server.h index b85ff535..bcf1c433 100644 --- a/include/sway/ipc-server.h +++ b/include/sway/ipc-server.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef _SWAY_IPC_SERVER_H | 1 | #ifndef _SWAY_IPC_SERVER_H |
2 | #define _SWAY_IPC_SERVER_H | 2 | #define _SWAY_IPC_SERVER_H |
3 | #include <sys/socket.h> | 3 | #include <sys/socket.h> |
4 | #include "sway/container.h" | ||
4 | #include "ipc.h" | 5 | #include "ipc.h" |
5 | 6 | ||
6 | struct sway_server; | 7 | struct sway_server; |
@@ -9,4 +10,6 @@ void ipc_init(struct sway_server *server); | |||
9 | void ipc_terminate(void); | 10 | void ipc_terminate(void); |
10 | struct sockaddr_un *ipc_user_sockaddr(void); | 11 | struct sockaddr_un *ipc_user_sockaddr(void); |
11 | 12 | ||
13 | void ipc_event_window(swayc_t *window, const char *change); | ||
14 | |||
12 | #endif | 15 | #endif |
diff --git a/sway/ipc-server.c b/sway/ipc-server.c index 4c0953e8..156de380 100644 --- a/sway/ipc-server.c +++ b/sway/ipc-server.c | |||
@@ -240,6 +240,57 @@ int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data) { | |||
240 | return 0; | 240 | return 0; |
241 | } | 241 | } |
242 | 242 | ||
243 | static void ipc_send_event(const char *json_string, enum ipc_command_type event) { | ||
244 | static struct { | ||
245 | enum ipc_command_type event; | ||
246 | enum ipc_feature feature; | ||
247 | } security_mappings[] = { | ||
248 | { IPC_EVENT_WORKSPACE, IPC_FEATURE_EVENT_WORKSPACE }, | ||
249 | { IPC_EVENT_OUTPUT, IPC_FEATURE_EVENT_OUTPUT }, | ||
250 | { IPC_EVENT_MODE, IPC_FEATURE_EVENT_MODE }, | ||
251 | { IPC_EVENT_WINDOW, IPC_FEATURE_EVENT_WINDOW }, | ||
252 | { IPC_EVENT_BINDING, IPC_FEATURE_EVENT_BINDING }, | ||
253 | { IPC_EVENT_INPUT, IPC_FEATURE_EVENT_INPUT } | ||
254 | }; | ||
255 | |||
256 | uint32_t security_mask = 0; | ||
257 | for (size_t i = 0; i < sizeof(security_mappings) / sizeof(security_mappings[0]); ++i) { | ||
258 | if (security_mappings[i].event == event) { | ||
259 | security_mask = security_mappings[i].feature; | ||
260 | break; | ||
261 | } | ||
262 | } | ||
263 | |||
264 | int i; | ||
265 | struct ipc_client *client; | ||
266 | for (i = 0; i < ipc_client_list->length; i++) { | ||
267 | client = ipc_client_list->items[i]; | ||
268 | if (!(client->security_policy & security_mask)) { | ||
269 | continue; | ||
270 | } | ||
271 | if ((client->subscribed_events & event_mask(event)) == 0) { | ||
272 | continue; | ||
273 | } | ||
274 | client->current_command = event; | ||
275 | if (!ipc_send_reply(client, json_string, (uint32_t) strlen(json_string))) { | ||
276 | wlr_log_errno(L_INFO, "Unable to send reply to IPC client"); | ||
277 | ipc_client_disconnect(client); | ||
278 | } | ||
279 | } | ||
280 | } | ||
281 | |||
282 | void ipc_event_window(swayc_t *window, const char *change) { | ||
283 | wlr_log(L_DEBUG, "Sending window::%s event", change); | ||
284 | json_object *obj = json_object_new_object(); | ||
285 | json_object_object_add(obj, "change", json_object_new_string(change)); | ||
286 | json_object_object_add(obj, "container", ipc_json_describe_container_recursive(window)); | ||
287 | |||
288 | const char *json_string = json_object_to_json_string(obj); | ||
289 | ipc_send_event(json_string, IPC_EVENT_WINDOW); | ||
290 | |||
291 | json_object_put(obj); // free | ||
292 | } | ||
293 | |||
243 | int ipc_client_handle_writable(int client_fd, uint32_t mask, void *data) { | 294 | int ipc_client_handle_writable(int client_fd, uint32_t mask, void *data) { |
244 | struct ipc_client *client = data; | 295 | struct ipc_client *client = data; |
245 | 296 | ||
@@ -361,6 +412,45 @@ void ipc_client_handle_command(struct ipc_client *client) { | |||
361 | goto exit_cleanup; | 412 | goto exit_cleanup; |
362 | } | 413 | } |
363 | 414 | ||
415 | case IPC_SUBSCRIBE: | ||
416 | { | ||
417 | // TODO: Check if they're permitted to use these events | ||
418 | struct json_object *request = json_tokener_parse(buf); | ||
419 | if (request == NULL) { | ||
420 | ipc_send_reply(client, "{\"success\": false}", 18); | ||
421 | wlr_log_errno(L_INFO, "Failed to read request"); | ||
422 | goto exit_cleanup; | ||
423 | } | ||
424 | |||
425 | // parse requested event types | ||
426 | for (size_t i = 0; i < json_object_array_length(request); i++) { | ||
427 | const char *event_type = json_object_get_string(json_object_array_get_idx(request, i)); | ||
428 | if (strcmp(event_type, "workspace") == 0) { | ||
429 | client->subscribed_events |= event_mask(IPC_EVENT_WORKSPACE); | ||
430 | } else if (strcmp(event_type, "barconfig_update") == 0) { | ||
431 | client->subscribed_events |= event_mask(IPC_EVENT_BARCONFIG_UPDATE); | ||
432 | } else if (strcmp(event_type, "mode") == 0) { | ||
433 | client->subscribed_events |= event_mask(IPC_EVENT_MODE); | ||
434 | } else if (strcmp(event_type, "window") == 0) { | ||
435 | client->subscribed_events |= event_mask(IPC_EVENT_WINDOW); | ||
436 | } else if (strcmp(event_type, "modifier") == 0) { | ||
437 | client->subscribed_events |= event_mask(IPC_EVENT_MODIFIER); | ||
438 | } else if (strcmp(event_type, "binding") == 0) { | ||
439 | client->subscribed_events |= event_mask(IPC_EVENT_BINDING); | ||
440 | } else { | ||
441 | ipc_send_reply(client, "{\"success\": false}", 18); | ||
442 | json_object_put(request); | ||
443 | wlr_log_errno(L_INFO, "Failed to parse request"); | ||
444 | goto exit_cleanup; | ||
445 | } | ||
446 | } | ||
447 | |||
448 | json_object_put(request); | ||
449 | |||
450 | ipc_send_reply(client, "{\"success\": true}", 17); | ||
451 | goto exit_cleanup; | ||
452 | } | ||
453 | |||
364 | case IPC_GET_INPUTS: | 454 | case IPC_GET_INPUTS: |
365 | { | 455 | { |
366 | json_object *inputs = json_object_new_array(); | 456 | json_object *inputs = json_object_new_array(); |
diff --git a/sway/tree/container.c b/sway/tree/container.c index fafbdb03..b424dd0a 100644 --- a/sway/tree/container.c +++ b/sway/tree/container.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include "sway/server.h" | 15 | #include "sway/server.h" |
16 | #include "sway/view.h" | 16 | #include "sway/view.h" |
17 | #include "sway/workspace.h" | 17 | #include "sway/workspace.h" |
18 | #include "sway/ipc-server.h" | ||
18 | #include "log.h" | 19 | #include "log.h" |
19 | 20 | ||
20 | static list_t *bfs_queue; | 21 | static list_t *bfs_queue; |
@@ -32,6 +33,11 @@ static list_t *get_bfs_queue() { | |||
32 | return bfs_queue; | 33 | return bfs_queue; |
33 | } | 34 | } |
34 | 35 | ||
36 | static void notify_new_container(swayc_t *container) { | ||
37 | wl_signal_emit(&root_container.sway_root->events.new_container, container); | ||
38 | ipc_event_window(container, "new"); | ||
39 | } | ||
40 | |||
35 | swayc_t *swayc_by_test(swayc_t *container, | 41 | swayc_t *swayc_by_test(swayc_t *container, |
36 | bool (*test)(swayc_t *view, void *data), void *data) { | 42 | bool (*test)(swayc_t *view, void *data), void *data) { |
37 | if (!container->children) { | 43 | if (!container->children) { |
@@ -175,7 +181,7 @@ swayc_t *new_output(struct sway_output *sway_output) { | |||
175 | } | 181 | } |
176 | 182 | ||
177 | free(ws_name); | 183 | free(ws_name); |
178 | wl_signal_emit(&root_container.sway_root->events.new_container, output); | 184 | notify_new_container(output); |
179 | return output; | 185 | return output; |
180 | } | 186 | } |
181 | 187 | ||
@@ -197,7 +203,7 @@ swayc_t *new_workspace(swayc_t *output, const char *name) { | |||
197 | 203 | ||
198 | add_child(output, workspace); | 204 | add_child(output, workspace); |
199 | sort_workspaces(output); | 205 | sort_workspaces(output); |
200 | wl_signal_emit(&root_container.sway_root->events.new_container, workspace); | 206 | notify_new_container(workspace); |
201 | return workspace; | 207 | return workspace; |
202 | } | 208 | } |
203 | 209 | ||
@@ -222,7 +228,7 @@ swayc_t *new_view(swayc_t *sibling, struct sway_view *sway_view) { | |||
222 | // Regular case, create as sibling of current container | 228 | // Regular case, create as sibling of current container |
223 | add_sibling(sibling, swayc); | 229 | add_sibling(sibling, swayc); |
224 | } | 230 | } |
225 | wl_signal_emit(&root_container.sway_root->events.new_container, swayc); | 231 | notify_new_container(swayc); |
226 | return swayc; | 232 | return swayc; |
227 | } | 233 | } |
228 | 234 | ||