diff options
author | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-06-29 20:04:24 +1000 |
---|---|---|
committer | Ryan Dwyer <ryandwyer1@gmail.com> | 2018-06-29 20:04:24 +1000 |
commit | a2fbb20a616444213ff3967b33eed7f4561e3978 (patch) | |
tree | 276a133eb78d6e0655bc164693650454d43a22ca /sway/desktop | |
parent | 3c81a900b766dd2c049ba7af6e603805893e0926 (diff) | |
parent | d3ea07f8283385d015e1d85b5fe9bc8a776fc7b4 (diff) | |
download | sway-a2fbb20a616444213ff3967b33eed7f4561e3978.tar.xz |
Merge remote-tracking branch 'upstream/master' into atomic
Diffstat (limited to 'sway/desktop')
-rw-r--r-- | sway/desktop/layer_shell.c | 9 | ||||
-rw-r--r-- | sway/desktop/output.c | 3 | ||||
-rw-r--r-- | sway/desktop/xdg_shell.c | 9 | ||||
-rw-r--r-- | sway/desktop/xdg_shell_v6.c | 10 | ||||
-rw-r--r-- | sway/desktop/xwayland.c | 94 |
5 files changed, 100 insertions, 25 deletions
diff --git a/sway/desktop/layer_shell.c b/sway/desktop/layer_shell.c index fe5fc316..ff37bbf1 100644 --- a/sway/desktop/layer_shell.c +++ b/sway/desktop/layer_shell.c @@ -219,6 +219,8 @@ static void handle_output_destroy(struct wl_listener *listener, void *data) { struct sway_layer_surface *sway_layer = wl_container_of(listener, sway_layer, output_destroy); wl_list_remove(&sway_layer->output_destroy.link); + wl_list_remove(&sway_layer->link); + wl_list_init(&sway_layer->link); sway_layer->layer_surface->output = NULL; wlr_layer_surface_close(sway_layer->layer_surface); } @@ -350,10 +352,6 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) { wl_signal_add(&layer_surface->surface->events.commit, &sway_layer->surface_commit); - sway_layer->output_destroy.notify = handle_output_destroy; - wl_signal_add(&layer_surface->output->events.destroy, - &sway_layer->output_destroy); - sway_layer->destroy.notify = handle_destroy; wl_signal_add(&layer_surface->events.destroy, &sway_layer->destroy); sway_layer->map.notify = handle_map; @@ -366,6 +364,9 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) { layer_surface->data = sway_layer; struct sway_output *output = layer_surface->output->data; + sway_layer->output_destroy.notify = handle_output_destroy; + wl_signal_add(&output->events.destroy, &sway_layer->output_destroy); + wl_list_insert(&output->layers[layer_surface->layer], &sway_layer->link); // Temporarily set the layer's current state to client_pending diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 34fefaa9..69d0bdd4 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -1263,6 +1263,8 @@ static void damage_handle_destroy(struct wl_listener *listener, void *data) { static void handle_destroy(struct wl_listener *listener, void *data) { struct sway_output *output = wl_container_of(listener, output, destroy); + wl_signal_emit(&output->events.destroy, output); + if (output->swayc) { container_destroy(output->swayc); } @@ -1343,6 +1345,7 @@ void output_enable(struct sway_output *output) { for (size_t i = 0; i < len; ++i) { wl_list_init(&output->layers[i]); } + wl_signal_init(&output->events.destroy); input_manager_configure_xcursor(input_manager); diff --git a/sway/desktop/xdg_shell.c b/sway/desktop/xdg_shell.c index b076d772..0f45399d 100644 --- a/sway/desktop/xdg_shell.c +++ b/sway/desktop/xdg_shell.c @@ -117,11 +117,12 @@ static void set_fullscreen(struct sway_view *view, bool fullscreen) { } static bool wants_floating(struct sway_view *view) { - struct wlr_xdg_toplevel_state *state = - &view->wlr_xdg_surface->toplevel->current; - return state->min_width != 0 && state->min_height != 0 + struct wlr_xdg_toplevel *toplevel = view->wlr_xdg_surface->toplevel; + struct wlr_xdg_toplevel_state *state = &toplevel->current; + return (state->min_width != 0 && state->min_height != 0 && state->min_width == state->max_width - && state->min_height == state->max_height; + && state->min_height == state->max_height) + || toplevel->parent; } static void for_each_surface(struct sway_view *view, diff --git a/sway/desktop/xdg_shell_v6.c b/sway/desktop/xdg_shell_v6.c index 7320e629..b296f1a8 100644 --- a/sway/desktop/xdg_shell_v6.c +++ b/sway/desktop/xdg_shell_v6.c @@ -117,11 +117,13 @@ static void set_fullscreen(struct sway_view *view, bool fullscreen) { } static bool wants_floating(struct sway_view *view) { - struct wlr_xdg_toplevel_v6_state *state = - &view->wlr_xdg_surface_v6->toplevel->current; - return state->min_width != 0 && state->min_height != 0 + struct wlr_xdg_toplevel_v6 *toplevel = + view->wlr_xdg_surface_v6->toplevel; + struct wlr_xdg_toplevel_v6_state *state = &toplevel->current; + return (state->min_width != 0 && state->min_height != 0 && state->min_width == state->max_width - && state->min_height == state->max_height; + && state->min_height == state->max_height) + || toplevel->parent; } static void for_each_surface(struct sway_view *view, diff --git a/sway/desktop/xwayland.c b/sway/desktop/xwayland.c index 854da006..023fb2a7 100644 --- a/sway/desktop/xwayland.c +++ b/sway/desktop/xwayland.c @@ -17,6 +17,14 @@ #include "sway/tree/layout.h" #include "sway/tree/view.h" +static const char *atom_map[ATOM_LAST] = { + "_NET_WM_WINDOW_TYPE_DIALOG", + "_NET_WM_WINDOW_TYPE_UTILITY", + "_NET_WM_WINDOW_TYPE_TOOLBAR", + "_NET_WM_WINDOW_TYPE_SPLASH", + "_NET_WM_STATE_MODAL", +}; + static void unmanaged_handle_request_configure(struct wl_listener *listener, void *data) { struct sway_xwayland_unmanaged *surface = @@ -63,7 +71,8 @@ static void unmanaged_handle_map(struct wl_listener *listener, void *data) { if (!wlr_xwayland_surface_is_unmanaged(xsurface)) { struct sway_seat *seat = input_manager_current_seat(input_manager); - struct wlr_xwayland *xwayland = seat->input->server->xwayland; + struct wlr_xwayland *xwayland = + seat->input->server->xwayland.wlr_xwayland; wlr_xwayland_set_seat(xwayland, seat->wlr_seat); seat_set_focus_surface(seat, xsurface->surface); } @@ -200,15 +209,32 @@ static void set_fullscreen(struct sway_view *view, bool fullscreen) { } static bool wants_floating(struct sway_view *view) { - // TODO: - // We want to return true if the window type contains any of these: - // NET_WM_WINDOW_TYPE_DIALOG - // NET_WM_WINDOW_TYPE_UTILITY - // NET_WM_WINDOW_TYPE_TOOLBAR - // NET_WM_WINDOW_TYPE_SPLASH - // - // We also want to return true if the NET_WM_STATE is MODAL. - // wlroots doesn't appear to provide all this information at the moment. + if (xwayland_view_from_view(view) == NULL) { + return false; + } + struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface; + struct sway_xwayland *xwayland = &server.xwayland; + + // TODO: return true if the NET_WM_STATE is MODAL + + for (size_t i = 0; i < surface->window_type_len; ++i) { + xcb_atom_t type = surface->window_type[i]; + if (type == xwayland->atoms[NET_WM_WINDOW_TYPE_DIALOG] || + type == xwayland->atoms[NET_WM_WINDOW_TYPE_UTILITY] || + type == xwayland->atoms[NET_WM_WINDOW_TYPE_TOOLBAR] || + type == xwayland->atoms[NET_WM_WINDOW_TYPE_SPLASH]) { + return true; + } + } + + struct wlr_xwayland_surface_size_hints *size_hints = surface->size_hints; + if (size_hints != NULL && + size_hints->min_width != 0 && size_hints->min_height != 0 && + size_hints->max_width == size_hints->min_width && + size_hints->max_height == size_hints->min_height) { + return true; + } + return false; } @@ -324,9 +350,14 @@ static void handle_request_configure(struct wl_listener *listener, void *data) { ev->width, ev->height); return; } - // TODO: Let floating views do whatever - configure(view, view->swayc->current.view_x, view->swayc->current.view_y, - view->swayc->current.view_width, view->swayc->current.view_height); + if (container_is_floating(view->swayc)) { + configure(view, view->swayc->current.view_x, + view->swayc->current.view_y, ev->width, ev->height); + } else { + configure(view, view->swayc->current.view_x, + view->swayc->current.view_y, view->swayc->current.view_width, + view->swayc->current.view_height); + } } static void handle_request_fullscreen(struct wl_listener *listener, void *data) { @@ -431,3 +462,40 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) { wl_signal_add(&xsurface->events.map, &xwayland_view->map); xwayland_view->map.notify = handle_map; } + +void handle_xwayland_ready(struct wl_listener *listener, void *data) { + struct sway_server *server = + wl_container_of(listener, server, xwayland_ready); + struct sway_xwayland *xwayland = &server->xwayland; + + xcb_connection_t *xcb_conn = xcb_connect(NULL, NULL); + int err = xcb_connection_has_error(xcb_conn); + if (err) { + wlr_log(L_ERROR, "XCB connect failed: %d", err); + return; + } + + xcb_intern_atom_cookie_t cookies[ATOM_LAST]; + for (size_t i = 0; i < ATOM_LAST; i++) { + cookies[i] = + xcb_intern_atom(xcb_conn, 0, strlen(atom_map[i]), atom_map[i]); + } + for (size_t i = 0; i < ATOM_LAST; i++) { + xcb_generic_error_t *error = NULL; + xcb_intern_atom_reply_t *reply = + xcb_intern_atom_reply(xcb_conn, cookies[i], &error); + if (reply != NULL && error == NULL) { + xwayland->atoms[i] = reply->atom; + } + free(reply); + + if (error != NULL) { + wlr_log(L_ERROR, "could not resolve atom %s, X11 error code %d", + atom_map[i], error->error_code); + free(error); + break; + } + } + + xcb_disconnect(xcb_conn); +} |