mirror of
https://github.com/swaywm/sway.git
synced 2026-04-22 06:46:27 -04:00
Fix inconsistent floating window z order across outputs
This commit is contained in:
parent
f92329701b
commit
9239bd05ca
6 changed files with 73 additions and 15 deletions
|
|
@ -113,6 +113,12 @@ struct sway_seat {
|
|||
// sway_keyboard_shortcuts_inhibitor::link
|
||||
|
||||
struct wl_list link; // input_manager::seats
|
||||
|
||||
// Used by sway_container.floating_order. This value will increment as
|
||||
// floating windows request to be shown on top, this makes sure that a
|
||||
// value can be assigned to a floating window that is guaranteed
|
||||
// to be highter (ignoring overflow) than other floating windows.
|
||||
uint32_t floating_counter;
|
||||
};
|
||||
|
||||
struct sway_pointer_constraint {
|
||||
|
|
|
|||
|
|
@ -113,6 +113,12 @@ struct sway_container {
|
|||
// Hidden scratchpad containers have a NULL parent.
|
||||
bool scratchpad;
|
||||
|
||||
// Value specifing in which order floating windows should be shown
|
||||
// higher values means that the floating window should appear
|
||||
// ontop of others. This variable is undefined if this container is not
|
||||
// floating.
|
||||
uint32_t floating_order;
|
||||
|
||||
float alpha;
|
||||
|
||||
struct wlr_texture *title_focused;
|
||||
|
|
|
|||
|
|
@ -996,8 +996,17 @@ static void render_floating_container(struct sway_output *soutput,
|
|||
}
|
||||
}
|
||||
|
||||
static int floating_order_compare (const void *a, const void *b) {
|
||||
struct sway_container *a_container = *(struct sway_container **)a;
|
||||
struct sway_container *b_container = *(struct sway_container **)b;
|
||||
|
||||
return a_container->floating_order - b_container->floating_order;
|
||||
}
|
||||
|
||||
static void render_floating(struct sway_output *soutput,
|
||||
pixman_region32_t *damage) {
|
||||
list_t *floating = create_list();
|
||||
|
||||
for (int i = 0; i < root->outputs->length; ++i) {
|
||||
struct sway_output *output = root->outputs->items[i];
|
||||
for (int j = 0; j < output->current.workspaces->length; ++j) {
|
||||
|
|
@ -1010,10 +1019,19 @@ static void render_floating(struct sway_output *soutput,
|
|||
if (floater->current.fullscreen_mode != FULLSCREEN_NONE) {
|
||||
continue;
|
||||
}
|
||||
render_floating_container(soutput, damage, floater);
|
||||
list_add(floating, floater);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list_qsort(floating, floating_order_compare);
|
||||
|
||||
for (int i = 0; i < floating->length; ++i) {
|
||||
struct sway_container *floater = floating->items[i];
|
||||
render_floating_container(soutput, damage, floater);
|
||||
}
|
||||
|
||||
list_free(floating);
|
||||
}
|
||||
|
||||
static void render_seatops(struct sway_output *output,
|
||||
|
|
|
|||
|
|
@ -565,6 +565,8 @@ struct sway_seat *seat_create(const char *seat_name) {
|
|||
}
|
||||
seat->wlr_seat->data = seat;
|
||||
|
||||
seat->floating_counter = 0;
|
||||
|
||||
seat->cursor = sway_cursor_create(seat);
|
||||
if (!seat->cursor) {
|
||||
wlr_seat_destroy(seat->wlr_seat);
|
||||
|
|
|
|||
|
|
@ -289,31 +289,49 @@ static struct sway_container *container_at_linear(struct sway_node *parent,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static int floating_order_compare (const void *a, const void *b) {
|
||||
struct sway_container *a_container = *(struct sway_container **)a;
|
||||
struct sway_container *b_container = *(struct sway_container **)b;
|
||||
|
||||
return a_container->floating_order - b_container->floating_order;
|
||||
}
|
||||
|
||||
static struct sway_container *floating_container_at(double lx, double ly,
|
||||
struct wlr_surface **surface, double *sx, double *sy) {
|
||||
// For outputs with floating containers that overhang the output bounds,
|
||||
// those at the end of the output list appear on top of floating
|
||||
// containers from other outputs, so iterate the list in reverse.
|
||||
for (int i = root->outputs->length - 1; i >= 0; --i) {
|
||||
list_t *floating = create_list();
|
||||
|
||||
for (int i = 0; i < root->outputs->length; ++i) {
|
||||
struct sway_output *output = root->outputs->items[i];
|
||||
for (int j = 0; j < output->workspaces->length; ++j) {
|
||||
struct sway_workspace *ws = output->workspaces->items[j];
|
||||
if (!workspace_is_visible(ws)) {
|
||||
continue;
|
||||
}
|
||||
// Items at the end of the list are on top, so iterate the list in
|
||||
// reverse.
|
||||
for (int k = ws->floating->length - 1; k >= 0; --k) {
|
||||
for (int k = 0; k < ws->floating->length; ++k) {
|
||||
struct sway_container *floater = ws->floating->items[k];
|
||||
struct sway_container *container =
|
||||
tiling_container_at(&floater->node, lx, ly, surface, sx, sy);
|
||||
if (container) {
|
||||
return container;
|
||||
}
|
||||
list_add(floating, floater);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
||||
list_qsort(floating, floating_order_compare);
|
||||
|
||||
struct sway_container *container = NULL;
|
||||
|
||||
// Items at the end of the list are on top, so iterate the list in
|
||||
// reverse.
|
||||
for (int i = floating->length - 1; i >= 0; --i) {
|
||||
struct sway_container *floater = floating->items[i];
|
||||
struct sway_container *current =
|
||||
tiling_container_at(&floater->node, lx, ly, surface, sx, sy);
|
||||
if (current) {
|
||||
container = current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list_free(floating);
|
||||
return container;
|
||||
}
|
||||
|
||||
static struct sway_container *view_container_content_at(struct sway_node *parent,
|
||||
|
|
@ -837,6 +855,7 @@ void container_set_floating(struct sway_container *container, bool enable) {
|
|||
if (enable) {
|
||||
struct sway_container *old_parent = container->pending.parent;
|
||||
container_detach(container);
|
||||
container->floating_order = ++seat->floating_counter;
|
||||
workspace_add_floating(workspace, container);
|
||||
if (container->view) {
|
||||
view_set_tiled(container->view, false);
|
||||
|
|
@ -1733,10 +1752,15 @@ void container_update_marks_textures(struct sway_container *con) {
|
|||
}
|
||||
|
||||
void container_raise_floating(struct sway_container *con) {
|
||||
struct sway_seat *seat = input_manager_current_seat();
|
||||
// Bring container to front by putting it at the end of the floating list.
|
||||
struct sway_container *floater = container_toplevel_ancestor(con);
|
||||
if (container_is_floating(floater) && floater->pending.workspace) {
|
||||
list_move_to_end(floater->pending.workspace->floating, floater);
|
||||
// Don't raise if already on top
|
||||
if (floater->floating_order != seat->floating_counter) {
|
||||
floater->floating_order = ++seat->floating_counter;
|
||||
}
|
||||
|
||||
node_set_dirty(&floater->pending.workspace->node);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -813,6 +813,8 @@ void workspace_add_floating(struct sway_workspace *workspace,
|
|||
if (con->pending.workspace) {
|
||||
container_detach(con);
|
||||
}
|
||||
struct sway_seat *seat = input_manager_current_seat();
|
||||
con->floating_order = ++seat->floating_counter;
|
||||
list_add(workspace->floating, con);
|
||||
con->pending.workspace = workspace;
|
||||
container_for_each_child(con, set_workspace, NULL);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue