Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/sway/server.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,12 @@ struct sway_server {
struct wlr_ext_workspace_manager_v1 *workspace_manager_v1;
struct wl_listener workspace_manager_v1_commit;

struct {
char *dir;
FILE *urandom;
struct wl_listener new_session;
} xdg_session_manager_v1;

struct wl_list pending_launcher_ctxs; // launcher_ctx::link

// The timeout for transactions, after which a transaction is applied
Expand Down
15 changes: 15 additions & 0 deletions include/sway/tree/view.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ struct sway_view_impl {
struct sway_view *ancestor);
void (*close)(struct sway_view *view);
void (*close_popups)(struct sway_view *view);
void (*notify_state_update)(struct sway_view *view);
void (*destroy)(struct sway_view *view);
};

Expand Down Expand Up @@ -113,6 +114,12 @@ struct sway_view {
#endif
};

struct {
bool pending;
char *workspace;
bool floating;
} session_restore;

struct {
struct wl_signal unmap;
} events;
Expand All @@ -131,6 +138,12 @@ struct sway_xdg_shell_view {
struct wlr_scene_tree *image_capture_tree;
char *tag;

struct {
struct sway_xdg_session_v1 *session;
char *name;
struct wl_list link; // sway_xdg_session_v1.toplevels
} xdg_session_v1;

struct wl_listener commit;
struct wl_listener request_move;
struct wl_listener request_resize;
Expand Down Expand Up @@ -366,4 +379,6 @@ bool view_can_tear(struct sway_view *view);

void xdg_toplevel_tag_manager_v1_handle_set_tag(struct wl_listener *listener, void *data);

void view_notify_state_update(struct sway_view *view);

#endif
12 changes: 12 additions & 0 deletions include/sway/xdg_session_management_v1.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#ifndef _SWAY_XDG_SESSION_MANAGEMENT_V1_H
#define _SWAY_XDG_SESSION_MANAGEMENT_V1_H

struct sway_xdg_session_v1;

bool init_xdg_session_management_v1(struct sway_server *server);
void finish_xdg_session_management_v1(struct sway_server *server);

void notify_xdg_session_management_v1_toplevel_initial_configure(struct sway_xdg_shell_view *view);
void notify_xdg_session_management_v1_toplevel_update(struct sway_xdg_shell_view *view);

#endif
20 changes: 19 additions & 1 deletion sway/desktop/xdg_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
#include "sway/xdg_decoration.h"
#include "sway/xdg_session_management_v1.h"

static struct sway_xdg_popup *popup_create(
struct wlr_xdg_popup *wlr_popup, struct sway_view *view,
Expand Down Expand Up @@ -193,7 +194,8 @@ static void set_activated(struct sway_view *view, bool activated) {
}

static void set_tiled(struct sway_view *view, bool tiled) {
if (xdg_shell_view_from_view(view) == NULL) {
struct sway_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view);
if (xdg_shell_view == NULL) {
return;
}
if (wl_resource_get_version(view->wlr_xdg_toplevel->resource) >=
Expand All @@ -209,6 +211,8 @@ static void set_tiled(struct sway_view *view, bool tiled) {
// to stop the client from drawing decorations outside of the toplevel geometry.
wlr_xdg_toplevel_set_maximized(view->wlr_xdg_toplevel, tiled);
}

notify_xdg_session_management_v1_toplevel_update(xdg_shell_view);
}

static void set_fullscreen(struct sway_view *view, bool fullscreen) {
Expand Down Expand Up @@ -263,6 +267,11 @@ static void close_popups(struct sway_view *view) {
}
}

static void notify_state_update(struct sway_view *view) {
struct sway_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view);
notify_xdg_session_management_v1_toplevel_update(xdg_shell_view);
}

static void destroy(struct sway_view *view) {
struct sway_xdg_shell_view *xdg_shell_view =
xdg_shell_view_from_view(view);
Expand All @@ -285,6 +294,7 @@ static const struct sway_view_impl view_impl = {
.is_transient_for = is_transient_for,
.close = _close,
.close_popups = close_popups,
.notify_state_update = notify_state_update,
.destroy = destroy,
};

Expand All @@ -303,6 +313,8 @@ static void handle_commit(struct wl_listener *listener, void *data) {
wlr_xdg_toplevel_set_wm_capabilities(view->wlr_xdg_toplevel,
WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
// TODO: wlr_xdg_toplevel_set_bounds()

notify_xdg_session_management_v1_toplevel_initial_configure(xdg_shell_view);
return;
}

Expand Down Expand Up @@ -528,6 +540,8 @@ static void handle_map(struct wl_listener *listener, void *data) {
xdg_shell_view->set_app_id.notify = handle_set_app_id;
wl_signal_add(&toplevel->events.set_app_id,
&xdg_shell_view->set_app_id);

notify_xdg_session_management_v1_toplevel_update(xdg_shell_view);
}

static void handle_destroy(struct wl_listener *listener, void *data) {
Expand All @@ -545,6 +559,8 @@ static void handle_destroy(struct wl_listener *listener, void *data) {
if (view->xdg_decoration) {
view->xdg_decoration->view = NULL;
}
wl_list_remove(&xdg_shell_view->xdg_session_v1.link);
free(xdg_shell_view->xdg_session_v1.name);
view_begin_destroy(view);
}

Expand Down Expand Up @@ -572,6 +588,8 @@ void handle_xdg_shell_toplevel(struct wl_listener *listener, void *data) {
}
xdg_shell_view->view.wlr_xdg_toplevel = xdg_toplevel;

wl_list_init(&xdg_shell_view->xdg_session_v1.link);

xdg_shell_view->map.notify = handle_map;
wl_signal_add(&xdg_toplevel->base->surface->events.map, &xdg_shell_view->map);

Expand Down
1 change: 1 addition & 0 deletions sway/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ sway_sources = files(
'swaynag.c',
'xdg_activation_v1.c',
'xdg_decoration.c',
'xdg_session_management_v1.c',

'desktop/idle_inhibit_v1.c',
'desktop/layer_shell.c',
Expand Down
7 changes: 7 additions & 0 deletions sway/server.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
#include "sway/input/cursor.h"
#include "sway/tree/root.h"
#include "sway/tree/workspace.h"
#include "sway/xdg_session_management_v1.h"

#if WLR_HAS_XWAYLAND
#include <wlr/xwayland/shell.h>
Expand Down Expand Up @@ -662,6 +663,11 @@ bool server_init(struct sway_server *server) {
return false;
}

if (!init_xdg_session_management_v1(server)) {
sway_log(SWAY_ERROR, "Failed to create XDG session manager");
return false;
}

wl_list_init(&server->pending_launcher_ctxs);

// Avoid using "wayland-0" as display socket
Expand Down Expand Up @@ -739,6 +745,7 @@ void server_fini(struct sway_server *server) {
wl_list_remove(&server->request_set_cursor_shape.link);
wl_list_remove(&server->new_foreign_toplevel_capture_request.link);
wl_list_remove(&server->workspace_manager_v1_commit.link);
finish_xdg_session_management_v1(server);
input_manager_finish(server->input);

// TODO: free sway-specific resources
Expand Down
29 changes: 28 additions & 1 deletion sway/tree/view.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ void view_destroy(struct sway_view *view) {
}
wl_list_remove(&view->events.unmap.listener_list);
list_free(view->executed_criteria);
free(view->session_restore.workspace);

view_assign_ctx(view, NULL);
wlr_scene_node_destroy(&view->image_capture_scene->tree.node);
Expand Down Expand Up @@ -618,6 +619,15 @@ static struct sway_workspace *select_workspace(struct sway_view *view) {
return ws;
}

// Check session restoration
if (view->session_restore.pending && view->session_restore.workspace != NULL) {
ws = workspace_by_name(view->session_restore.workspace);
if (ws) {
view_assign_ctx(view, NULL);
return ws;
}
}

// Check if there's a PID mapping
ws = view->ctx ? launcher_ctx_get_workspace(view->ctx) : NULL;
if (ws) {
Expand Down Expand Up @@ -859,7 +869,14 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
view_update_csd_from_client(view, decoration);
}

if (view->impl->wants_floating && view->impl->wants_floating(view)) {
bool floating;
if (view->session_restore.pending) {
floating = view->session_restore.floating;
} else {
floating = view->impl->wants_floating && view->impl->wants_floating(view);
}

if (floating) {
view->container->pending.border = config->floating_border;
view->container->pending.border_thickness = config->floating_border_thickness;
container_set_floating(view->container, true);
Expand Down Expand Up @@ -909,6 +926,10 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
input_manager_set_focus(&view->container->node);
}

view->session_restore.pending = false;
free(view->session_restore.workspace);
view->session_restore.workspace = NULL;

if (view->ext_foreign_toplevel) {
update_ext_foreign_toplevel(view);
}
Expand Down Expand Up @@ -1278,3 +1299,9 @@ void view_send_frame_done(struct sway_view *view) {
wlr_scene_node_for_each_buffer(node, send_frame_done_iterator, &when);
}
}

void view_notify_state_update(struct sway_view *view) {
if (view->impl->notify_state_update) {
view->impl->notify_state_update(view);
}
}
4 changes: 4 additions & 0 deletions sway/tree/workspace.c
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,11 @@ struct sway_container *workspace_find_container(struct sway_workspace *ws,
}

static void set_workspace(struct sway_container *container, void *data) {
bool changed = container->pending.workspace != container->pending.parent->pending.workspace;
container->pending.workspace = container->pending.parent->pending.workspace;
if (changed && container->view) {
view_notify_state_update(container->view);
}
}

static void workspace_attach_tiling(struct sway_workspace *ws,
Expand Down
Loading