mirror of
https://github.com/swaywm/sway.git
synced 2026-04-25 06:46:24 -04:00
Merge branch 'master' of https://github.com/swaywm/sway
This commit is contained in:
commit
0645dac76e
8 changed files with 89 additions and 24 deletions
|
|
@ -64,6 +64,12 @@ struct sway_drag_icon {
|
||||||
struct wl_listener destroy;
|
struct wl_listener destroy;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct sway_drag {
|
||||||
|
struct sway_seat *seat;
|
||||||
|
struct wlr_drag *wlr_drag;
|
||||||
|
struct wl_listener destroy;
|
||||||
|
};
|
||||||
|
|
||||||
struct sway_seat {
|
struct sway_seat {
|
||||||
struct wlr_seat *wlr_seat;
|
struct wlr_seat *wlr_seat;
|
||||||
struct sway_cursor *cursor;
|
struct sway_cursor *cursor;
|
||||||
|
|
|
||||||
|
|
@ -434,18 +434,10 @@ struct sway_workspace *output_get_active_workspace(struct sway_output *output) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool output_has_opaque_overlay_layer_surface(struct sway_output *output) {
|
bool output_has_opaque_overlay_layer_surface(struct sway_output *output) {
|
||||||
struct wlr_layer_surface_v1 *wlr_layer_surface_v1;
|
struct sway_layer_surface *sway_layer_surface;
|
||||||
wl_list_for_each(wlr_layer_surface_v1, &server.layer_shell->surfaces, link) {
|
wl_list_for_each(sway_layer_surface,
|
||||||
if (wlr_layer_surface_v1->output != output->wlr_output ||
|
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], link) {
|
||||||
wlr_layer_surface_v1->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY) {
|
struct wlr_surface *wlr_surface = sway_layer_surface->layer_surface->surface;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
struct wlr_surface *wlr_surface = wlr_layer_surface_v1->surface;
|
|
||||||
struct sway_layer_surface *sway_layer_surface =
|
|
||||||
layer_from_wlr_layer_surface_v1(wlr_layer_surface_v1);
|
|
||||||
if (sway_layer_surface == NULL) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
pixman_box32_t output_box = {
|
pixman_box32_t output_box = {
|
||||||
.x2 = output->width,
|
.x2 = output->width,
|
||||||
.y2 = output->height,
|
.y2 = output->height,
|
||||||
|
|
|
||||||
|
|
@ -501,7 +501,7 @@ void transaction_notify_view_ready_by_serial(struct sway_view *view,
|
||||||
uint32_t serial) {
|
uint32_t serial) {
|
||||||
struct sway_transaction_instruction *instruction =
|
struct sway_transaction_instruction *instruction =
|
||||||
view->container->node.instruction;
|
view->container->node.instruction;
|
||||||
if (instruction->serial == serial) {
|
if (instruction != NULL && instruction->serial == serial) {
|
||||||
set_instruction_ready(instruction);
|
set_instruction_ready(instruction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -510,7 +510,8 @@ void transaction_notify_view_ready_by_size(struct sway_view *view,
|
||||||
int width, int height) {
|
int width, int height) {
|
||||||
struct sway_transaction_instruction *instruction =
|
struct sway_transaction_instruction *instruction =
|
||||||
view->container->node.instruction;
|
view->container->node.instruction;
|
||||||
if (instruction->container_state.content_width == width &&
|
if (instruction != NULL &&
|
||||||
|
instruction->container_state.content_width == width &&
|
||||||
instruction->container_state.content_height == height) {
|
instruction->container_state.content_height == height) {
|
||||||
set_instruction_ready(instruction);
|
set_instruction_ready(instruction);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -293,6 +293,8 @@ static void handle_commit(struct wl_listener *listener, void *data) {
|
||||||
memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box));
|
memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box));
|
||||||
desktop_damage_view(view);
|
desktop_damage_view(view);
|
||||||
transaction_commit_dirty();
|
transaction_commit_dirty();
|
||||||
|
transaction_notify_view_ready_by_size(view,
|
||||||
|
new_geo.width, new_geo.height);
|
||||||
} else {
|
} else {
|
||||||
memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box));
|
memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -383,6 +383,8 @@ static void handle_commit(struct wl_listener *listener, void *data) {
|
||||||
memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box));
|
memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box));
|
||||||
desktop_damage_view(view);
|
desktop_damage_view(view);
|
||||||
transaction_commit_dirty();
|
transaction_commit_dirty();
|
||||||
|
transaction_notify_view_ready_by_size(view,
|
||||||
|
new_geo.width, new_geo.height);
|
||||||
} else {
|
} else {
|
||||||
memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box));
|
memcpy(&view->geometry, &new_geo, sizeof(struct wlr_box));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -402,6 +402,31 @@ static void drag_icon_handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
free(icon);
|
free(icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void drag_handle_destroy(struct wl_listener *listener, void *data) {
|
||||||
|
struct sway_drag *drag = wl_container_of(listener, drag, destroy);
|
||||||
|
|
||||||
|
// Focus enter isn't sent during drag, so refocus the focused node, layer
|
||||||
|
// surface or unmanaged surface.
|
||||||
|
struct sway_seat *seat = drag->seat;
|
||||||
|
struct sway_node *focus = seat_get_focus(seat);
|
||||||
|
if (focus) {
|
||||||
|
seat_set_focus(seat, NULL);
|
||||||
|
seat_set_focus(seat, focus);
|
||||||
|
} else if (seat->focused_layer) {
|
||||||
|
struct wlr_layer_surface_v1 *layer = seat->focused_layer;
|
||||||
|
seat_set_focus_layer(seat, NULL);
|
||||||
|
seat_set_focus_layer(seat, layer);
|
||||||
|
} else {
|
||||||
|
struct wlr_surface *unmanaged = seat->wlr_seat->keyboard_state.focused_surface;
|
||||||
|
seat_set_focus_surface(seat, NULL, false);
|
||||||
|
seat_set_focus_surface(seat, unmanaged, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
drag->wlr_drag->data = NULL;
|
||||||
|
wl_list_remove(&drag->destroy.link);
|
||||||
|
free(drag);
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_request_start_drag(struct wl_listener *listener,
|
static void handle_request_start_drag(struct wl_listener *listener,
|
||||||
void *data) {
|
void *data) {
|
||||||
struct sway_seat *seat = wl_container_of(listener, seat, request_start_drag);
|
struct sway_seat *seat = wl_container_of(listener, seat, request_start_drag);
|
||||||
|
|
@ -431,6 +456,19 @@ static void handle_request_start_drag(struct wl_listener *listener,
|
||||||
static void handle_start_drag(struct wl_listener *listener, void *data) {
|
static void handle_start_drag(struct wl_listener *listener, void *data) {
|
||||||
struct sway_seat *seat = wl_container_of(listener, seat, start_drag);
|
struct sway_seat *seat = wl_container_of(listener, seat, start_drag);
|
||||||
struct wlr_drag *wlr_drag = data;
|
struct wlr_drag *wlr_drag = data;
|
||||||
|
|
||||||
|
struct sway_drag *drag = calloc(1, sizeof(struct sway_drag));
|
||||||
|
if (drag == NULL) {
|
||||||
|
sway_log(SWAY_ERROR, "Allocation failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
drag->seat = seat;
|
||||||
|
drag->wlr_drag = wlr_drag;
|
||||||
|
wlr_drag->data = drag;
|
||||||
|
|
||||||
|
drag->destroy.notify = drag_handle_destroy;
|
||||||
|
wl_signal_add(&wlr_drag->events.destroy, &drag->destroy);
|
||||||
|
|
||||||
struct wlr_drag_icon *wlr_drag_icon = wlr_drag->icon;
|
struct wlr_drag_icon *wlr_drag_icon = wlr_drag->icon;
|
||||||
if (wlr_drag_icon == NULL) {
|
if (wlr_drag_icon == NULL) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -280,8 +280,9 @@ static bool trigger_pointer_button_binding(struct sway_seat *seat,
|
||||||
enum wlr_button_state state, uint32_t modifiers,
|
enum wlr_button_state state, uint32_t modifiers,
|
||||||
bool on_titlebar, bool on_border, bool on_contents, bool on_workspace) {
|
bool on_titlebar, bool on_border, bool on_contents, bool on_workspace) {
|
||||||
// We can reach this for non-pointer devices if we're currently emulating
|
// We can reach this for non-pointer devices if we're currently emulating
|
||||||
// pointer input for one. Emulated input should not trigger bindings.
|
// pointer input for one. Emulated input should not trigger bindings. The
|
||||||
if (device->type != WLR_INPUT_DEVICE_POINTER) {
|
// device can be NULL if this is synthetic (e.g. swaymsg-generated) input.
|
||||||
|
if (device && device->type != WLR_INPUT_DEVICE_POINTER) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,23 @@ bool view_ancestor_is_only_visible(struct sway_view *view) {
|
||||||
return only_visible;
|
return only_visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool view_is_only_visible(struct sway_view *view) {
|
||||||
|
struct sway_container *con = view->container;
|
||||||
|
while (con) {
|
||||||
|
enum sway_container_layout layout = container_parent_layout(con);
|
||||||
|
if (layout != L_TABBED && layout != L_STACKED) {
|
||||||
|
list_t *siblings = container_get_siblings(con);
|
||||||
|
if (siblings && siblings->length > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
con = con->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static bool gaps_to_edge(struct sway_view *view) {
|
static bool gaps_to_edge(struct sway_view *view) {
|
||||||
struct side_gaps gaps = view->container->workspace->current_gaps;
|
struct side_gaps gaps = view->container->workspace->current_gaps;
|
||||||
return gaps.top > 0 || gaps.right > 0 || gaps.bottom > 0 || gaps.left > 0;
|
return gaps.top > 0 || gaps.right > 0 || gaps.bottom > 0 || gaps.left > 0;
|
||||||
|
|
@ -245,25 +262,31 @@ void view_autoconfigure(struct sway_view *view) {
|
||||||
double y_offset = 0;
|
double y_offset = 0;
|
||||||
|
|
||||||
if (!container_is_floating(con) && ws) {
|
if (!container_is_floating(con) && ws) {
|
||||||
|
|
||||||
bool smart = config->hide_edge_borders_smart == ESMART_ON ||
|
|
||||||
(config->hide_edge_borders_smart == ESMART_NO_GAPS &&
|
|
||||||
!gaps_to_edge(view));
|
|
||||||
bool hide_smart = smart && view_ancestor_is_only_visible(view);
|
|
||||||
|
|
||||||
if (config->hide_edge_borders == E_BOTH
|
if (config->hide_edge_borders == E_BOTH
|
||||||
|| config->hide_edge_borders == E_VERTICAL || hide_smart) {
|
|| config->hide_edge_borders == E_VERTICAL) {
|
||||||
con->border_left = con->x != ws->x;
|
con->border_left = con->x != ws->x;
|
||||||
int right_x = con->x + con->width;
|
int right_x = con->x + con->width;
|
||||||
con->border_right = right_x != ws->x + ws->width;
|
con->border_right = right_x != ws->x + ws->width;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config->hide_edge_borders == E_BOTH
|
if (config->hide_edge_borders == E_BOTH
|
||||||
|| config->hide_edge_borders == E_HORIZONTAL || hide_smart) {
|
|| config->hide_edge_borders == E_HORIZONTAL) {
|
||||||
con->border_top = con->y != ws->y;
|
con->border_top = con->y != ws->y;
|
||||||
int bottom_y = con->y + con->height;
|
int bottom_y = con->y + con->height;
|
||||||
con->border_bottom = bottom_y != ws->y + ws->height;
|
con->border_bottom = bottom_y != ws->y + ws->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool smart = config->hide_edge_borders_smart == ESMART_ON ||
|
||||||
|
(config->hide_edge_borders_smart == ESMART_NO_GAPS &&
|
||||||
|
!gaps_to_edge(view));
|
||||||
|
if (smart) {
|
||||||
|
bool show_border = !view_is_only_visible(view);
|
||||||
|
con->border_left &= show_border;
|
||||||
|
con->border_right &= show_border;
|
||||||
|
con->border_top &= show_border;
|
||||||
|
con->border_bottom &= show_border;
|
||||||
|
}
|
||||||
|
|
||||||
// In a tabbed or stacked container, the container's y is the top of the
|
// In a tabbed or stacked container, the container's y is the top of the
|
||||||
// title area. We have to offset the surface y by the height of the title,
|
// title area. We have to offset the surface y by the height of the title,
|
||||||
// bar, and disable any top border because we'll always have the title bar.
|
// bar, and disable any top border because we'll always have the title bar.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue