diff options
author | Drew DeVault <sir@cmpwn.com> | 2017-11-11 18:06:50 -0500 |
---|---|---|
committer | Drew DeVault <sir@cmpwn.com> | 2017-11-11 18:06:50 -0500 |
commit | 0c8491f7d0c735299a25f0ab929f5d1e0866b929 (patch) | |
tree | 69fc808ce6b8ceda33e8fadcf7cbbc10b892ca00 /sway | |
parent | 1efd5f819f9986bf27e390f4988359388606cea0 (diff) | |
download | sway-0c8491f7d0c735299a25f0ab929f5d1e0866b929.tar.xz |
Initial (awful) pass on xdg shell support
Diffstat (limited to 'sway')
-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 |
5 files changed, 156 insertions, 27 deletions
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 add_executable(sway desktop/output.c + desktop/xdg_shell_v6.c tree/container.c 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) { static void invoke_swaybar(struct bar_config *bar) { return; // TODO WLR + sway_log(L_DEBUG, "Invoking swaybar for bar id '%s'", bar->id); // Pipe to communicate errors int filedes[2]; if (pipe(filedes) == -1) { @@ -1059,7 +1060,6 @@ void load_swaybars() { if (bar->pid != 0) { terminate_swaybar(bar->pid); } - sway_log(L_DEBUG, "Invoking swaybar for bar id '%s'", bar->id); invoke_swaybar(bar); } 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 @@ +#include <stdlib.h> +#include <wayland-server.h> +#include <wlr/types/wlr_xdg_shell_v6.h> +#include "sway/commands.h" +#include "sway/container.h" +#include "sway/focus.h" +#include "sway/ipc-server.h" +#include "sway/server.h" +#include "sway/view.h" +#include "log.h" + +// TODO: move elsewhere +static void temp_ws_cleanup() { + swayc_t *op, *ws; + int i = 0, j; + if (!root_container.children) + return; + while (i < root_container.children->length) { + op = root_container.children->items[i++]; + if (!op->children) + continue; + j = 0; + while (j < op->children->length) { + ws = op->children->items[j++]; + if (ws->children->length == 0 && ws->floating->length == 0 && ws != op->focused) { + if (destroy_workspace(ws)) { + j--; + } + } + } + } +} + +// TODO: move elsewhere +static swayc_t *move_focus_to_tiling(swayc_t *focused) { + if (focused->is_floating) { + if (focused->parent->children->length == 0) { + return focused->parent; + } + // TODO find a better way of doing this + // Or to focused container + return get_focused_container(focused->parent->children->items[0]); + } + return focused; +} + +static const char *get_prop(struct sway_view *view, enum sway_view_prop prop) { + if (!sway_assert(view->type == SWAY_XDG_SHELL_V6_VIEW, + "xdg get_prop for non-xdg view!")) { + return NULL; + } + switch (prop) { + case VIEW_PROP_TITLE: + return view->wlr_xdg_surface_v6->title; + case VIEW_PROP_APP_ID: + return view->wlr_xdg_surface_v6->app_id; + default: + return NULL; + } +} + +void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) { + struct sway_server *server = wl_container_of( + listener, server, xdg_shell_v6_surface); + struct wlr_xdg_surface_v6 *xdg_surface = data; + + if (xdg_surface->role == WLR_XDG_SURFACE_V6_ROLE_POPUP) { + // TODO: popups + return; + } + + sway_log(L_DEBUG, "New xdg_shell_v6 toplevel title='%s' app_id='%s'", + xdg_surface->title, xdg_surface->app_id); + wlr_xdg_surface_v6_ping(xdg_surface); + + struct sway_xdg_surface_v6 *sway_surface = + calloc(1, sizeof(struct sway_xdg_surface_v6)); + if (!sway_assert(sway_surface, "Failed to allocate surface!")) { + return; + } + + struct sway_view *sway_view = calloc(1, sizeof(struct sway_view)); + if (!sway_assert(sway_view, "Failed to allocate view!")) { + return; + } + sway_view->type = SWAY_XDG_SHELL_V6_VIEW; + sway_view->iface.get_prop = get_prop; + sway_surface->view = sway_view; + + // TODO: + // - Consolodate common logic between shells + // - Wire up listeners + // - Handle popups + // - Look up pid and open on appropriate workspace + // - Set new view to maximized so it behaves nicely + // - Criteria + + suspend_workspace_cleanup = true; + //swayc_t *current_ws = swayc_active_workspace(); + swayc_t *prev_focus = get_focused_container(&root_container); + swayc_t *focused = move_focus_to_tiling(prev_focus); + + // TODO: fix new_view + swayc_t *view = new_view(focused, sway_view); + ipc_event_window(view, "new"); + set_focused_container(view); + + swayc_t *output = swayc_parent_by_type(view, C_OUTPUT); + arrange_windows(output, -1, -1); + + swayc_t *workspace = swayc_parent_by_type(focused, C_WORKSPACE); + if (workspace && workspace->fullscreen) { + set_focused_container(workspace->fullscreen); + } + suspend_workspace_cleanup = false; + temp_ws_cleanup(); +} 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) { wl_signal_add(&server->backend->events.output_remove, &server->output_remove); + server->xdg_shell_v6 = wlr_xdg_shell_v6_create(server->wl_display); + wl_signal_add(&server->xdg_shell_v6->events.new_surface, + &server->xdg_shell_v6_surface); + server->xdg_shell_v6_surface.notify = handle_xdg_shell_v6_surface; + server->socket = wl_display_add_socket_auto(server->wl_display); if (!sway_assert(server->socket, "Unable to open wayland socket")) { 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 @@ #include "sway/input_state.h" #include "sway/ipc-server.h" #include "sway/output.h" +#include "sway/view.h" #include "log.h" #include "stringop.h" @@ -291,44 +292,49 @@ swayc_t *new_container(swayc_t *child, enum swayc_layouts layout) { return cont; } -swayc_t *new_view(swayc_t *sibling, wlc_handle handle) { +swayc_t *new_view(swayc_t *sibling, struct sway_view *view) { if (!ASSERT_NONNULL(sibling)) { return NULL; } - const char *title = wlc_view_get_title(handle); - swayc_t *view = new_swayc(C_VIEW); - sway_log(L_DEBUG, "Adding new view %" PRIuPTR ":%s to container %p %d", - handle, title, sibling, sibling ? sibling->type : 0); + const char *title = view->iface.get_prop(view, VIEW_PROP_TITLE); + swayc_t *swayc = new_swayc(C_VIEW); + sway_log(L_DEBUG, "Adding new view %p:%s to container %p %d", + swayc, title, sibling, sibling ? sibling->type : 0); // Setup values - view->handle = handle; - view->name = title ? strdup(title) : NULL; - const char *class = wlc_view_get_class(handle); - view->class = class ? strdup(class) : NULL; - const char *instance = wlc_view_get_instance(handle); - view->instance = instance ? strdup(instance) : NULL; - const char *app_id = wlc_view_get_app_id(handle); - view->app_id = app_id ? strdup(app_id) : NULL; - view->visible = true; - view->is_focused = true; - view->sticky = false; - view->width = 0; - view->height = 0; - view->desired_width = -1; - view->desired_height = -1; + swayc->_handle.view = view; + + swayc->name = title ? strdup(title) : NULL; + + const char *class = view->iface.get_prop(view, VIEW_PROP_CLASS); + swayc->class = class ? strdup(class) : NULL; + + const char *instance = view->iface.get_prop(view, VIEW_PROP_INSTANCE); + swayc->instance = instance ? strdup(instance) : NULL; + + const char *app_id = view->iface.get_prop(view, VIEW_PROP_APP_ID); + swayc->app_id = app_id ? strdup(app_id) : NULL; + + swayc->visible = true; + swayc->is_focused = true; + swayc->sticky = false; + swayc->width = 0; + swayc->height = 0; + swayc->desired_width = -1; + swayc->desired_height = -1; // setup border - view->border_type = config->border; - view->border_thickness = config->border_thickness; + swayc->border_type = config->border; + swayc->border_thickness = config->border_thickness; - view->is_floating = false; + swayc->is_floating = false; if (sibling->type == C_WORKSPACE) { // Case of focused workspace, just create as child of it - add_child(sibling, view); + add_child(sibling, swayc); } else { // Regular case, create as sibling of current container - add_sibling(sibling, view); + add_sibling(sibling, swayc); } - return view; + return swayc; } swayc_t *new_floating_view(wlc_handle handle) { |