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 sway_drag {
|
||||
struct sway_seat *seat;
|
||||
struct wlr_drag *wlr_drag;
|
||||
struct wl_listener destroy;
|
||||
};
|
||||
|
||||
struct sway_seat {
|
||||
struct wlr_seat *wlr_seat;
|
||||
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) {
|
||||
struct wlr_layer_surface_v1 *wlr_layer_surface_v1;
|
||||
wl_list_for_each(wlr_layer_surface_v1, &server.layer_shell->surfaces, link) {
|
||||
if (wlr_layer_surface_v1->output != output->wlr_output ||
|
||||
wlr_layer_surface_v1->current.layer != ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY) {
|
||||
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;
|
||||
}
|
||||
struct sway_layer_surface *sway_layer_surface;
|
||||
wl_list_for_each(sway_layer_surface,
|
||||
&output->layers[ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY], link) {
|
||||
struct wlr_surface *wlr_surface = sway_layer_surface->layer_surface->surface;
|
||||
pixman_box32_t output_box = {
|
||||
.x2 = output->width,
|
||||
.y2 = output->height,
|
||||
|
|
|
|||
|
|
@ -501,7 +501,7 @@ void transaction_notify_view_ready_by_serial(struct sway_view *view,
|
|||
uint32_t serial) {
|
||||
struct sway_transaction_instruction *instruction =
|
||||
view->container->node.instruction;
|
||||
if (instruction->serial == serial) {
|
||||
if (instruction != NULL && instruction->serial == serial) {
|
||||
set_instruction_ready(instruction);
|
||||
}
|
||||
}
|
||||
|
|
@ -510,7 +510,8 @@ void transaction_notify_view_ready_by_size(struct sway_view *view,
|
|||
int width, int height) {
|
||||
struct sway_transaction_instruction *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) {
|
||||
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));
|
||||
desktop_damage_view(view);
|
||||
transaction_commit_dirty();
|
||||
transaction_notify_view_ready_by_size(view,
|
||||
new_geo.width, new_geo.height);
|
||||
} else {
|
||||
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));
|
||||
desktop_damage_view(view);
|
||||
transaction_commit_dirty();
|
||||
transaction_notify_view_ready_by_size(view,
|
||||
new_geo.width, new_geo.height);
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
||||
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,
|
||||
void *data) {
|
||||
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) {
|
||||
struct sway_seat *seat = wl_container_of(listener, seat, start_drag);
|
||||
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;
|
||||
if (wlr_drag_icon == NULL) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -280,8 +280,9 @@ static bool trigger_pointer_button_binding(struct sway_seat *seat,
|
|||
enum wlr_button_state state, uint32_t modifiers,
|
||||
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
|
||||
// pointer input for one. Emulated input should not trigger bindings.
|
||||
if (device->type != WLR_INPUT_DEVICE_POINTER) {
|
||||
// pointer input for one. Emulated input should not trigger bindings. The
|
||||
// device can be NULL if this is synthetic (e.g. swaymsg-generated) input.
|
||||
if (device && device->type != WLR_INPUT_DEVICE_POINTER) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -211,6 +211,23 @@ bool view_ancestor_is_only_visible(struct sway_view *view) {
|
|||
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) {
|
||||
struct side_gaps gaps = view->container->workspace->current_gaps;
|
||||
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;
|
||||
|
||||
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
|
||||
|| config->hide_edge_borders == E_VERTICAL || hide_smart) {
|
||||
|| config->hide_edge_borders == E_VERTICAL) {
|
||||
con->border_left = con->x != ws->x;
|
||||
int right_x = con->x + con->width;
|
||||
con->border_right = right_x != ws->x + ws->width;
|
||||
}
|
||||
|
||||
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;
|
||||
int bottom_y = con->y + con->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
|
||||
// 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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue