mirror of
https://github.com/swaywm/sway.git
synced 2024-11-23 00:11:28 +00:00
Merge pull request #2356 from RyanDwyer/fullscreen-containers
Allow containers to be fullscreen
This commit is contained in:
commit
75ebeb4a16
|
@ -60,6 +60,8 @@ struct sway_container_state {
|
||||||
double swayc_x, swayc_y;
|
double swayc_x, swayc_y;
|
||||||
double swayc_width, swayc_height;
|
double swayc_width, swayc_height;
|
||||||
|
|
||||||
|
bool is_fullscreen;
|
||||||
|
|
||||||
bool has_gaps;
|
bool has_gaps;
|
||||||
double current_gaps;
|
double current_gaps;
|
||||||
double gaps_inner;
|
double gaps_inner;
|
||||||
|
@ -74,7 +76,6 @@ struct sway_container_state {
|
||||||
// View properties
|
// View properties
|
||||||
double view_x, view_y;
|
double view_x, view_y;
|
||||||
double view_width, view_height;
|
double view_width, view_height;
|
||||||
bool is_fullscreen;
|
|
||||||
|
|
||||||
enum sway_container_border border;
|
enum sway_container_border border;
|
||||||
int border_thickness;
|
int border_thickness;
|
||||||
|
@ -84,7 +85,7 @@ struct sway_container_state {
|
||||||
bool border_right;
|
bool border_right;
|
||||||
|
|
||||||
// Workspace properties
|
// Workspace properties
|
||||||
struct sway_view *ws_fullscreen;
|
struct sway_container *ws_fullscreen;
|
||||||
struct sway_container *ws_floating;
|
struct sway_container *ws_floating;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -124,6 +125,8 @@ struct sway_container {
|
||||||
double saved_x, saved_y;
|
double saved_x, saved_y;
|
||||||
double saved_width, saved_height;
|
double saved_width, saved_height;
|
||||||
|
|
||||||
|
bool is_fullscreen;
|
||||||
|
|
||||||
// The gaps currently applied to the container.
|
// The gaps currently applied to the container.
|
||||||
double current_gaps;
|
double current_gaps;
|
||||||
|
|
||||||
|
@ -335,4 +338,20 @@ bool container_has_urgent_child(struct sway_container *container);
|
||||||
*/
|
*/
|
||||||
void container_end_mouse_operation(struct sway_container *container);
|
void container_end_mouse_operation(struct sway_container *container);
|
||||||
|
|
||||||
|
void container_set_fullscreen(struct sway_container *container, bool enable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return true if the container is fullscreen, or a child of a fullscreen split
|
||||||
|
* container.
|
||||||
|
*/
|
||||||
|
bool container_is_fullscreen_or_child(struct sway_container *container);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap the children of parent in a new container. The new container will be the
|
||||||
|
* only child of parent.
|
||||||
|
*
|
||||||
|
* The new container is returned.
|
||||||
|
*/
|
||||||
|
struct sway_container *container_wrap_children(struct sway_container *parent);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -69,8 +69,6 @@ struct sway_view {
|
||||||
// Used when changing a view from tiled to floating.
|
// Used when changing a view from tiled to floating.
|
||||||
int natural_width, natural_height;
|
int natural_width, natural_height;
|
||||||
|
|
||||||
bool is_fullscreen;
|
|
||||||
|
|
||||||
char *title_format;
|
char *title_format;
|
||||||
enum sway_container_border border;
|
enum sway_container_border border;
|
||||||
int border_thickness;
|
int border_thickness;
|
||||||
|
@ -251,10 +249,6 @@ void view_set_activated(struct sway_view *view, bool activated);
|
||||||
|
|
||||||
void view_set_tiled(struct sway_view *view, bool tiled);
|
void view_set_tiled(struct sway_view *view, bool tiled);
|
||||||
|
|
||||||
void view_set_fullscreen_raw(struct sway_view *view, bool fullscreen);
|
|
||||||
|
|
||||||
void view_set_fullscreen(struct sway_view *view, bool fullscreen);
|
|
||||||
|
|
||||||
void view_close(struct sway_view *view);
|
void view_close(struct sway_view *view);
|
||||||
|
|
||||||
void view_damage_from(struct sway_view *view);
|
void view_damage_from(struct sway_view *view);
|
||||||
|
|
|
@ -7,7 +7,7 @@ struct sway_view;
|
||||||
|
|
||||||
struct sway_workspace {
|
struct sway_workspace {
|
||||||
struct sway_container *swayc;
|
struct sway_container *swayc;
|
||||||
struct sway_view *fullscreen;
|
struct sway_container *fullscreen;
|
||||||
struct sway_container *floating;
|
struct sway_container *floating;
|
||||||
list_t *output_priority;
|
list_t *output_priority;
|
||||||
bool urgent;
|
bool urgent;
|
||||||
|
|
|
@ -14,18 +14,24 @@ struct cmd_results *cmd_fullscreen(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
struct sway_container *container =
|
struct sway_container *container =
|
||||||
config->handler_context.current_container;
|
config->handler_context.current_container;
|
||||||
if (container->type != C_VIEW) {
|
if (container->type == C_WORKSPACE && container->children->length == 0) {
|
||||||
return cmd_results_new(CMD_INVALID, "fullscreen",
|
return cmd_results_new(CMD_INVALID, "fullscreen",
|
||||||
"Only views can fullscreen");
|
"Can't fullscreen an empty workspace");
|
||||||
}
|
}
|
||||||
struct sway_view *view = container->sway_view;
|
if (container->type == C_WORKSPACE) {
|
||||||
bool wants_fullscreen = !view->is_fullscreen;
|
// Wrap the workspace's children in a container so we can fullscreen it
|
||||||
|
struct sway_container *workspace = container;
|
||||||
|
container = container_wrap_children(container);
|
||||||
|
workspace->layout = L_HORIZ;
|
||||||
|
seat_set_focus(config->handler_context.seat, container);
|
||||||
|
}
|
||||||
|
bool enable = !container->is_fullscreen;
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
wants_fullscreen = parse_boolean(argv[0], view->is_fullscreen);
|
enable = parse_boolean(argv[0], container->is_fullscreen);
|
||||||
}
|
}
|
||||||
|
|
||||||
view_set_fullscreen(view, wants_fullscreen);
|
container_set_fullscreen(container, enable);
|
||||||
|
|
||||||
struct sway_container *workspace = container_parent(container, C_WORKSPACE);
|
struct sway_container *workspace = container_parent(container, C_WORKSPACE);
|
||||||
arrange_windows(workspace->parent);
|
arrange_windows(workspace->parent);
|
||||||
|
|
|
@ -196,7 +196,7 @@ static struct cmd_results *move_in_direction(struct sway_container *container,
|
||||||
"Cannot move workspaces in a direction");
|
"Cannot move workspaces in a direction");
|
||||||
}
|
}
|
||||||
if (container_is_floating(container)) {
|
if (container_is_floating(container)) {
|
||||||
if (container->type == C_VIEW && container->sway_view->is_fullscreen) {
|
if (container->is_fullscreen) {
|
||||||
return cmd_results_new(CMD_FAILURE, "move",
|
return cmd_results_new(CMD_FAILURE, "move",
|
||||||
"Cannot move fullscreen floating container");
|
"Cannot move fullscreen floating container");
|
||||||
}
|
}
|
||||||
|
|
|
@ -279,13 +279,15 @@ static void send_frame_done(struct sway_output *output, struct timespec *when) {
|
||||||
|
|
||||||
struct sway_container *workspace = output_get_active_workspace(output);
|
struct sway_container *workspace = output_get_active_workspace(output);
|
||||||
if (workspace->current.ws_fullscreen) {
|
if (workspace->current.ws_fullscreen) {
|
||||||
|
if (workspace->current.ws_fullscreen->type == C_VIEW) {
|
||||||
send_frame_done_container_iterator(
|
send_frame_done_container_iterator(
|
||||||
workspace->current.ws_fullscreen->swayc, &data);
|
workspace->current.ws_fullscreen, &data);
|
||||||
|
} else {
|
||||||
|
send_frame_done_container(&data, workspace->current.ws_fullscreen);
|
||||||
|
}
|
||||||
#ifdef HAVE_XWAYLAND
|
#ifdef HAVE_XWAYLAND
|
||||||
if (workspace->current.ws_fullscreen->type == SWAY_VIEW_XWAYLAND) {
|
|
||||||
send_frame_done_unmanaged(&data,
|
send_frame_done_unmanaged(&data,
|
||||||
&root_container.sway_root->xwayland_unmanaged);
|
&root_container.sway_root->xwayland_unmanaged);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
send_frame_done_layer(&data,
|
send_frame_done_layer(&data,
|
||||||
|
|
|
@ -836,13 +836,13 @@ void output_render(struct sway_output *output, struct timespec *when,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sway_container *workspace = output_get_active_workspace(output);
|
struct sway_container *workspace = output_get_active_workspace(output);
|
||||||
struct sway_view *fullscreen_view = workspace->current.ws_fullscreen;
|
struct sway_container *fullscreen_con = workspace->current.ws_fullscreen;
|
||||||
|
|
||||||
if (output_has_opaque_overlay_layer_surface(output)) {
|
if (output_has_opaque_overlay_layer_surface(output)) {
|
||||||
goto render_overlay;
|
goto render_overlay;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fullscreen_view) {
|
if (fullscreen_con) {
|
||||||
float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
|
float clear_color[] = {0.0f, 0.0f, 0.0f, 1.0f};
|
||||||
|
|
||||||
int nrects;
|
int nrects;
|
||||||
|
@ -853,16 +853,21 @@ void output_render(struct sway_output *output, struct timespec *when,
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: handle views smaller than the output
|
// TODO: handle views smaller than the output
|
||||||
if (fullscreen_view->swayc->instructions->length) {
|
if (fullscreen_con->type == C_VIEW) {
|
||||||
render_saved_view(fullscreen_view, output, damage, 1.0f);
|
if (fullscreen_con->instructions->length) {
|
||||||
|
render_saved_view(fullscreen_con->sway_view,
|
||||||
|
output, damage, 1.0f);
|
||||||
} else {
|
} else {
|
||||||
render_view_surfaces(fullscreen_view, output, damage, 1.0f);
|
render_view_surfaces(fullscreen_con->sway_view,
|
||||||
|
output, damage, 1.0f);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
render_container(output, damage, fullscreen_con,
|
||||||
|
fullscreen_con->current.focused);
|
||||||
}
|
}
|
||||||
#ifdef HAVE_XWAYLAND
|
#ifdef HAVE_XWAYLAND
|
||||||
if (fullscreen_view->type == SWAY_VIEW_XWAYLAND) {
|
|
||||||
render_unmanaged(output, damage,
|
render_unmanaged(output, damage,
|
||||||
&root_container.sway_root->xwayland_unmanaged);
|
&root_container.sway_root->xwayland_unmanaged);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f};
|
float clear_color[] = {0.25f, 0.25f, 0.25f, 1.0f};
|
||||||
|
|
|
@ -110,6 +110,7 @@ static void copy_pending_state(struct sway_container *container,
|
||||||
state->swayc_y = container->y;
|
state->swayc_y = container->y;
|
||||||
state->swayc_width = container->width;
|
state->swayc_width = container->width;
|
||||||
state->swayc_height = container->height;
|
state->swayc_height = container->height;
|
||||||
|
state->is_fullscreen = container->is_fullscreen;
|
||||||
state->has_gaps = container->has_gaps;
|
state->has_gaps = container->has_gaps;
|
||||||
state->current_gaps = container->current_gaps;
|
state->current_gaps = container->current_gaps;
|
||||||
state->gaps_inner = container->gaps_inner;
|
state->gaps_inner = container->gaps_inner;
|
||||||
|
@ -122,7 +123,6 @@ static void copy_pending_state(struct sway_container *container,
|
||||||
state->view_y = view->y;
|
state->view_y = view->y;
|
||||||
state->view_width = view->width;
|
state->view_width = view->width;
|
||||||
state->view_height = view->height;
|
state->view_height = view->height;
|
||||||
state->is_fullscreen = view->is_fullscreen;
|
|
||||||
state->border = view->border;
|
state->border = view->border;
|
||||||
state->border_thickness = view->border_thickness;
|
state->border_thickness = view->border_thickness;
|
||||||
state->border_top = view->border_top;
|
state->border_top = view->border_top;
|
||||||
|
|
|
@ -267,7 +267,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
view_set_fullscreen(view, e->fullscreen);
|
container_set_fullscreen(view->swayc, e->fullscreen);
|
||||||
|
|
||||||
struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
|
struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
|
||||||
arrange_windows(output);
|
arrange_windows(output);
|
||||||
|
@ -338,7 +338,7 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
||||||
view_map(view, view->wlr_xdg_surface->surface);
|
view_map(view, view->wlr_xdg_surface->surface);
|
||||||
|
|
||||||
if (xdg_surface->toplevel->client_pending.fullscreen) {
|
if (xdg_surface->toplevel->client_pending.fullscreen) {
|
||||||
view_set_fullscreen(view, true);
|
container_set_fullscreen(view->swayc, true);
|
||||||
struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
|
struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
|
||||||
arrange_windows(ws);
|
arrange_windows(ws);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -262,7 +262,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
view_set_fullscreen(view, e->fullscreen);
|
container_set_fullscreen(view->swayc, e->fullscreen);
|
||||||
|
|
||||||
struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
|
struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
|
||||||
arrange_windows(output);
|
arrange_windows(output);
|
||||||
|
@ -333,7 +333,7 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
||||||
view_map(view, view->wlr_xdg_surface_v6->surface);
|
view_map(view, view->wlr_xdg_surface_v6->surface);
|
||||||
|
|
||||||
if (xdg_surface->toplevel->client_pending.fullscreen) {
|
if (xdg_surface->toplevel->client_pending.fullscreen) {
|
||||||
view_set_fullscreen(view, true);
|
container_set_fullscreen(view->swayc, true);
|
||||||
struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
|
struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
|
||||||
arrange_windows(ws);
|
arrange_windows(ws);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -357,7 +357,7 @@ static void handle_map(struct wl_listener *listener, void *data) {
|
||||||
view_map(view, xsurface->surface);
|
view_map(view, xsurface->surface);
|
||||||
|
|
||||||
if (xsurface->fullscreen) {
|
if (xsurface->fullscreen) {
|
||||||
view_set_fullscreen(view, true);
|
container_set_fullscreen(view->swayc, true);
|
||||||
struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
|
struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
|
||||||
arrange_windows(ws);
|
arrange_windows(ws);
|
||||||
} else {
|
} else {
|
||||||
|
@ -395,7 +395,7 @@ static void handle_request_fullscreen(struct wl_listener *listener, void *data)
|
||||||
if (!xsurface->mapped) {
|
if (!xsurface->mapped) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
view_set_fullscreen(view, xsurface->fullscreen);
|
container_set_fullscreen(view->swayc, xsurface->fullscreen);
|
||||||
|
|
||||||
struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
|
struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
|
||||||
arrange_windows(output);
|
arrange_windows(output);
|
||||||
|
|
|
@ -99,14 +99,8 @@ static struct sway_container *container_at_coords(
|
||||||
return ws;
|
return ws;
|
||||||
}
|
}
|
||||||
if (ws->sway_workspace->fullscreen) {
|
if (ws->sway_workspace->fullscreen) {
|
||||||
struct wlr_surface *wlr_surface = ws->sway_workspace->fullscreen->surface;
|
return container_at(ws->sway_workspace->fullscreen, lx, ly,
|
||||||
if (wlr_surface_point_accepts_input(wlr_surface, ox, oy)) {
|
surface, sx, sy);
|
||||||
*sx = ox;
|
|
||||||
*sy = oy;
|
|
||||||
*surface = wlr_surface;
|
|
||||||
return ws->sway_workspace->fullscreen->swayc;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
if ((*surface = layer_surface_at(output,
|
if ((*surface = layer_surface_at(output,
|
||||||
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
|
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_TOP],
|
||||||
|
@ -438,8 +432,8 @@ static void dispatch_cursor_button_floating(struct sway_cursor *cursor,
|
||||||
struct sway_container *cont) {
|
struct sway_container *cont) {
|
||||||
struct sway_seat *seat = cursor->seat;
|
struct sway_seat *seat = cursor->seat;
|
||||||
|
|
||||||
// Deny moving or resizing a fullscreen view
|
// Deny moving or resizing a fullscreen container
|
||||||
if (cont->type == C_VIEW && cont->sway_view->is_fullscreen) {
|
if (container_is_fullscreen_or_child(cont)) {
|
||||||
seat_pointer_notify_button(seat, time_msec, button, state);
|
seat_pointer_notify_button(seat, time_msec, button, state);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -632,8 +632,7 @@ void seat_set_focus_warp(struct sway_seat *seat,
|
||||||
|
|
||||||
if (last_workspace && last_workspace == new_workspace
|
if (last_workspace && last_workspace == new_workspace
|
||||||
&& last_workspace->sway_workspace->fullscreen
|
&& last_workspace->sway_workspace->fullscreen
|
||||||
&& container && container->type == C_VIEW
|
&& container && !container_is_fullscreen_or_child(container)) {
|
||||||
&& !container->sway_view->is_fullscreen) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ static void scratchpad_show(struct sway_container *con) {
|
||||||
// If the current con or any of its parents are in fullscreen mode, we
|
// If the current con or any of its parents are in fullscreen mode, we
|
||||||
// first need to disable it before showing the scratchpad con.
|
// first need to disable it before showing the scratchpad con.
|
||||||
if (ws->sway_workspace->fullscreen) {
|
if (ws->sway_workspace->fullscreen) {
|
||||||
view_set_fullscreen(ws->sway_workspace->fullscreen, false);
|
container_set_fullscreen(ws->sway_workspace->fullscreen, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show the container
|
// Show the container
|
||||||
|
|
|
@ -220,9 +220,23 @@ static void arrange_workspace(struct sway_container *workspace) {
|
||||||
container_set_dirty(workspace);
|
container_set_dirty(workspace);
|
||||||
wlr_log(WLR_DEBUG, "Arranging workspace '%s' at %f, %f", workspace->name,
|
wlr_log(WLR_DEBUG, "Arranging workspace '%s' at %f, %f", workspace->name,
|
||||||
workspace->x, workspace->y);
|
workspace->x, workspace->y);
|
||||||
|
if (workspace->sway_workspace->fullscreen) {
|
||||||
|
struct sway_container *fs = workspace->sway_workspace->fullscreen;
|
||||||
|
fs->x = workspace->parent->x;
|
||||||
|
fs->y = workspace->parent->y;
|
||||||
|
fs->width = workspace->parent->width;
|
||||||
|
fs->height = workspace->parent->height;
|
||||||
|
if (fs->type == C_VIEW) {
|
||||||
|
view_autoconfigure(fs->sway_view);
|
||||||
|
} else {
|
||||||
|
arrange_children_of(fs);
|
||||||
|
}
|
||||||
|
container_set_dirty(fs);
|
||||||
|
} else {
|
||||||
arrange_floating(workspace->sway_workspace->floating);
|
arrange_floating(workspace->sway_workspace->floating);
|
||||||
arrange_children_of(workspace);
|
arrange_children_of(workspace);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void arrange_output(struct sway_container *output) {
|
static void arrange_output(struct sway_container *output) {
|
||||||
if (config->reloading) {
|
if (config->reloading) {
|
||||||
|
|
|
@ -1130,3 +1130,90 @@ void container_end_mouse_operation(struct sway_container *container) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void set_fullscreen_iterator(struct sway_container *con, void *data) {
|
||||||
|
if (con->type != C_VIEW) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (con->sway_view->impl->set_fullscreen) {
|
||||||
|
bool *enable = data;
|
||||||
|
con->sway_view->impl->set_fullscreen(con->sway_view, *enable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void container_set_fullscreen(struct sway_container *container, bool enable) {
|
||||||
|
if (container->is_fullscreen == enable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sway_container *workspace = container_parent(container, C_WORKSPACE);
|
||||||
|
if (enable && workspace->sway_workspace->fullscreen) {
|
||||||
|
container_set_fullscreen(workspace->sway_workspace->fullscreen, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
container_for_each_descendant_dfs(container,
|
||||||
|
set_fullscreen_iterator, &enable);
|
||||||
|
|
||||||
|
container->is_fullscreen = enable;
|
||||||
|
|
||||||
|
if (enable) {
|
||||||
|
workspace->sway_workspace->fullscreen = container;
|
||||||
|
container->saved_x = container->x;
|
||||||
|
container->saved_y = container->y;
|
||||||
|
container->saved_width = container->width;
|
||||||
|
container->saved_height = container->height;
|
||||||
|
|
||||||
|
struct sway_seat *seat;
|
||||||
|
struct sway_container *focus, *focus_ws;
|
||||||
|
wl_list_for_each(seat, &input_manager->seats, link) {
|
||||||
|
focus = seat_get_focus(seat);
|
||||||
|
if (focus) {
|
||||||
|
focus_ws = focus;
|
||||||
|
if (focus_ws->type != C_WORKSPACE) {
|
||||||
|
focus_ws = container_parent(focus_ws, C_WORKSPACE);
|
||||||
|
}
|
||||||
|
if (focus_ws == workspace) {
|
||||||
|
seat_set_focus(seat, container);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
workspace->sway_workspace->fullscreen = NULL;
|
||||||
|
if (container_is_floating(container)) {
|
||||||
|
container->x = container->saved_x;
|
||||||
|
container->y = container->saved_y;
|
||||||
|
container->width = container->saved_width;
|
||||||
|
container->height = container->saved_height;
|
||||||
|
} else {
|
||||||
|
container->width = container->saved_width;
|
||||||
|
container->height = container->saved_height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
container_end_mouse_operation(container);
|
||||||
|
|
||||||
|
ipc_event_window(container, "fullscreen_mode");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool container_is_fullscreen_or_child(struct sway_container *container) {
|
||||||
|
do {
|
||||||
|
if (container->is_fullscreen) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
container = container->parent;
|
||||||
|
} while (container && container->type != C_WORKSPACE);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct sway_container *container_wrap_children(struct sway_container *parent) {
|
||||||
|
struct sway_container *middle = container_create(C_CONTAINER);
|
||||||
|
middle->layout = parent->layout;
|
||||||
|
while (parent->children->length) {
|
||||||
|
struct sway_container *child = parent->children->items[0];
|
||||||
|
container_remove_child(child);
|
||||||
|
container_add_child(middle, child);
|
||||||
|
}
|
||||||
|
container_add_child(parent, middle);
|
||||||
|
return middle;
|
||||||
|
}
|
||||||
|
|
|
@ -66,10 +66,9 @@ static int index_child(const struct sway_container *child) {
|
||||||
|
|
||||||
static void container_handle_fullscreen_reparent(struct sway_container *con,
|
static void container_handle_fullscreen_reparent(struct sway_container *con,
|
||||||
struct sway_container *old_parent) {
|
struct sway_container *old_parent) {
|
||||||
if (con->type != C_VIEW || !con->sway_view->is_fullscreen) {
|
if (!con->is_fullscreen) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
struct sway_view *view = con->sway_view;
|
|
||||||
struct sway_container *old_workspace = old_parent;
|
struct sway_container *old_workspace = old_parent;
|
||||||
if (old_workspace && old_workspace->type != C_WORKSPACE) {
|
if (old_workspace && old_workspace->type != C_WORKSPACE) {
|
||||||
old_workspace = container_parent(old_workspace, C_WORKSPACE);
|
old_workspace = container_parent(old_workspace, C_WORKSPACE);
|
||||||
|
@ -85,19 +84,27 @@ static void container_handle_fullscreen_reparent(struct sway_container *con,
|
||||||
|
|
||||||
// Mark the new workspace as fullscreen
|
// Mark the new workspace as fullscreen
|
||||||
if (new_workspace->sway_workspace->fullscreen) {
|
if (new_workspace->sway_workspace->fullscreen) {
|
||||||
view_set_fullscreen(new_workspace->sway_workspace->fullscreen, false);
|
container_set_fullscreen(
|
||||||
|
new_workspace->sway_workspace->fullscreen, false);
|
||||||
}
|
}
|
||||||
new_workspace->sway_workspace->fullscreen = view;
|
new_workspace->sway_workspace->fullscreen = con;
|
||||||
// Resize view to new output dimensions
|
|
||||||
|
// Resize container to new output dimensions
|
||||||
struct sway_container *output = new_workspace->parent;
|
struct sway_container *output = new_workspace->parent;
|
||||||
view->x = output->x;
|
|
||||||
view->y = output->y;
|
|
||||||
view->width = output->width;
|
|
||||||
view->height = output->height;
|
|
||||||
con->x = output->x;
|
con->x = output->x;
|
||||||
con->y = output->y;
|
con->y = output->y;
|
||||||
con->width = output->width;
|
con->width = output->width;
|
||||||
con->height = output->height;
|
con->height = output->height;
|
||||||
|
|
||||||
|
if (con->type == C_VIEW) {
|
||||||
|
struct sway_view *view = con->sway_view;
|
||||||
|
view->x = output->x;
|
||||||
|
view->y = output->y;
|
||||||
|
view->width = output->width;
|
||||||
|
view->height = output->height;
|
||||||
|
} else {
|
||||||
|
arrange_windows(new_workspace);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void container_insert_child(struct sway_container *parent,
|
void container_insert_child(struct sway_container *parent,
|
||||||
|
@ -146,7 +153,7 @@ void container_add_child(struct sway_container *parent,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sway_container *container_remove_child(struct sway_container *child) {
|
struct sway_container *container_remove_child(struct sway_container *child) {
|
||||||
if (child->type == C_VIEW && child->sway_view->is_fullscreen) {
|
if (child->is_fullscreen) {
|
||||||
struct sway_container *workspace = container_parent(child, C_WORKSPACE);
|
struct sway_container *workspace = container_parent(child, C_WORKSPACE);
|
||||||
workspace->sway_workspace->fullscreen = NULL;
|
workspace->sway_workspace->fullscreen = NULL;
|
||||||
}
|
}
|
||||||
|
@ -229,10 +236,10 @@ void container_move_to(struct sway_container *container,
|
||||||
if (focus_ws->type != C_WORKSPACE) {
|
if (focus_ws->type != C_WORKSPACE) {
|
||||||
focus_ws = container_parent(focus_ws, C_WORKSPACE);
|
focus_ws = container_parent(focus_ws, C_WORKSPACE);
|
||||||
}
|
}
|
||||||
seat_set_focus(seat,
|
if (focus_ws == new_workspace) {
|
||||||
new_workspace->sway_workspace->fullscreen->swayc);
|
struct sway_container *new_focus = seat_get_focus_inactive(seat,
|
||||||
if (focus_ws != new_workspace) {
|
new_workspace->sway_workspace->fullscreen);
|
||||||
seat_set_focus(seat, focus);
|
seat_set_focus(seat, new_focus);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -375,10 +382,16 @@ void container_move(struct sway_container *container,
|
||||||
struct sway_container *sibling = NULL;
|
struct sway_container *sibling = NULL;
|
||||||
struct sway_container *current = container;
|
struct sway_container *current = container;
|
||||||
struct sway_container *parent = current->parent;
|
struct sway_container *parent = current->parent;
|
||||||
|
struct sway_container *top = &root_container;
|
||||||
|
|
||||||
// If moving a fullscreen view, only consider outputs
|
// If moving a fullscreen view, only consider outputs
|
||||||
if (container->type == C_VIEW && container->sway_view->is_fullscreen) {
|
if (container->is_fullscreen) {
|
||||||
current = container_parent(container, C_OUTPUT);
|
current = container_parent(container, C_OUTPUT);
|
||||||
|
} else if (container_is_fullscreen_or_child(container)) {
|
||||||
|
// If we've fullscreened a split container, only allow the child to move
|
||||||
|
// around within the fullscreen parent.
|
||||||
|
struct sway_container *ws = container_parent(container, C_WORKSPACE);
|
||||||
|
top = ws->sway_workspace->fullscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sway_container *new_parent = container_flatten(parent);
|
struct sway_container *new_parent = container_flatten(parent);
|
||||||
|
@ -388,7 +401,7 @@ void container_move(struct sway_container *container,
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!sibling) {
|
while (!sibling) {
|
||||||
if (current->type == C_ROOT) {
|
if (current == top) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -452,8 +465,9 @@ void container_move(struct sway_container *container,
|
||||||
if ((index == parent->children->length - 1 && offs > 0)
|
if ((index == parent->children->length - 1 && offs > 0)
|
||||||
|| (index == 0 && offs < 0)) {
|
|| (index == 0 && offs < 0)) {
|
||||||
if (current->parent == container->parent) {
|
if (current->parent == container->parent) {
|
||||||
if (parent->layout == L_TABBED
|
if (!parent->is_fullscreen &&
|
||||||
|| parent->layout == L_STACKED) {
|
(parent->layout == L_TABBED ||
|
||||||
|
parent->layout == L_STACKED)) {
|
||||||
move_out_of_tabs_stacks(container, current,
|
move_out_of_tabs_stacks(container, current,
|
||||||
move_dir, offs);
|
move_dir, offs);
|
||||||
return;
|
return;
|
||||||
|
@ -474,8 +488,8 @@ void container_move(struct sway_container *container,
|
||||||
sibling = parent->children->items[index + offs];
|
sibling = parent->children->items[index + offs];
|
||||||
wlr_log(WLR_DEBUG, "Selecting sibling id:%zd", sibling->id);
|
wlr_log(WLR_DEBUG, "Selecting sibling id:%zd", sibling->id);
|
||||||
}
|
}
|
||||||
} else if (parent->layout == L_TABBED
|
} else if (!parent->is_fullscreen && (parent->layout == L_TABBED ||
|
||||||
|| parent->layout == L_STACKED) {
|
parent->layout == L_STACKED)) {
|
||||||
move_out_of_tabs_stacks(container, current, move_dir, offs);
|
move_out_of_tabs_stacks(container, current, move_dir, offs);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
|
@ -707,16 +721,16 @@ struct sway_container *container_get_in_direction(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (container->type == C_VIEW && container->sway_view->is_fullscreen) {
|
if (dir == MOVE_CHILD) {
|
||||||
if (dir == MOVE_PARENT || dir == MOVE_CHILD) {
|
return seat_get_focus_inactive(seat, container);
|
||||||
|
}
|
||||||
|
if (container->is_fullscreen) {
|
||||||
|
if (dir == MOVE_PARENT) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
container = container_parent(container, C_OUTPUT);
|
container = container_parent(container, C_OUTPUT);
|
||||||
parent = container->parent;
|
parent = container->parent;
|
||||||
} else {
|
} else {
|
||||||
if (dir == MOVE_CHILD) {
|
|
||||||
return seat_get_focus_inactive(seat, container);
|
|
||||||
}
|
|
||||||
if (dir == MOVE_PARENT) {
|
if (dir == MOVE_PARENT) {
|
||||||
if (parent->type == C_OUTPUT) {
|
if (parent->type == C_OUTPUT) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -767,7 +781,8 @@ struct sway_container *container_get_in_direction(
|
||||||
}
|
}
|
||||||
sway_assert(next_workspace, "Next container has no workspace");
|
sway_assert(next_workspace, "Next container has no workspace");
|
||||||
if (next_workspace->sway_workspace->fullscreen) {
|
if (next_workspace->sway_workspace->fullscreen) {
|
||||||
return next_workspace->sway_workspace->fullscreen->swayc;
|
return seat_get_focus_inactive(seat,
|
||||||
|
next_workspace->sway_workspace->fullscreen);
|
||||||
}
|
}
|
||||||
if (next->children && next->children->length) {
|
if (next->children && next->children->length) {
|
||||||
// TODO consider floating children as well
|
// TODO consider floating children as well
|
||||||
|
@ -1014,13 +1029,13 @@ void container_swap(struct sway_container *con1, struct sway_container *con2) {
|
||||||
|
|
||||||
wlr_log(WLR_DEBUG, "Swapping containers %zu and %zu", con1->id, con2->id);
|
wlr_log(WLR_DEBUG, "Swapping containers %zu and %zu", con1->id, con2->id);
|
||||||
|
|
||||||
int fs1 = con1->type == C_VIEW && con1->sway_view->is_fullscreen;
|
int fs1 = con1->is_fullscreen;
|
||||||
int fs2 = con2->type == C_VIEW && con2->sway_view->is_fullscreen;
|
int fs2 = con2->is_fullscreen;
|
||||||
if (fs1) {
|
if (fs1) {
|
||||||
view_set_fullscreen(con1->sway_view, false);
|
container_set_fullscreen(con1, false);
|
||||||
}
|
}
|
||||||
if (fs2) {
|
if (fs2) {
|
||||||
view_set_fullscreen(con2->sway_view, false);
|
container_set_fullscreen(con2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sway_seat *seat = input_manager_get_default_seat(input_manager);
|
struct sway_seat *seat = input_manager_get_default_seat(input_manager);
|
||||||
|
@ -1053,10 +1068,10 @@ void container_swap(struct sway_container *con1, struct sway_container *con2) {
|
||||||
prev_workspace_name = stored_prev_name;
|
prev_workspace_name = stored_prev_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fs1 && con2->type == C_VIEW) {
|
if (fs1) {
|
||||||
view_set_fullscreen(con2->sway_view, true);
|
container_set_fullscreen(con2, true);
|
||||||
}
|
}
|
||||||
if (fs2 && con1->type == C_VIEW) {
|
if (fs2) {
|
||||||
view_set_fullscreen(con1->sway_view, true);
|
container_set_fullscreen(con1, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,7 +225,7 @@ void view_autoconfigure(struct sway_view *view) {
|
||||||
|
|
||||||
struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
|
struct sway_container *output = container_parent(view->swayc, C_OUTPUT);
|
||||||
|
|
||||||
if (view->is_fullscreen) {
|
if (view->swayc->is_fullscreen) {
|
||||||
view->x = output->x;
|
view->x = output->x;
|
||||||
view->y = output->y;
|
view->y = output->y;
|
||||||
view->width = output->width;
|
view->width = output->width;
|
||||||
|
@ -233,10 +233,6 @@ void view_autoconfigure(struct sway_view *view) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (container_is_floating(view->swayc)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
|
struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
|
||||||
|
|
||||||
int other_views = 0;
|
int other_views = 0;
|
||||||
|
@ -349,68 +345,6 @@ void view_set_tiled(struct sway_view *view, bool tiled) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void view_set_fullscreen(struct sway_view *view, bool fullscreen) {
|
|
||||||
if (view->is_fullscreen == fullscreen) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sway_container *workspace =
|
|
||||||
container_parent(view->swayc, C_WORKSPACE);
|
|
||||||
|
|
||||||
if (view->impl->set_fullscreen) {
|
|
||||||
view->impl->set_fullscreen(view, fullscreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
view->is_fullscreen = fullscreen;
|
|
||||||
|
|
||||||
if (fullscreen) {
|
|
||||||
if (workspace->sway_workspace->fullscreen) {
|
|
||||||
view_set_fullscreen(workspace->sway_workspace->fullscreen, false);
|
|
||||||
}
|
|
||||||
workspace->sway_workspace->fullscreen = view;
|
|
||||||
view->saved_x = view->x;
|
|
||||||
view->saved_y = view->y;
|
|
||||||
view->saved_width = view->width;
|
|
||||||
view->saved_height = view->height;
|
|
||||||
view->swayc->saved_x = view->swayc->x;
|
|
||||||
view->swayc->saved_y = view->swayc->y;
|
|
||||||
view->swayc->saved_width = view->swayc->width;
|
|
||||||
view->swayc->saved_height = view->swayc->height;
|
|
||||||
|
|
||||||
struct sway_seat *seat;
|
|
||||||
struct sway_container *focus, *focus_ws;
|
|
||||||
wl_list_for_each(seat, &input_manager->seats, link) {
|
|
||||||
focus = seat_get_focus(seat);
|
|
||||||
if (focus) {
|
|
||||||
focus_ws = focus;
|
|
||||||
if (focus && focus_ws->type != C_WORKSPACE) {
|
|
||||||
focus_ws = container_parent(focus_ws, C_WORKSPACE);
|
|
||||||
}
|
|
||||||
seat_set_focus(seat, view->swayc);
|
|
||||||
if (focus_ws != workspace) {
|
|
||||||
seat_set_focus(seat, focus);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
workspace->sway_workspace->fullscreen = NULL;
|
|
||||||
if (container_is_floating(view->swayc)) {
|
|
||||||
view->x = view->saved_x;
|
|
||||||
view->y = view->saved_y;
|
|
||||||
view->width = view->saved_width;
|
|
||||||
view->height = view->saved_height;
|
|
||||||
container_set_geometry_from_floating_view(view->swayc);
|
|
||||||
} else {
|
|
||||||
view->swayc->width = view->swayc->saved_width;
|
|
||||||
view->swayc->height = view->swayc->saved_height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
container_end_mouse_operation(view->swayc);
|
|
||||||
|
|
||||||
ipc_event_window(view->swayc, "fullscreen_mode");
|
|
||||||
}
|
|
||||||
|
|
||||||
void view_close(struct sway_view *view) {
|
void view_close(struct sway_view *view) {
|
||||||
if (view->impl->close) {
|
if (view->impl->close) {
|
||||||
view->impl->close(view);
|
view->impl->close(view);
|
||||||
|
@ -680,7 +614,7 @@ void view_unmap(struct sway_view *view) {
|
||||||
struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
|
struct sway_container *ws = container_parent(view->swayc, C_WORKSPACE);
|
||||||
|
|
||||||
struct sway_container *parent;
|
struct sway_container *parent;
|
||||||
if (view->is_fullscreen) {
|
if (view->swayc->is_fullscreen) {
|
||||||
ws->sway_workspace->fullscreen = NULL;
|
ws->sway_workspace->fullscreen = NULL;
|
||||||
parent = container_destroy(view->swayc);
|
parent = container_destroy(view->swayc);
|
||||||
|
|
||||||
|
@ -1133,7 +1067,8 @@ bool view_is_visible(struct sway_view *view) {
|
||||||
container = container->parent;
|
container = container->parent;
|
||||||
}
|
}
|
||||||
// Check view isn't hidden by another fullscreen view
|
// Check view isn't hidden by another fullscreen view
|
||||||
if (workspace->sway_workspace->fullscreen && !view->is_fullscreen) {
|
if (workspace->sway_workspace->fullscreen &&
|
||||||
|
!container_is_fullscreen_or_child(view->swayc)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Check the workspace is visible
|
// Check the workspace is visible
|
||||||
|
|
Loading…
Reference in a new issue