1
0
Fork 0
mirror of https://github.com/swaywm/sway.git synced 2025-04-15 18:06:20 +00:00

Merge branch 'master' into master

This commit is contained in:
Radical 2023-03-04 14:27:28 +01:00 committed by GitHub
commit fdb82b9d30
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 474 additions and 303 deletions

View file

@ -4,6 +4,7 @@ packages:
- eudev-dev
- gdk-pixbuf-dev
- json-c-dev
- libdisplay-info-dev
- libevdev-dev
- libinput-dev
- libseat-dev

View file

@ -3,6 +3,7 @@ packages:
- cairo
- gdk-pixbuf2
- json-c
- libdisplay-info
- libegl
- libinput
- libxcb

View file

@ -20,6 +20,7 @@ packages:
- devel/libudev-devd
- graphics/libdrm
- graphics/mesa-libs
- sysutils/libdisplay-info
- sysutils/seatd
- x11/libinput
- x11/libX11

View file

@ -108,6 +108,10 @@ void cursor_unhide(struct sway_cursor *cursor);
int cursor_get_timeout(struct sway_cursor *cursor);
void cursor_notify_key_press(struct sway_cursor *cursor);
void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
struct wlr_input_device *device, double dx, double dy,
double dx_unaccel, double dy_unaccel);
void dispatch_cursor_button(struct sway_cursor *cursor,
struct wlr_input_device *device, uint32_t time_msec, uint32_t button,
enum wlr_button_state state);

View file

@ -4,6 +4,7 @@
#include <wlr/types/wlr_keyboard_shortcuts_inhibit_v1.h>
#include <wlr/types/wlr_layer_shell_v1.h>
#include <wlr/types/wlr_seat.h>
#include <wlr/types/wlr_touch.h>
#include <wlr/util/edges.h>
#include "sway/config.h"
#include "sway/input/input-manager.h"
@ -36,6 +37,12 @@ struct sway_seatop_impl {
void (*swipe_end)(struct sway_seat *seat,
struct wlr_pointer_swipe_end_event *event);
void (*rebase)(struct sway_seat *seat, uint32_t time_msec);
void (*touch_motion)(struct sway_seat *seat,
struct wlr_touch_motion_event *event, double lx, double ly);
void (*touch_up)(struct sway_seat *seat,
struct wlr_touch_up_event *event);
void (*touch_down)(struct sway_seat *seat,
struct wlr_touch_down_event *event, double lx, double ly);
void (*tablet_tool_motion)(struct sway_seat *seat,
struct sway_tablet_tool *tool, uint32_t time_msec);
void (*tablet_tool_tip)(struct sway_seat *seat, struct sway_tablet_tool *tool,
@ -43,7 +50,7 @@ struct sway_seatop_impl {
void (*end)(struct sway_seat *seat);
void (*unref)(struct sway_seat *seat, struct sway_container *con);
void (*render)(struct sway_seat *seat, struct sway_output *output,
pixman_region32_t *damage);
const pixman_region32_t *damage);
bool allow_set_cursor;
};
@ -256,10 +263,13 @@ enum wlr_edges find_resize_edge(struct sway_container *cont,
void seatop_begin_default(struct sway_seat *seat);
void seatop_begin_down(struct sway_seat *seat, struct sway_container *con,
uint32_t time_msec, double sx, double sy);
double sx, double sy);
void seatop_begin_down_on_surface(struct sway_seat *seat,
struct wlr_surface *surface, uint32_t time_msec, double sx, double sy);
struct wlr_surface *surface, double sx, double sy);
void seatop_begin_touch_down(struct sway_seat *seat, struct wlr_surface *surface,
struct wlr_touch_down_event *event, double sx, double sy, double lx, double ly);
void seatop_begin_move_floating(struct sway_seat *seat,
struct sway_container *con);
@ -319,6 +329,15 @@ void seatop_swipe_update(struct sway_seat *seat,
void seatop_swipe_end(struct sway_seat *seat,
struct wlr_pointer_swipe_end_event *event);
void seatop_touch_motion(struct sway_seat *seat,
struct wlr_touch_motion_event *event, double lx, double ly);
void seatop_touch_up(struct sway_seat *seat,
struct wlr_touch_up_event *event);
void seatop_touch_down(struct sway_seat *seat,
struct wlr_touch_down_event *event, double lx, double ly);
void seatop_rebase(struct sway_seat *seat, uint32_t time_msec);
/**
@ -338,7 +357,7 @@ void seatop_unref(struct sway_seat *seat, struct sway_container *con);
* (eg. dropzone for move-tiling)
*/
void seatop_render(struct sway_seat *seat, struct sway_output *output,
pixman_region32_t *damage);
const pixman_region32_t *damage);
bool seatop_allows_set_cursor(struct sway_seat *seat);

View file

@ -112,8 +112,7 @@ bool output_has_opaque_overlay_layer_surface(struct sway_output *output);
struct sway_workspace *output_get_active_workspace(struct sway_output *output);
void output_render(struct sway_output *output, struct timespec *when,
pixman_region32_t *damage);
void output_render(struct sway_output *output, pixman_region32_t *damage);
void output_surface_for_each_surface(struct sway_output *output,
struct wlr_surface *surface, double ox, double oy,
@ -167,7 +166,7 @@ enum sway_container_layout output_get_default_layout(
struct sway_output *output);
void render_rect(struct sway_output *output,
pixman_region32_t *output_damage, const struct wlr_box *_box,
const pixman_region32_t *output_damage, const struct wlr_box *_box,
float color[static 4]);
void premultiply_alpha(float color[4], float opacity);

View file

@ -15,6 +15,7 @@ struct sway_surface {
struct wl_event_source *frame_done_timer;
};
void surface_update_outputs(struct wlr_surface *surface);
void surface_enter_output(struct wlr_surface *surface,
struct sway_output *output);
void surface_leave_output(struct wlr_surface *surface,

View file

@ -5,6 +5,7 @@
#include "sway/commands.h"
#include "sway/output.h"
#include "sway/tree/arrange.h"
#include "sway/tree/container.h"
#include "sway/tree/root.h"
#include "sway/tree/view.h"
#include "sway/tree/workspace.h"
@ -13,180 +14,6 @@
static const char expected_syntax[] =
"Expected 'swap container with id|con_id|mark <arg>'";
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 = config->handler_context.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);
}
}
static bool test_con_id(struct sway_container *container, void *data) {
size_t *con_id = data;
return container->node.id == *con_id;

View file

@ -460,6 +460,16 @@ static void queue_output_config(struct output_config *oc,
float scale;
if (oc && oc->scale > 0) {
scale = oc->scale;
// The factional-scale-v1 protocol uses increments of 120ths to send
// the scale factor to the client. Adjust the scale so that we use the
// same value as the clients'.
float adjusted_scale = round(scale * 120) / 120;
if (scale != adjusted_scale) {
sway_log(SWAY_INFO, "Adjusting output scale from %f to %f",
scale, adjusted_scale);
scale = adjusted_scale;
}
} else {
scale = compute_default_scale(wlr_output, pending);
sway_log(SWAY_DEBUG, "Auto-detected output scale: %f", scale);

View file

@ -383,7 +383,6 @@ static void handle_map(struct wl_listener *listener, void *data) {
struct sway_output *output = wlr_output->data;
output_damage_surface(output, sway_layer->geo.x, sway_layer->geo.y,
sway_layer->layer_surface->surface, true);
surface_enter_output(sway_layer->layer_surface->surface, output);
cursor_rebase_all();
}
@ -679,6 +678,8 @@ void handle_layer_shell_surface(struct wl_listener *listener, void *data) {
wl_list_insert(&output->layers[layer_surface->pending.layer],
&sway_layer->link);
surface_enter_output(layer_surface->surface, output);
// Temporarily set the layer's current state to pending
// So that we can easily arrange it
struct wlr_layer_surface_v1_state old_state = layer_surface->current;

View file

@ -496,6 +496,12 @@ static bool scan_out_fullscreen_view(struct sway_output *output,
if (n_surfaces != 1) {
return false;
}
size_t n_popups = 0;
output_view_for_each_popup_surface(output, view,
count_surface_iterator, &n_popups);
if (n_popups > 0) {
return false;
}
if (surface->buffer == NULL) {
return false;
@ -517,13 +523,34 @@ static bool scan_out_fullscreen_view(struct sway_output *output,
return wlr_output_commit(wlr_output);
}
static void get_frame_damage(struct sway_output *output,
pixman_region32_t *frame_damage) {
struct wlr_output *wlr_output = output->wlr_output;
int width, height;
wlr_output_transformed_resolution(wlr_output, &width, &height);
pixman_region32_init(frame_damage);
enum wl_output_transform transform =
wlr_output_transform_invert(wlr_output->transform);
wlr_region_transform(frame_damage, &output->damage_ring.current,
transform, width, height);
if (debug.damage != DAMAGE_DEFAULT) {
pixman_region32_union_rect(frame_damage, frame_damage,
0, 0, wlr_output->width, wlr_output->height);
}
}
static int output_repaint_timer_handler(void *data) {
struct sway_output *output = data;
if (output->wlr_output == NULL) {
struct wlr_output *wlr_output = output->wlr_output;
if (wlr_output == NULL) {
return 0;
}
output->wlr_output->frame_pending = false;
wlr_output->frame_pending = false;
struct sway_workspace *workspace = output->current.active_workspace;
if (workspace == NULL) {
@ -557,6 +584,11 @@ static int output_repaint_timer_handler(void *data) {
}
}
if (!output->wlr_output->needs_frame &&
!pixman_region32_not_empty(&output->damage_ring.current)) {
return 0;
}
int buffer_age;
if (!wlr_output_attach_render(output->wlr_output, &buffer_age)) {
return 0;
@ -565,20 +597,26 @@ static int output_repaint_timer_handler(void *data) {
pixman_region32_t damage;
pixman_region32_init(&damage);
wlr_damage_ring_get_buffer_damage(&output->damage_ring, buffer_age, &damage);
if (!output->wlr_output->needs_frame &&
!pixman_region32_not_empty(&output->damage_ring.current)) {
pixman_region32_fini(&damage);
wlr_output_rollback(output->wlr_output);
return 0;
}
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
output_render(output, &now, &damage);
output_render(output, &damage);
pixman_region32_fini(&damage);
pixman_region32_t frame_damage;
get_frame_damage(output, &frame_damage);
wlr_output_set_damage(wlr_output, &frame_damage);
pixman_region32_fini(&frame_damage);
if (!wlr_output_commit(wlr_output)) {
return 0;
}
wlr_damage_ring_rotate(&output->damage_ring);
output->last_frame = now;
return 0;
}
@ -859,6 +897,12 @@ static void update_textures(struct sway_container *con, void *data) {
container_update_marks_textures(con);
}
static void update_output_scale_iterator(struct sway_output *output,
struct sway_view *view, struct wlr_surface *surface,
struct wlr_box *box, void *user_data) {
surface_update_outputs(surface);
}
static void handle_commit(struct wl_listener *listener, void *data) {
struct sway_output *output = wl_container_of(listener, output, commit);
struct wlr_output_event_commit *event = data;
@ -873,6 +917,7 @@ static void handle_commit(struct wl_listener *listener, void *data) {
if (event->committed & WLR_OUTPUT_STATE_SCALE) {
output_for_each_container(output, update_textures, NULL);
output_for_each_surface(output, update_output_scale_iterator, NULL);
}
if (event->committed & (WLR_OUTPUT_STATE_TRANSFORM | WLR_OUTPUT_STATE_SCALE)) {

View file

@ -32,7 +32,7 @@
#endif
struct render_data {
pixman_region32_t *damage;
const pixman_region32_t *damage;
float alpha;
struct wlr_box *clip_box;
};
@ -102,7 +102,7 @@ static void set_scale_filter(struct wlr_output *wlr_output,
}
static void render_texture(struct wlr_output *wlr_output,
pixman_region32_t *output_damage, struct wlr_texture *texture,
const pixman_region32_t *output_damage, struct wlr_texture *texture,
const struct wlr_fbox *src_box, const struct wlr_box *dst_box,
const float matrix[static 9], float alpha) {
struct wlr_renderer *renderer = wlr_output->renderer;
@ -139,7 +139,7 @@ static void render_surface_iterator(struct sway_output *output,
struct wlr_box *_box, void *_data) {
struct render_data *data = _data;
struct wlr_output *wlr_output = output->wlr_output;
pixman_region32_t *output_damage = data->damage;
const pixman_region32_t *output_damage = data->damage;
float alpha = data->alpha;
struct wlr_texture *texture = wlr_surface_get_texture(surface);
@ -175,7 +175,7 @@ static void render_surface_iterator(struct sway_output *output,
}
static void render_layer_toplevel(struct sway_output *output,
pixman_region32_t *damage, struct wl_list *layer_surfaces) {
const pixman_region32_t *damage, struct wl_list *layer_surfaces) {
struct render_data data = {
.damage = damage,
.alpha = 1.0f,
@ -185,7 +185,7 @@ static void render_layer_toplevel(struct sway_output *output,
}
static void render_layer_popups(struct sway_output *output,
pixman_region32_t *damage, struct wl_list *layer_surfaces) {
const pixman_region32_t *damage, struct wl_list *layer_surfaces) {
struct render_data data = {
.damage = damage,
.alpha = 1.0f,
@ -196,7 +196,7 @@ static void render_layer_popups(struct sway_output *output,
#if HAVE_XWAYLAND
static void render_unmanaged(struct sway_output *output,
pixman_region32_t *damage, struct wl_list *unmanaged) {
const pixman_region32_t *damage, struct wl_list *unmanaged) {
struct render_data data = {
.damage = damage,
.alpha = 1.0f,
@ -207,7 +207,7 @@ static void render_unmanaged(struct sway_output *output,
#endif
static void render_drag_icons(struct sway_output *output,
pixman_region32_t *damage, struct wl_list *drag_icons) {
const pixman_region32_t *damage, struct wl_list *drag_icons) {
struct render_data data = {
.damage = damage,
.alpha = 1.0f,
@ -219,7 +219,7 @@ static void render_drag_icons(struct sway_output *output,
// _box.x and .y are expected to be layout-local
// _box.width and .height are expected to be output-buffer-local
void render_rect(struct sway_output *output,
pixman_region32_t *output_damage, const struct wlr_box *_box,
const pixman_region32_t *output_damage, const struct wlr_box *_box,
float color[static 4]) {
struct wlr_output *wlr_output = output->wlr_output;
struct wlr_renderer *renderer = wlr_output->renderer;
@ -259,7 +259,7 @@ void premultiply_alpha(float color[4], float opacity) {
}
static void render_view_toplevels(struct sway_view *view,
struct sway_output *output, pixman_region32_t *damage, float alpha) {
struct sway_output *output, const pixman_region32_t *damage, float alpha) {
struct render_data data = {
.damage = damage,
.alpha = alpha,
@ -282,7 +282,7 @@ static void render_view_toplevels(struct sway_view *view,
}
static void render_view_popups(struct sway_view *view,
struct sway_output *output, pixman_region32_t *damage, float alpha) {
struct sway_output *output, const pixman_region32_t *damage, float alpha) {
struct render_data data = {
.damage = damage,
.alpha = alpha,
@ -292,7 +292,7 @@ static void render_view_popups(struct sway_view *view,
}
static void render_saved_view(struct sway_view *view,
struct sway_output *output, pixman_region32_t *damage, float alpha) {
struct sway_output *output, const pixman_region32_t *damage, float alpha) {
struct wlr_output *wlr_output = output->wlr_output;
if (wl_list_empty(&view->saved_buffers)) {
@ -355,7 +355,7 @@ static void render_saved_view(struct sway_view *view,
/**
* Render a view's surface and left/bottom/right borders.
*/
static void render_view(struct sway_output *output, pixman_region32_t *damage,
static void render_view(struct sway_output *output, const pixman_region32_t *damage,
struct sway_container *con, struct border_colors *colors) {
struct sway_view *view = con->view;
if (!wl_list_empty(&view->saved_buffers)) {
@ -429,7 +429,7 @@ static void render_view(struct sway_output *output, pixman_region32_t *damage,
* The left side is: 1px border, 2px padding, title
*/
static void render_titlebar(struct sway_output *output,
pixman_region32_t *output_damage, struct sway_container *con,
const pixman_region32_t *output_damage, struct sway_container *con,
int x, int y, int width,
struct border_colors *colors, struct wlr_texture *title_texture,
struct wlr_texture *marks_texture) {
@ -684,7 +684,7 @@ static void render_titlebar(struct sway_output *output,
* Render the top border line for a view using "border pixel".
*/
static void render_top_border(struct sway_output *output,
pixman_region32_t *output_damage, struct sway_container *con,
const pixman_region32_t *output_damage, struct sway_container *con,
struct border_colors *colors) {
struct sway_container_state *state = &con->current;
if (!state->border_top) {
@ -714,7 +714,7 @@ struct parent_data {
};
static void render_container(struct sway_output *output,
pixman_region32_t *damage, struct sway_container *con, bool parent_focused);
const pixman_region32_t *damage, struct sway_container *con, bool parent_focused);
/**
* Render a container's children using a L_HORIZ or L_VERT layout.
@ -723,7 +723,7 @@ static void render_container(struct sway_output *output,
* they'll apply their own borders to their children.
*/
static void render_containers_linear(struct sway_output *output,
pixman_region32_t *damage, struct parent_data *parent) {
const pixman_region32_t *damage, struct parent_data *parent) {
for (int i = 0; i < parent->children->length; ++i) {
struct sway_container *child = parent->children->items[i];
@ -779,7 +779,7 @@ static bool container_has_focused_child(struct sway_container *con) {
* Render a container's children using the L_TABBED layout.
*/
static void render_containers_tabbed(struct sway_output *output,
pixman_region32_t *damage, struct parent_data *parent) {
const pixman_region32_t *damage, struct parent_data *parent) {
if (!parent->children->length) {
return;
}
@ -848,7 +848,7 @@ static void render_containers_tabbed(struct sway_output *output,
* Render a container's children using the L_STACKED layout.
*/
static void render_containers_stacked(struct sway_output *output,
pixman_region32_t *damage, struct parent_data *parent) {
const pixman_region32_t *damage, struct parent_data *parent) {
if (!parent->children->length) {
return;
}
@ -908,7 +908,7 @@ static void render_containers_stacked(struct sway_output *output,
}
static void render_containers(struct sway_output *output,
pixman_region32_t *damage, struct parent_data *parent) {
const pixman_region32_t *damage, struct parent_data *parent) {
if (config->hide_lone_tab && parent->children->length == 1) {
struct sway_container *child = parent->children->items[0];
if (child->view) {
@ -933,7 +933,7 @@ static void render_containers(struct sway_output *output,
}
static void render_container(struct sway_output *output,
pixman_region32_t *damage, struct sway_container *con, bool focused) {
const pixman_region32_t *damage, struct sway_container *con, bool focused) {
struct parent_data data = {
.layout = con->current.layout,
.box = {
@ -950,7 +950,7 @@ static void render_container(struct sway_output *output,
}
static void render_workspace(struct sway_output *output,
pixman_region32_t *damage, struct sway_workspace *ws, bool focused) {
const pixman_region32_t *damage, struct sway_workspace *ws, bool focused) {
struct parent_data data = {
.layout = ws->current.layout,
.box = {
@ -967,7 +967,7 @@ static void render_workspace(struct sway_output *output,
}
static void render_floating_container(struct sway_output *soutput,
pixman_region32_t *damage, struct sway_container *con) {
const pixman_region32_t *damage, struct sway_container *con) {
if (con->view) {
struct sway_view *view = con->view;
struct border_colors *colors;
@ -1002,7 +1002,7 @@ static void render_floating_container(struct sway_output *soutput,
}
static void render_floating(struct sway_output *soutput,
pixman_region32_t *damage) {
const pixman_region32_t *damage) {
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) {
@ -1022,15 +1022,14 @@ static void render_floating(struct sway_output *soutput,
}
static void render_seatops(struct sway_output *output,
pixman_region32_t *damage) {
const pixman_region32_t *damage) {
struct sway_seat *seat;
wl_list_for_each(seat, &server.input->seats, link) {
seatop_render(seat, output, damage);
}
}
void output_render(struct sway_output *output, struct timespec *when,
pixman_region32_t *damage) {
void output_render(struct sway_output *output, pixman_region32_t *damage) {
struct wlr_output *wlr_output = output->wlr_output;
struct wlr_renderer *renderer = output->server->renderer;
@ -1184,30 +1183,4 @@ renderer_end:
wlr_renderer_scissor(renderer, NULL);
wlr_output_render_software_cursors(wlr_output, damage);
wlr_renderer_end(renderer);
int width, height;
wlr_output_transformed_resolution(wlr_output, &width, &height);
pixman_region32_t frame_damage;
pixman_region32_init(&frame_damage);
enum wl_output_transform transform =
wlr_output_transform_invert(wlr_output->transform);
wlr_region_transform(&frame_damage, &output->damage_ring.current,
transform, width, height);
if (debug.damage != DAMAGE_DEFAULT) {
pixman_region32_union_rect(&frame_damage, &frame_damage,
0, 0, wlr_output->width, wlr_output->height);
}
wlr_output_set_damage(wlr_output, &frame_damage);
pixman_region32_fini(&frame_damage);
if (!wlr_output_commit(wlr_output)) {
return;
}
wlr_damage_ring_rotate(&output->damage_ring);
output->last_frame = *when;
}

View file

@ -47,7 +47,7 @@ void handle_compositor_new_surface(struct wl_listener *listener, void *data) {
}
}
static void surface_update_outputs(struct wlr_surface *surface) {
void surface_update_outputs(struct wlr_surface *surface) {
float scale = 1;
struct wlr_surface_output *surface_output;
wl_list_for_each(surface_output, &surface->current_outputs, link) {

View file

@ -364,7 +364,7 @@ void cursor_unhide(struct sway_cursor *cursor) {
wl_event_source_timer_update(cursor->hide_source, cursor_get_timeout(cursor));
}
static void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
void pointer_motion(struct sway_cursor *cursor, uint32_t time_msec,
struct wlr_input_device *device, double dx, double dy,
double dx_unaccel, double dy_unaccel) {
wlr_relative_pointer_manager_v1_send_relative_motion(
@ -479,43 +479,16 @@ static void handle_touch_down(struct wl_listener *listener, void *data) {
cursor_hide(cursor);
struct sway_seat *seat = cursor->seat;
struct wlr_seat *wlr_seat = seat->wlr_seat;
struct wlr_surface *surface = NULL;
double lx, ly;
wlr_cursor_absolute_to_layout_coords(cursor->cursor, &event->touch->base,
event->x, event->y, &lx, &ly);
double sx, sy;
struct sway_node *focused_node = node_at_coords(seat, lx, ly, &surface, &sx, &sy);
seat->touch_id = event->touch_id;
seat->touch_x = lx;
seat->touch_y = ly;
if (surface && wlr_surface_accepts_touch(wlr_seat, surface)) {
if (seat_is_input_allowed(seat, surface)) {
wlr_seat_touch_notify_down(wlr_seat, surface, event->time_msec,
event->touch_id, sx, sy);
if (focused_node) {
seat_set_focus(seat, focused_node);
}
}
} else if (!cursor->simulating_pointer_from_touch &&
(!surface || seat_is_input_allowed(seat, surface))) {
// Fallback to cursor simulation.
// The pointer_touch_id state is needed, so drags are not aborted when over
// a surface supporting touch and multi touch events don't interfere.
cursor->simulating_pointer_from_touch = true;
cursor->pointer_touch_id = seat->touch_id;
double dx, dy;
dx = lx - cursor->cursor->x;
dy = ly - cursor->cursor->y;
pointer_motion(cursor, event->time_msec, &event->touch->base, dx, dy,
dx, dy);
dispatch_cursor_button(cursor, &event->touch->base, event->time_msec,
BTN_LEFT, WLR_BUTTON_PRESSED);
}
seatop_touch_down(seat, event, lx, ly);
}
static void handle_touch_up(struct wl_listener *listener, void *data) {
@ -523,7 +496,7 @@ static void handle_touch_up(struct wl_listener *listener, void *data) {
struct wlr_touch_up_event *event = data;
cursor_handle_activity_from_device(cursor, &event->touch->base);
struct wlr_seat *wlr_seat = cursor->seat->wlr_seat;
struct sway_seat *seat = cursor->seat;
if (cursor->simulating_pointer_from_touch) {
if (cursor->pointer_touch_id == cursor->seat->touch_id) {
@ -532,7 +505,7 @@ static void handle_touch_up(struct wl_listener *listener, void *data) {
event->time_msec, BTN_LEFT, WLR_BUTTON_RELEASED);
}
} else {
wlr_seat_touch_notify_up(wlr_seat, event->time_msec, event->touch_id);
seatop_touch_up(seat, event);
}
}
@ -543,19 +516,14 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) {
cursor_handle_activity_from_device(cursor, &event->touch->base);
struct sway_seat *seat = cursor->seat;
struct wlr_seat *wlr_seat = seat->wlr_seat;
struct wlr_surface *surface = NULL;
double lx, ly;
wlr_cursor_absolute_to_layout_coords(cursor->cursor, &event->touch->base,
event->x, event->y, &lx, &ly);
double sx, sy;
node_at_coords(cursor->seat, lx, ly, &surface, &sx, &sy);
if (seat->touch_id == event->touch_id) {
seat->touch_x = lx;
seat->touch_y = ly;
struct sway_drag_icon *drag_icon;
wl_list_for_each(drag_icon, &root->drag_icons, link) {
if (drag_icon->seat == seat) {
@ -572,9 +540,8 @@ static void handle_touch_motion(struct wl_listener *listener, void *data) {
pointer_motion(cursor, event->time_msec, &event->touch->base,
dx, dy, dx, dy);
}
} else if (surface) {
wlr_seat_touch_notify_motion(wlr_seat, event->time_msec,
event->touch_id, sx, sy);
} else {
seatop_touch_motion(seat, event, lx, ly);
}
}

View file

@ -220,7 +220,8 @@ bool sway_input_configure_libinput_device(struct sway_input_device *input_device
bool changed = false;
if (ic->mapped_to_output &&
!output_by_name_or_id(ic->mapped_to_output)) {
strcmp("*", ic->mapped_to_output) != 0 &&
!output_by_name_or_id(ic->mapped_to_output)) {
sway_log(SWAY_DEBUG,
"%s '%s' is mapped to offline output '%s'; disabling input",
ic->input_type, ic->identifier, ic->mapped_to_output);

View file

@ -1618,6 +1618,26 @@ void seatop_pointer_axis(struct sway_seat *seat,
}
}
void seatop_touch_motion(struct sway_seat *seat, struct wlr_touch_motion_event *event,
double lx, double ly) {
if (seat->seatop_impl->touch_motion) {
seat->seatop_impl->touch_motion(seat, event, lx, ly);
}
}
void seatop_touch_up(struct sway_seat *seat, struct wlr_touch_up_event *event) {
if (seat->seatop_impl->touch_up) {
seat->seatop_impl->touch_up(seat, event);
}
}
void seatop_touch_down(struct sway_seat *seat, struct wlr_touch_down_event *event,
double lx, double ly) {
if (seat->seatop_impl->touch_down) {
seat->seatop_impl->touch_down(seat, event, lx, ly);
}
}
void seatop_tablet_tool_tip(struct sway_seat *seat,
struct sway_tablet_tool *tool, uint32_t time_msec,
enum wlr_tablet_tool_tip_state state) {
@ -1707,7 +1727,7 @@ void seatop_end(struct sway_seat *seat) {
}
void seatop_render(struct sway_seat *seat, struct sway_output *output,
pixman_region32_t *damage) {
const pixman_region32_t *damage) {
if (seat->seatop_impl->render) {
seat->seatop_impl->render(seat, output, damage);
}

View file

@ -261,7 +261,7 @@ static void handle_tablet_tool_tip(struct sway_seat *seat,
// Handle tapping on a container surface
seat_set_focus_container(seat, cont);
seatop_begin_down(seat, node->sway_container, time_msec, sx, sy);
seatop_begin_down(seat, node->sway_container, sx, sy);
}
#if HAVE_XWAYLAND
// Handle tapping on an xwayland unmanaged view
@ -374,7 +374,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
transaction_commit_dirty();
}
if (state == WLR_BUTTON_PRESSED) {
seatop_begin_down_on_surface(seat, surface, time_msec, sx, sy);
seatop_begin_down_on_surface(seat, surface, sx, sy);
}
seat_pointer_notify_button(seat, time_msec, button, state);
return;
@ -499,7 +499,7 @@ static void handle_button(struct sway_seat *seat, uint32_t time_msec,
// Handle mousedown on a container surface
if (surface && cont && state == WLR_BUTTON_PRESSED) {
seatop_begin_down(seat, cont, time_msec, sx, sy);
seatop_begin_down(seat, cont, sx, sy);
seat_pointer_notify_button(seat, time_msec, button, WLR_BUTTON_PRESSED);
return;
}
@ -649,6 +649,36 @@ static void handle_tablet_tool_motion(struct sway_seat *seat,
e->previous_node = node;
}
static void handle_touch_down(struct sway_seat *seat,
struct wlr_touch_down_event *event, double lx, double ly) {
struct wlr_surface *surface = NULL;
struct wlr_seat *wlr_seat = seat->wlr_seat;
struct sway_cursor *cursor = seat->cursor;
double sx, sy;
node_at_coords(seat, seat->touch_x, seat->touch_y, &surface, &sx, &sy);
if (surface && wlr_surface_accepts_touch(wlr_seat, surface)) {
if (seat_is_input_allowed(seat, surface)) {
cursor->simulating_pointer_from_touch = false;
seatop_begin_touch_down(seat, surface, event, sx, sy, lx, ly);
}
} else if (!cursor->simulating_pointer_from_touch &&
(!surface || seat_is_input_allowed(seat, surface))) {
// Fallback to cursor simulation.
// The pointer_touch_id state is needed, so drags are not aborted when over
// a surface supporting touch and multi touch events don't interfere.
cursor->simulating_pointer_from_touch = true;
cursor->pointer_touch_id = seat->touch_id;
double dx, dy;
dx = seat->touch_x - cursor->cursor->x;
dy = seat->touch_y - cursor->cursor->y;
pointer_motion(cursor, event->time_msec, &event->touch->base, dx, dy,
dx, dy);
dispatch_cursor_button(cursor, &event->touch->base, event->time_msec,
BTN_LEFT, WLR_BUTTON_PRESSED);
}
}
/*----------------------------------------\
* Functions used by handle_pointer_axis /
*--------------------------------------*/
@ -1096,6 +1126,7 @@ static const struct sway_seatop_impl seatop_impl = {
.swipe_begin = handle_swipe_begin,
.swipe_update = handle_swipe_update,
.swipe_end = handle_swipe_end,
.touch_down = handle_touch_down,
.rebase = handle_rebase,
.allow_set_cursor = true,
};

View file

@ -2,12 +2,20 @@
#include <float.h>
#include <wlr/types/wlr_cursor.h>
#include <wlr/types/wlr_tablet_v2.h>
#include <wlr/types/wlr_touch.h>
#include "sway/input/cursor.h"
#include "sway/input/seat.h"
#include "sway/tree/view.h"
#include "sway/desktop/transaction.h"
#include "log.h"
struct seatop_touch_point_event {
double ref_lx, ref_ly; // touch's x/y at start of op
double ref_con_lx, ref_con_ly; // container's x/y at start of op
int32_t touch_id;
struct wl_list link;
};
struct seatop_down_event {
struct sway_container *con;
struct sway_seat *seat;
@ -15,8 +23,87 @@ struct seatop_down_event {
struct wlr_surface *surface;
double ref_lx, ref_ly; // cursor's x/y at start of op
double ref_con_lx, ref_con_ly; // container's x/y at start of op
struct wl_list point_events; // seatop_touch_point_event::link
};
static void handle_touch_motion(struct sway_seat *seat,
struct wlr_touch_motion_event *event, double lx, double ly) {
struct seatop_down_event *e = seat->seatop_data;
struct seatop_touch_point_event *point_event;
bool found = false;
wl_list_for_each(point_event, &e->point_events, link) {
if (point_event->touch_id == event->touch_id) {
found = true;
break;
}
}
if (!found) {
return; // Probably not a point_event from this seatop_down
}
double moved_x = lx - point_event->ref_lx;
double moved_y = ly - point_event->ref_ly;
double sx = point_event->ref_con_lx + moved_x;
double sy = point_event->ref_con_ly + moved_y;
wlr_seat_touch_notify_motion(seat->wlr_seat, event->time_msec,
event->touch_id, sx, sy);
}
static void handle_touch_up(struct sway_seat *seat,
struct wlr_touch_up_event *event) {
struct seatop_down_event *e = seat->seatop_data;
struct seatop_touch_point_event *point_event, *tmp;
wl_list_for_each_safe(point_event, tmp, &e->point_events, link) {
if (point_event->touch_id == event->touch_id) {
wl_list_remove(&point_event->link);
free(point_event);
break;
}
}
if (wl_list_empty(&e->point_events)) {
seatop_begin_default(seat);
}
wlr_seat_touch_notify_up(seat->wlr_seat, event->time_msec, event->touch_id);
}
static void handle_touch_down(struct sway_seat *seat,
struct wlr_touch_down_event *event, double lx, double ly) {
struct seatop_down_event *e = seat->seatop_data;
double sx, sy;
struct wlr_surface *surface = NULL;
struct sway_node *focused_node = node_at_coords(seat, seat->touch_x,
seat->touch_y, &surface, &sx, &sy);
if (!surface || surface != e->surface) { // Must start from the initial surface
return;
}
struct seatop_touch_point_event *point_event =
calloc(1, sizeof(struct seatop_touch_point_event));
if (!sway_assert(point_event, "Unable to allocate point_event")) {
return;
}
point_event->touch_id = event->touch_id;
point_event->ref_lx = lx;
point_event->ref_ly = ly;
point_event->ref_con_lx = sx;
point_event->ref_con_ly = sy;
wl_list_insert(&e->point_events, &point_event->link);
wlr_seat_touch_notify_down(seat->wlr_seat, surface, event->time_msec,
event->touch_id, sx, sy);
if (focused_node) {
seat_set_focus(seat, focused_node);
}
}
static void handle_pointer_axis(struct sway_seat *seat,
struct wlr_pointer_axis_event *event) {
struct sway_input_device *input_device =
@ -99,14 +186,17 @@ static const struct sway_seatop_impl seatop_impl = {
.pointer_axis = handle_pointer_axis,
.tablet_tool_tip = handle_tablet_tool_tip,
.tablet_tool_motion = handle_tablet_tool_motion,
.touch_motion = handle_touch_motion,
.touch_up = handle_touch_up,
.touch_down = handle_touch_down,
.unref = handle_unref,
.end = handle_end,
.allow_set_cursor = true,
};
void seatop_begin_down(struct sway_seat *seat, struct sway_container *con,
uint32_t time_msec, double sx, double sy) {
seatop_begin_down_on_surface(seat, con->view->surface, time_msec, sx, sy);
double sx, double sy) {
seatop_begin_down_on_surface(seat, con->view->surface, sx, sy);
struct seatop_down_event *e = seat->seatop_data;
e->con = con;
@ -114,13 +204,20 @@ void seatop_begin_down(struct sway_seat *seat, struct sway_container *con,
transaction_commit_dirty();
}
void seatop_begin_touch_down(struct sway_seat *seat,
struct wlr_surface *surface, struct wlr_touch_down_event *event,
double sx, double sy, double lx, double ly) {
seatop_begin_down_on_surface(seat, surface, sx, sy);
handle_touch_down(seat, event, lx, ly);
}
void seatop_begin_down_on_surface(struct sway_seat *seat,
struct wlr_surface *surface, uint32_t time_msec, double sx, double sy) {
struct wlr_surface *surface, double sx, double sy) {
seatop_end(seat);
struct seatop_down_event *e =
calloc(1, sizeof(struct seatop_down_event));
if (!e) {
if (!sway_assert(e, "Unable to allocate e")) {
return;
}
e->con = NULL;
@ -132,6 +229,7 @@ void seatop_begin_down_on_surface(struct sway_seat *seat,
e->ref_ly = seat->cursor->cursor->y;
e->ref_con_lx = sx;
e->ref_con_ly = sy;
wl_list_init(&e->point_events);
seat->seatop_impl = &seatop_impl;
seat->seatop_data = e;

View file

@ -32,7 +32,7 @@ struct seatop_move_tiling_event {
};
static void handle_render(struct sway_seat *seat,
struct sway_output *output, pixman_region32_t *damage) {
struct sway_output *output, const pixman_region32_t *damage) {
struct seatop_move_tiling_event *e = seat->seatop_data;
if (!e->threshold_reached) {
return;

View file

@ -508,7 +508,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 {
@ -1764,3 +1763,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);
}
}

View file

@ -369,16 +369,13 @@ void view_set_activated(struct sway_view *view, bool activated) {
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();
}
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 {
@ -389,8 +386,12 @@ void view_request_activate(struct sway_view *view, struct sway_seat *seat) {
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;

View file

@ -774,14 +774,12 @@ void render_frame(struct swaybar_output *output) {
ctx.cairo = cairo;
cairo_font_options_t *fo = cairo_font_options_create();
cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL);
cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_GRAY);
ctx.textaa_safe = fo;
if (output->subpixel == WL_OUTPUT_SUBPIXEL_NONE) {
ctx.textaa_sharp = ctx.textaa_safe;
} else {
fo = cairo_font_options_create();
cairo_font_options_set_hint_style(fo, CAIRO_HINT_STYLE_FULL);
cairo_font_options_set_antialias(fo, CAIRO_ANTIALIAS_SUBPIXEL);
cairo_font_options_set_subpixel_order(fo,
to_cairo_subpixel_order(output->subpixel));

View file

@ -60,7 +60,7 @@ static void pretty_print_cmd(json_object *r) {
if (!success_object(r)) {
json_object *error;
if (!json_object_object_get_ex(r, "error", &error)) {
printf("An unknkown error occurred");
printf("An unknown error occurred");
} else {
printf("Error: %s\n", json_object_get_string(error));
}