mirror of
https://github.com/swaywm/sway.git
synced 2026-04-23 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
|
// sway_keyboard_shortcuts_inhibitor::link
|
||||||
|
|
||||||
struct wl_list link; // input_manager::seats
|
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 {
|
struct sway_pointer_constraint {
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,12 @@ struct sway_container {
|
||||||
// Hidden scratchpad containers have a NULL parent.
|
// Hidden scratchpad containers have a NULL parent.
|
||||||
bool scratchpad;
|
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;
|
float alpha;
|
||||||
|
|
||||||
struct wlr_texture *title_focused;
|
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,
|
static void render_floating(struct sway_output *soutput,
|
||||||
pixman_region32_t *damage) {
|
pixman_region32_t *damage) {
|
||||||
|
list_t *floating = create_list();
|
||||||
|
|
||||||
for (int i = 0; i < root->outputs->length; ++i) {
|
for (int i = 0; i < root->outputs->length; ++i) {
|
||||||
struct sway_output *output = root->outputs->items[i];
|
struct sway_output *output = root->outputs->items[i];
|
||||||
for (int j = 0; j < output->current.workspaces->length; ++j) {
|
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) {
|
if (floater->current.fullscreen_mode != FULLSCREEN_NONE) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
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);
|
render_floating_container(soutput, damage, floater);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
list_free(floating);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void render_seatops(struct sway_output *output,
|
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->wlr_seat->data = seat;
|
||||||
|
|
||||||
|
seat->floating_counter = 0;
|
||||||
|
|
||||||
seat->cursor = sway_cursor_create(seat);
|
seat->cursor = sway_cursor_create(seat);
|
||||||
if (!seat->cursor) {
|
if (!seat->cursor) {
|
||||||
wlr_seat_destroy(seat->wlr_seat);
|
wlr_seat_destroy(seat->wlr_seat);
|
||||||
|
|
|
||||||
|
|
@ -289,32 +289,50 @@ static struct sway_container *container_at_linear(struct sway_node *parent,
|
||||||
return NULL;
|
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,
|
static struct sway_container *floating_container_at(double lx, double ly,
|
||||||
struct wlr_surface **surface, double *sx, double *sy) {
|
struct wlr_surface **surface, double *sx, double *sy) {
|
||||||
// For outputs with floating containers that overhang the output bounds,
|
list_t *floating = create_list();
|
||||||
// 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 = 0; i < root->outputs->length; ++i) {
|
||||||
for (int i = root->outputs->length - 1; i >= 0; --i) {
|
|
||||||
struct sway_output *output = root->outputs->items[i];
|
struct sway_output *output = root->outputs->items[i];
|
||||||
for (int j = 0; j < output->workspaces->length; ++j) {
|
for (int j = 0; j < output->workspaces->length; ++j) {
|
||||||
struct sway_workspace *ws = output->workspaces->items[j];
|
struct sway_workspace *ws = output->workspaces->items[j];
|
||||||
if (!workspace_is_visible(ws)) {
|
if (!workspace_is_visible(ws)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
for (int k = 0; k < ws->floating->length; ++k) {
|
||||||
|
struct sway_container *floater = ws->floating->items[k];
|
||||||
|
list_add(floating, floater);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
// Items at the end of the list are on top, so iterate the list in
|
||||||
// reverse.
|
// reverse.
|
||||||
for (int k = ws->floating->length - 1; k >= 0; --k) {
|
for (int i = floating->length - 1; i >= 0; --i) {
|
||||||
struct sway_container *floater = ws->floating->items[k];
|
struct sway_container *floater = floating->items[i];
|
||||||
struct sway_container *container =
|
struct sway_container *current =
|
||||||
tiling_container_at(&floater->node, lx, ly, surface, sx, sy);
|
tiling_container_at(&floater->node, lx, ly, surface, sx, sy);
|
||||||
if (container) {
|
if (current) {
|
||||||
|
container = current;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
list_free(floating);
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct sway_container *view_container_content_at(struct sway_node *parent,
|
static struct sway_container *view_container_content_at(struct sway_node *parent,
|
||||||
double lx, double ly,
|
double lx, double ly,
|
||||||
|
|
@ -837,6 +855,7 @@ void container_set_floating(struct sway_container *container, bool enable) {
|
||||||
if (enable) {
|
if (enable) {
|
||||||
struct sway_container *old_parent = container->pending.parent;
|
struct sway_container *old_parent = container->pending.parent;
|
||||||
container_detach(container);
|
container_detach(container);
|
||||||
|
container->floating_order = ++seat->floating_counter;
|
||||||
workspace_add_floating(workspace, container);
|
workspace_add_floating(workspace, container);
|
||||||
if (container->view) {
|
if (container->view) {
|
||||||
view_set_tiled(container->view, false);
|
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) {
|
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.
|
// Bring container to front by putting it at the end of the floating list.
|
||||||
struct sway_container *floater = container_toplevel_ancestor(con);
|
struct sway_container *floater = container_toplevel_ancestor(con);
|
||||||
if (container_is_floating(floater) && floater->pending.workspace) {
|
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);
|
node_set_dirty(&floater->pending.workspace->node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -813,6 +813,8 @@ void workspace_add_floating(struct sway_workspace *workspace,
|
||||||
if (con->pending.workspace) {
|
if (con->pending.workspace) {
|
||||||
container_detach(con);
|
container_detach(con);
|
||||||
}
|
}
|
||||||
|
struct sway_seat *seat = input_manager_current_seat();
|
||||||
|
con->floating_order = ++seat->floating_counter;
|
||||||
list_add(workspace->floating, con);
|
list_add(workspace->floating, con);
|
||||||
con->pending.workspace = workspace;
|
con->pending.workspace = workspace;
|
||||||
container_for_each_child(con, set_workspace, NULL);
|
container_for_each_child(con, set_workspace, NULL);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue