summaryrefslogtreecommitdiff
path: root/sway/tree
diff options
context:
space:
mode:
authorReza Jelveh <[email protected]>2024-04-15 13:39:41 +0800
committerGitHub <[email protected]>2024-04-15 01:39:41 -0400
commitfb86ed6b0588dfdebfb66ce875bc63cfa0a897f6 (patch)
tree29857a1769107adc58696f08d379f608aa4e29a2 /sway/tree
parenta5e79676c4bd22fc5902182acf0667907202a465 (diff)
feat: 1.9 merge (#277)
Co-authored-by: William McKinnon <[email protected]> Co-authored-by: Erik Reider <[email protected]>
Diffstat (limited to 'sway/tree')
-rw-r--r--sway/tree/arrange.c14
-rw-r--r--sway/tree/container.c296
-rw-r--r--sway/tree/output.c3
-rw-r--r--sway/tree/root.c41
-rw-r--r--sway/tree/view.c65
-rw-r--r--sway/tree/workspace.c25
6 files changed, 292 insertions, 152 deletions
diff --git a/sway/tree/arrange.c b/sway/tree/arrange.c
index 9c1a11e5..af925d05 100644
--- a/sway/tree/arrange.c
+++ b/sway/tree/arrange.c
@@ -264,6 +264,9 @@ void arrange_workspace(struct sway_workspace *workspace) {
area->width, area->height, area->x, area->y);
bool first_arrange = workspace->width == 0 && workspace->height == 0;
+ struct wlr_box prev_box;
+ workspace_get_box(workspace, &prev_box);
+
double prev_x = workspace->x - workspace->current_gaps.left;
double prev_y = workspace->y - workspace->current_gaps.top;
workspace->width = area->width;
@@ -277,13 +280,14 @@ void arrange_workspace(struct sway_workspace *workspace) {
if (!first_arrange && (diff_x != 0 || diff_y != 0)) {
for (int i = 0; i < workspace->floating->length; ++i) {
struct sway_container *floater = workspace->floating->items[i];
- container_floating_translate(floater, diff_x, diff_y);
- double center_x = floater->pending.x + floater->pending.width / 2;
- double center_y = floater->pending.y + floater->pending.height / 2;
struct wlr_box workspace_box;
workspace_get_box(workspace, &workspace_box);
- if (!wlr_box_contains_point(&workspace_box, center_x, center_y)) {
- container_floating_move_to_center(floater);
+ floating_fix_coordinates(floater, &prev_box, &workspace_box);
+ // Set transformation for scratchpad windows.
+ if (floater->scratchpad) {
+ struct wlr_box output_box;
+ output_get_box(output, &output_box);
+ floater->transform = output_box;
}
}
}
diff --git a/sway/tree/container.c b/sway/tree/container.c
index 2e61ff5c..9b90b774 100644
--- a/sway/tree/container.c
+++ b/sway/tree/container.c
@@ -3,14 +3,10 @@
#include <drm_fourcc.h>
#include <stdint.h>
#include <stdlib.h>
-#include <string.h>
-#include <strings.h>
-#include <sys/stat.h>
#include <wayland-server-core.h>
#include <wlr/types/wlr_linux_dmabuf_v1.h>
#include <wlr/types/wlr_output_layout.h>
#include <wlr/types/wlr_subcompositor.h>
-#include <wlr/render/drm_format_set.h>
#include "linux-dmabuf-unstable-v1-protocol.h"
#include "cairo_util.h"
#include "pango.h"
@@ -22,6 +18,7 @@
#include "sway/ipc-server.h"
#include "sway/output.h"
#include "sway/server.h"
+#include "sway/surface.h"
#include "sway/tree/arrange.h"
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
@@ -392,17 +389,17 @@ struct sway_container *tiling_container_at(struct sway_node *parent,
}
static bool surface_is_popup(struct wlr_surface *surface) {
- while (!wlr_surface_is_xdg_surface(surface)) {
- if (!wlr_surface_is_subsurface(surface)) {
+ while (wlr_xdg_surface_try_from_wlr_surface(surface) == NULL) {
+ struct wlr_subsurface *subsurface =
+ wlr_subsurface_try_from_wlr_surface(surface);
+ if (subsurface == NULL) {
return false;
}
- struct wlr_subsurface *subsurface =
- wlr_subsurface_from_wlr_surface(surface);
surface = subsurface->parent;
}
struct wlr_xdg_surface *xdg_surface =
- wlr_xdg_surface_from_wlr_surface(surface);
- return xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP;
+ wlr_xdg_surface_try_from_wlr_surface(surface);
+ return xdg_surface->role == WLR_XDG_SURFACE_ROLE_POPUP && xdg_surface->popup != NULL;
}
struct sway_container *container_at(struct sway_workspace *workspace,
@@ -516,7 +513,6 @@ static void render_titlebar_text_texture(struct sway_output *output,
cairo_t *c = cairo_create(dummy_surface);
cairo_set_antialias(c, CAIRO_ANTIALIAS_BEST);
cairo_font_options_t *fo = cairo_font_options_create();
- cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL);
if (output->wlr_output->subpixel == WL_OUTPUT_SUBPIXEL_NONE) {
cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_GRAY);
} else {
@@ -721,6 +717,21 @@ void floating_calculate_constraints(int *min_width, int *max_width,
}
+void floating_fix_coordinates(struct sway_container *con, struct wlr_box *old, struct wlr_box *new) {
+ if (!old->width || !old->height) {
+ // Fall back to centering on the workspace.
+ container_floating_move_to_center(con);
+ } else {
+ int rel_x = con->pending.x - old->x + (con->pending.width / 2);
+ int rel_y = con->pending.y - old->y + (con->pending.height / 2);
+
+ con->pending.x = new->x + (double)(rel_x * new->width) / old->width - (con->pending.width / 2);
+ con->pending.y = new->y + (double)(rel_y * new->height) / old->height - (con->pending.height / 2);
+
+ sway_log(SWAY_DEBUG, "Transformed container %p to coords (%f, %f)", con, con->pending.x, con->pending.y);
+ }
+}
+
static void floating_natural_resize(struct sway_container *con) {
int min_width, max_width, min_height, max_height;
floating_calculate_constraints(&min_width, &max_width,
@@ -1034,6 +1045,13 @@ void container_floating_move_to(struct sway_container *con,
workspace_add_floating(new_workspace, con);
arrange_workspace(old_workspace);
arrange_workspace(new_workspace);
+ // If the moved container was a visible scratchpad container, then
+ // update its transform.
+ if (con->scratchpad) {
+ struct wlr_box output_box;
+ output_get_box(new_output, &output_box);
+ con->transform = output_box;
+ }
workspace_detect_urgent(old_workspace);
workspace_detect_urgent(new_workspace);
}
@@ -1065,16 +1083,6 @@ void container_end_mouse_operation(struct sway_container *container) {
}
}
-static bool devid_from_fd(int fd, dev_t *devid) {
- struct stat stat;
- if (fstat(fd, &stat) != 0) {
- sway_log_errno(SWAY_ERROR, "fstat failed");
- return false;
- }
- *devid = stat.st_rdev;
- return true;
-}
-
static void set_fullscreen(struct sway_container *con, bool enable) {
if (!con->view) {
return;
@@ -1101,60 +1109,19 @@ static void set_fullscreen(struct sway_container *con, bool enable) {
}
struct sway_output *output = con->pending.workspace->output;
- struct wlr_output *wlr_output = output->wlr_output;
-
- // TODO: add wlroots helpers for all of this stuff
-
- const struct wlr_drm_format_set *renderer_formats =
- wlr_renderer_get_dmabuf_texture_formats(server.wlr_renderer);
- assert(renderer_formats);
-
- int renderer_drm_fd = wlr_renderer_get_drm_fd(server.wlr_renderer);
- int backend_drm_fd = wlr_backend_get_drm_fd(wlr_output->backend);
- if (renderer_drm_fd < 0 || backend_drm_fd < 0) {
- return;
- }
-
- dev_t render_dev, scanout_dev;
- if (!devid_from_fd(renderer_drm_fd, &render_dev) ||
- !devid_from_fd(backend_drm_fd, &scanout_dev)) {
- return;
- }
-
- const struct wlr_drm_format_set *output_formats =
- wlr_output_get_primary_formats(output->wlr_output,
- WLR_BUFFER_CAP_DMABUF);
- if (!output_formats) {
- return;
- }
-
- struct wlr_drm_format_set scanout_formats = {0};
- if (!wlr_drm_format_set_intersect(&scanout_formats,
- output_formats, renderer_formats)) {
- return;
- }
-
- struct wlr_linux_dmabuf_feedback_v1_tranche tranches[] = {
- {
- .target_device = scanout_dev,
- .flags = ZWP_LINUX_DMABUF_FEEDBACK_V1_TRANCHE_FLAGS_SCANOUT,
- .formats = &scanout_formats,
- },
- {
- .target_device = render_dev,
- .formats = renderer_formats,
- },
+ const struct wlr_linux_dmabuf_feedback_v1_init_options options = {
+ .main_renderer = server.renderer,
+ .scanout_primary_output = output->wlr_output,
};
+ struct wlr_linux_dmabuf_feedback_v1 feedback = {0};
+ if (!wlr_linux_dmabuf_feedback_v1_init_with_options(&feedback, &options)) {
+ return;
+ }
- const struct wlr_linux_dmabuf_feedback_v1 feedback = {
- .main_device = render_dev,
- .tranches = tranches,
- .tranches_len = sizeof(tranches) / sizeof(tranches[0]),
- };
wlr_linux_dmabuf_v1_set_surface_feedback(server.linux_dmabuf_v1,
con->view->surface, &feedback);
- wlr_drm_format_set_finish(&scanout_formats);
+ wlr_linux_dmabuf_feedback_v1_finish(&feedback);
}
static void container_fullscreen_workspace(struct sway_container *con) {
@@ -1326,14 +1293,14 @@ bool container_is_fullscreen_or_child(struct sway_container *container) {
static void surface_send_enter_iterator(struct wlr_surface *surface,
int x, int y, void *data) {
- struct wlr_output *wlr_output = data;
- wlr_surface_send_enter(surface, wlr_output);
+ struct sway_output *output = data;
+ surface_enter_output(surface, output);
}
static void surface_send_leave_iterator(struct wlr_surface *surface,
int x, int y, void *data) {
- struct wlr_output *wlr_output = data;
- wlr_surface_send_leave(surface, wlr_output);
+ struct sway_output *output = data;
+ surface_leave_output(surface, output);
}
void container_discover_outputs(struct sway_container *con) {
@@ -1359,7 +1326,7 @@ void container_discover_outputs(struct sway_container *con) {
sway_log(SWAY_DEBUG, "Container %p entered output %p", con, output);
if (con->view) {
view_for_each_surface(con->view,
- surface_send_enter_iterator, output->wlr_output);
+ surface_send_enter_iterator, output);
if (con->view->foreign_toplevel) {
wlr_foreign_toplevel_handle_v1_output_enter(
con->view->foreign_toplevel, output->wlr_output);
@@ -1371,7 +1338,7 @@ void container_discover_outputs(struct sway_container *con) {
sway_log(SWAY_DEBUG, "Container %p left output %p", con, output);
if (con->view) {
view_for_each_surface(con->view,
- surface_send_leave_iterator, output->wlr_output);
+ surface_send_leave_iterator, output);
if (con->view->foreign_toplevel) {
wlr_foreign_toplevel_handle_v1_output_leave(
con->view->foreign_toplevel, output->wlr_output);
@@ -1412,9 +1379,6 @@ list_t *container_get_siblings(struct sway_container *container) {
if (container->pending.parent) {
return container->pending.parent->pending.children;
}
- if (container_is_scratchpad_hidden(container)) {
- return NULL;
- }
if (!container->pending.workspace) {
return NULL;
}
@@ -1827,3 +1791,177 @@ int container_squash(struct sway_container *con) {
}
return change;
}
+
+static void swap_places(struct sway_container *con1,
+ struct sway_container *con2) {
+ struct sway_container *temp = malloc(sizeof(struct sway_container));
+ temp->pending.x = con1->pending.x;
+ temp->pending.y = con1->pending.y;
+ temp->pending.width = con1->pending.width;
+ temp->pending.height = con1->pending.height;
+ temp->width_fraction = con1->width_fraction;
+ temp->height_fraction = con1->height_fraction;
+ temp->pending.parent = con1->pending.parent;
+ temp->pending.workspace = con1->pending.workspace;
+ bool temp_floating = container_is_floating(con1);
+
+ con1->pending.x = con2->pending.x;
+ con1->pending.y = con2->pending.y;
+ con1->pending.width = con2->pending.width;
+ con1->pending.height = con2->pending.height;
+ con1->width_fraction = con2->width_fraction;
+ con1->height_fraction = con2->height_fraction;
+
+ con2->pending.x = temp->pending.x;
+ con2->pending.y = temp->pending.y;
+ con2->pending.width = temp->pending.width;
+ con2->pending.height = temp->pending.height;
+ con2->width_fraction = temp->width_fraction;
+ con2->height_fraction = temp->height_fraction;
+
+ int temp_index = container_sibling_index(con1);
+ if (con2->pending.parent) {
+ container_insert_child(con2->pending.parent, con1,
+ container_sibling_index(con2));
+ } else if (container_is_floating(con2)) {
+ workspace_add_floating(con2->pending.workspace, con1);
+ } else {
+ workspace_insert_tiling(con2->pending.workspace, con1,
+ container_sibling_index(con2));
+ }
+ if (temp->pending.parent) {
+ container_insert_child(temp->pending.parent, con2, temp_index);
+ } else if (temp_floating) {
+ workspace_add_floating(temp->pending.workspace, con2);
+ } else {
+ workspace_insert_tiling(temp->pending.workspace, con2, temp_index);
+ }
+
+ free(temp);
+}
+
+static void swap_focus(struct sway_container *con1,
+ struct sway_container *con2, struct sway_seat *seat,
+ struct sway_container *focus) {
+ if (focus == con1 || focus == con2) {
+ struct sway_workspace *ws1 = con1->pending.workspace;
+ struct sway_workspace *ws2 = con2->pending.workspace;
+ enum sway_container_layout layout1 = container_parent_layout(con1);
+ enum sway_container_layout layout2 = container_parent_layout(con2);
+ if (focus == con1 && (layout2 == L_TABBED || layout2 == L_STACKED)) {
+ if (workspace_is_visible(ws2)) {
+ seat_set_focus(seat, &con2->node);
+ }
+ seat_set_focus_container(seat, ws1 != ws2 ? con2 : con1);
+ } else if (focus == con2 && (layout1 == L_TABBED
+ || layout1 == L_STACKED)) {
+ if (workspace_is_visible(ws1)) {
+ seat_set_focus(seat, &con1->node);
+ }
+ seat_set_focus_container(seat, ws1 != ws2 ? con1 : con2);
+ } else if (ws1 != ws2) {
+ seat_set_focus_container(seat, focus == con1 ? con2 : con1);
+ } else {
+ seat_set_focus_container(seat, focus);
+ }
+ } else {
+ seat_set_focus_container(seat, focus);
+ }
+
+ if (root->fullscreen_global) {
+ seat_set_focus(seat,
+ seat_get_focus_inactive(seat, &root->fullscreen_global->node));
+ }
+}
+
+void container_swap(struct sway_container *con1, struct sway_container *con2) {
+ if (!sway_assert(con1 && con2, "Cannot swap with nothing")) {
+ return;
+ }
+ if (!sway_assert(!container_has_ancestor(con1, con2)
+ && !container_has_ancestor(con2, con1),
+ "Cannot swap ancestor and descendant")) {
+ return;
+ }
+
+ sway_log(SWAY_DEBUG, "Swapping containers %zu and %zu",
+ con1->node.id, con2->node.id);
+
+ bool scratch1 = con1->scratchpad;
+ bool hidden1 = container_is_scratchpad_hidden(con1);
+ bool scratch2 = con2->scratchpad;
+ bool hidden2 = container_is_scratchpad_hidden(con2);
+ if (scratch1) {
+ if (hidden1) {
+ root_scratchpad_show(con1);
+ }
+ root_scratchpad_remove_container(con1);
+ }
+ if (scratch2) {
+ if (hidden2) {
+ root_scratchpad_show(con2);
+ }
+ root_scratchpad_remove_container(con2);
+ }
+
+ enum sway_fullscreen_mode fs1 = con1->pending.fullscreen_mode;
+ if (fs1) {
+ container_fullscreen_disable(con1);
+ }
+ enum sway_fullscreen_mode fs2 = con2->pending.fullscreen_mode;
+ if (fs2) {
+ container_fullscreen_disable(con2);
+ }
+
+ struct sway_seat *seat = input_manager_current_seat();
+ struct sway_container *focus = seat_get_focused_container(seat);
+ struct sway_workspace *vis1 =
+ output_get_active_workspace(con1->pending.workspace->output);
+ struct sway_workspace *vis2 =
+ output_get_active_workspace(con2->pending.workspace->output);
+ if (!sway_assert(vis1 && vis2, "con1 or con2 are on an output without a"
+ "workspace. This should not happen")) {
+ return;
+ }
+
+ char *stored_prev_name = NULL;
+ if (seat->prev_workspace_name) {
+ stored_prev_name = strdup(seat->prev_workspace_name);
+ }
+
+ swap_places(con1, con2);
+
+ if (!workspace_is_visible(vis1)) {
+ seat_set_focus(seat, seat_get_focus_inactive(seat, &vis1->node));
+ }
+ if (!workspace_is_visible(vis2)) {
+ seat_set_focus(seat, seat_get_focus_inactive(seat, &vis2->node));
+ }
+
+ swap_focus(con1, con2, seat, focus);
+
+ if (stored_prev_name) {
+ free(seat->prev_workspace_name);
+ seat->prev_workspace_name = stored_prev_name;
+ }
+
+ if (scratch1) {
+ root_scratchpad_add_container(con2, NULL);
+ if (!hidden1) {
+ root_scratchpad_show(con2);
+ }
+ }
+ if (scratch2) {
+ root_scratchpad_add_container(con1, NULL);
+ if (!hidden2) {
+ root_scratchpad_show(con1);
+ }
+ }
+
+ if (fs1) {
+ container_set_fullscreen(con2, fs1);
+ }
+ if (fs2) {
+ container_set_fullscreen(con1, fs2);
+ }
+}
diff --git a/sway/tree/output.c b/sway/tree/output.c
index eccab2f7..4aa3a7fe 100644
--- a/sway/tree/output.c
+++ b/sway/tree/output.c
@@ -271,14 +271,13 @@ void output_disable(struct sway_output *output) {
list_del(root->outputs, index);
output->enabled = false;
- output->current_mode = NULL;
arrange_root();
// Reconfigure all devices, since devices with map_to_output directives for
// an output that goes offline should stop sending events as long as the
// output remains offline.
- input_manager_configure_all_inputs();
+ input_manager_configure_all_input_mappings();
}
void output_begin_destroy(struct sway_output *output) {
diff --git a/sway/tree/root.c b/sway/tree/root.c
index 9df6f002..381e83de 100644
--- a/sway/tree/root.c
+++ b/sway/tree/root.c
@@ -50,6 +50,7 @@ struct sway_root *root_create(void) {
void root_destroy(struct sway_root *root) {
wl_list_remove(&root->output_layout_change.link);
list_free(root->scratchpad);
+ list_free(root->non_desktop_outputs);
list_free(root->outputs);
wlr_output_layout_destroy(root->output_layout);
free(root);
@@ -59,9 +60,8 @@ void root_destroy(struct sway_root *root) {
static void root_scratchpad_set_minimize(struct sway_container *con, bool minimize) {
if (con->view) {
#if HAVE_XWAYLAND
- if (wlr_surface_is_xwayland_surface(con->view->surface)) {
- struct wlr_xwayland_surface *xsurface
- = wlr_xwayland_surface_from_wlr_surface(con->view->surface);
+ struct wlr_xwayland_surface *xsurface;
+ if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(con->view->surface))) {
wlr_xwayland_surface_set_minimized(xsurface, minimize);
return;
}
@@ -73,6 +73,16 @@ static void root_scratchpad_set_minimize(struct sway_container *con, bool minimi
}
}
+static void set_container_transform(struct sway_workspace *ws,
+ struct sway_container *con) {
+ struct sway_output *output = ws->output;
+ struct wlr_box box = {0};
+ if (output) {
+ output_get_box(output, &box);
+ }
+ con->transform = box;
+}
+
void root_scratchpad_add_container(struct sway_container *con, struct sway_workspace *ws) {
if (!sway_assert(!con->scratchpad, "Container is already in scratchpad")) {
return;
@@ -81,6 +91,8 @@ void root_scratchpad_add_container(struct sway_container *con, struct sway_works
struct sway_container *parent = con->pending.parent;
struct sway_workspace *workspace = con->pending.workspace;
+ set_container_transform(workspace, con);
+
// Clear the fullscreen mode when sending to the scratchpad
if (con->pending.fullscreen_mode != FULLSCREEN_NONE) {
container_fullscreen_disable(con);
@@ -155,7 +167,10 @@ void root_scratchpad_show(struct sway_container *con) {
// Show the container
if (old_ws) {
container_detach(con);
- workspace_consider_destroy(old_ws);
+ // Make sure the last inactive container on the old workspace is above
+ // the workspace itself in the focus stack.
+ struct sway_node *node = seat_get_focus_inactive(seat, &old_ws->node);
+ seat_set_raw_focus(seat, node);
} else {
// Act on the ancestor of scratchpad hidden split containers
while (con->pending.parent) {
@@ -169,18 +184,18 @@ void root_scratchpad_show(struct sway_container *con) {
root_scratchpad_set_minimize(con, false);
}
- // Make sure the container's center point overlaps this workspace
- double center_lx = con->pending.x + con->pending.width / 2;
- double center_ly = con->pending.y + con->pending.height / 2;
-
- struct wlr_box workspace_box;
- workspace_get_box(new_ws, &workspace_box);
- if (!wlr_box_contains_point(&workspace_box, center_lx, center_ly)) {
- container_floating_resize_and_center(con);
+ if (new_ws->output) {
+ struct wlr_box output_box;
+ output_get_box(new_ws->output, &output_box);
+ floating_fix_coordinates(con, &con->transform, &output_box);
}
+ set_container_transform(new_ws, con);
arrange_workspace(new_ws);
seat_set_focus(seat, seat_get_focus_inactive(seat, &con->node));
+ if (old_ws) {
+ workspace_consider_destroy(old_ws);
+ }
}
static void disable_fullscreen(struct sway_container *con, void *data) {
@@ -205,6 +220,8 @@ void root_scratchpad_hide(struct sway_container *con) {
root_scratchpad_set_minimize(con, true);
}
+ set_container_transform(con->pending.workspace, con);
+
disable_fullscreen(con, NULL);
container_for_each_child(con, disable_fullscreen, NULL);
container_detach(con);
diff --git a/sway/tree/view.c b/sway/tree/view.c
index 272967f4..bd2268fd 100644
--- a/sway/tree/view.c
+++ b/sway/tree/view.c
@@ -25,6 +25,7 @@
#include "sway/output.h"
#include "sway/input/seat.h"
#include "sway/server.h"
+#include "sway/surface.h"
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
#include "sway/tree/view.h"
@@ -366,16 +367,15 @@ void view_set_activated(struct sway_view *view, bool activated) {
}
}
-void view_request_activate(struct sway_view *view) {
+void view_request_activate(struct sway_view *view, struct sway_seat *seat) {
struct sway_workspace *ws = view->container->pending.workspace;
- if (!ws) { // hidden scratchpad container
- return;
+ if (!seat) {
+ seat = input_manager_current_seat();
}
- struct sway_seat *seat = input_manager_current_seat();
switch (config->focus_on_window_activation) {
case FOWA_SMART:
- if (workspace_is_visible(ws)) {
+ if (ws && workspace_is_visible(ws)) {
seat_set_focus_container(seat, view->container);
container_raise_floating(view->container);
} else {
@@ -386,8 +386,12 @@ void view_request_activate(struct sway_view *view) {
view_set_urgent(view, true);
break;
case FOWA_FOCUS:
- seat_set_focus_container(seat, view->container);
- container_raise_floating(view->container);
+ if (container_is_scratchpad_hidden_or_child(view->container)) {
+ root_scratchpad_show(view->container);
+ } else {
+ seat_set_focus_container(seat, view->container);
+ container_raise_floating(view->container);
+ }
break;
case FOWA_NONE:
break;
@@ -395,6 +399,12 @@ void view_request_activate(struct sway_view *view) {
transaction_commit_dirty();
}
+void view_request_urgent(struct sway_view *view) {
+ if (config->focus_on_window_activation != FOWA_NONE) {
+ view_set_urgent(view, true);
+ }
+}
+
void view_set_csd_from_server(struct sway_view *view, bool enabled) {
sway_log(SWAY_DEBUG, "Telling view %p to set CSD to %i", view, enabled);
if (view->xdg_decoration) {
@@ -526,7 +536,7 @@ static void view_populate_pid(struct sway_view *view) {
#if HAVE_XWAYLAND
case SWAY_VIEW_XWAYLAND:;
struct wlr_xwayland_surface *surf =
- wlr_xwayland_surface_from_wlr_surface(view->surface);
+ wlr_xwayland_surface_try_from_wlr_surface(view->surface);
pid = surf->pid;
break;
#endif
@@ -885,9 +895,8 @@ void view_map(struct sway_view *view, struct wlr_surface *wlr_surface,
bool set_focus = should_focus(view);
#if HAVE_XWAYLAND
- if (wlr_surface_is_xwayland_surface(wlr_surface)) {
- struct wlr_xwayland_surface *xsurface =
- wlr_xwayland_surface_from_wlr_surface(wlr_surface);
+ struct wlr_xwayland_surface *xsurface;
+ if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(wlr_surface))) {
set_focus &= wlr_xwayland_icccm_input_model(xsurface) !=
WLR_ICCCM_INPUT_MODEL_NONE;
}
@@ -911,6 +920,8 @@ void view_unmap(struct sway_view *view) {
wl_list_remove(&view->surface_new_subsurface.link);
+ view->executed_criteria->length = 0;
+
if (view->urgent_timer) {
wl_event_source_remove(view->urgent_timer);
view->urgent_timer = NULL;
@@ -984,7 +995,7 @@ static void subsurface_get_view_coords(struct sway_view_child *child,
*sx = *sy = 0;
}
struct wlr_subsurface *subsurface =
- wlr_subsurface_from_wlr_surface(surface);
+ wlr_subsurface_try_from_wlr_surface(surface);
*sx += subsurface->current.x;
*sy += subsurface->current.y;
}
@@ -1179,7 +1190,7 @@ void view_child_init(struct sway_view_child *child,
if (container != NULL) {
struct sway_workspace *workspace = container->pending.workspace;
if (workspace) {
- wlr_surface_send_enter(child->surface, workspace->output->wlr_output);
+ surface_enter_output(child->surface, workspace->output);
}
}
@@ -1220,33 +1231,21 @@ void view_child_destroy(struct sway_view_child *child) {
}
struct sway_view *view_from_wlr_surface(struct wlr_surface *wlr_surface) {
- if (wlr_surface_is_xdg_surface(wlr_surface)) {
- struct wlr_xdg_surface *xdg_surface =
- wlr_xdg_surface_from_wlr_surface(wlr_surface);
- if (xdg_surface == NULL) {
- return NULL;
- }
+ struct wlr_xdg_surface *xdg_surface;
+ if ((xdg_surface = wlr_xdg_surface_try_from_wlr_surface(wlr_surface))) {
return view_from_wlr_xdg_surface(xdg_surface);
}
#if HAVE_XWAYLAND
- if (wlr_surface_is_xwayland_surface(wlr_surface)) {
- struct wlr_xwayland_surface *xsurface =
- wlr_xwayland_surface_from_wlr_surface(wlr_surface);
- if (xsurface == NULL) {
- return NULL;
- }
+ struct wlr_xwayland_surface *xsurface;
+ if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(wlr_surface))) {
return view_from_wlr_xwayland_surface(xsurface);
}
#endif
- if (wlr_surface_is_subsurface(wlr_surface)) {
- struct wlr_subsurface *subsurface =
- wlr_subsurface_from_wlr_surface(wlr_surface);
- if (subsurface == NULL) {
- return NULL;
- }
+ struct wlr_subsurface *subsurface;
+ if ((subsurface = wlr_subsurface_try_from_wlr_surface(wlr_surface))) {
return view_from_wlr_surface(subsurface->parent);
}
- if (wlr_surface_is_layer_surface(wlr_surface)) {
+ if (wlr_layer_surface_v1_try_from_wlr_surface(wlr_surface) != NULL) {
return NULL;
}
@@ -1463,7 +1462,7 @@ static void view_save_buffer_iterator(struct wlr_surface *surface,
int sx, int sy, void *data) {
struct sway_view *view = data;
- if (surface && wlr_surface_has_buffer(surface)) {
+ if (surface && surface->buffer) {
wlr_buffer_lock(&surface->buffer->base);
struct sway_saved_buffer *saved_buffer = calloc(1, sizeof(struct sway_saved_buffer));
saved_buffer->buffer = surface->buffer;
diff --git a/sway/tree/workspace.c b/sway/tree/workspace.c
index b2305341..98a177fa 100644
--- a/sway/tree/workspace.c
+++ b/sway/tree/workspace.c
@@ -178,22 +178,16 @@ void workspace_consider_destroy(struct sway_workspace *ws) {
static bool workspace_valid_on_output(const char *output_name,
const char *ws_name) {
struct workspace_config *wsc = workspace_find_config(ws_name);
- char identifier[128];
struct sway_output *output = output_by_name_or_id(output_name);
if (!output) {
return false;
}
- output_name = output->wlr_output->name;
- output_get_identifier(identifier, sizeof(identifier), output);
-
if (!wsc) {
return true;
}
for (int i = 0; i < wsc->outputs->length; i++) {
- if (strcmp(wsc->outputs->items[i], "*") == 0 ||
- strcmp(wsc->outputs->items[i], output_name) == 0 ||
- strcmp(wsc->outputs->items[i], identifier) == 0) {
+ if (output_match_name_or_id(output, wsc->outputs->items[i])) {
return true;
}
}
@@ -288,13 +282,10 @@ char *workspace_next_name(const char *output_name) {
// assignments primarily, falling back to bindings and numbers.
struct sway_mode *mode = config->current_mode;
- char identifier[128];
struct sway_output *output = output_by_name_or_id(output_name);
if (!output) {
return NULL;
}
- output_name = output->wlr_output->name;
- output_get_identifier(identifier, sizeof(identifier), output);
int order = INT_MAX;
char *target = NULL;
@@ -314,9 +305,7 @@ char *workspace_next_name(const char *output_name) {
}
bool found = false;
for (int j = 0; j < wsc->outputs->length; ++j) {
- if (strcmp(wsc->outputs->items[j], "*") == 0 ||
- strcmp(wsc->outputs->items[j], output_name) == 0 ||
- strcmp(wsc->outputs->items[j], identifier) == 0) {
+ if (output_match_name_or_id(output, wsc->outputs->items[j])) {
found = true;
free(target);
target = strdup(wsc->workspace);
@@ -656,15 +645,9 @@ void workspace_output_add_priority(struct sway_workspace *workspace,
struct sway_output *workspace_output_get_highest_available(
struct sway_workspace *ws, struct sway_output *exclude) {
- char exclude_id[128] = {'\0'};
- if (exclude) {
- output_get_identifier(exclude_id, sizeof(exclude_id), exclude);
- }
-
for (int i = 0; i < ws->output_priority->length; i++) {
- char *name = ws->output_priority->items[i];
- if (exclude && (strcmp(name, exclude->wlr_output->name) == 0
- || strcmp(name, exclude_id) == 0)) {
+ const char *name = ws->output_priority->items[i];
+ if (exclude && output_match_name_or_id(exclude, name)) {
continue;
}