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:
commit
fdb82b9d30
23 changed files with 474 additions and 303 deletions
.builds
include/sway
sway
commands
config
desktop
input
tree
swaybar
swaymsg
|
@ -4,6 +4,7 @@ packages:
|
|||
- eudev-dev
|
||||
- gdk-pixbuf-dev
|
||||
- json-c-dev
|
||||
- libdisplay-info-dev
|
||||
- libevdev-dev
|
||||
- libinput-dev
|
||||
- libseat-dev
|
||||
|
|
|
@ -3,6 +3,7 @@ packages:
|
|||
- cairo
|
||||
- gdk-pixbuf2
|
||||
- json-c
|
||||
- libdisplay-info
|
||||
- libegl
|
||||
- libinput
|
||||
- libxcb
|
||||
|
|
|
@ -20,6 +20,7 @@ packages:
|
|||
- devel/libudev-devd
|
||||
- graphics/libdrm
|
||||
- graphics/mesa-libs
|
||||
- sysutils/libdisplay-info
|
||||
- sysutils/seatd
|
||||
- x11/libinput
|
||||
- x11/libX11
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue