This commit is contained in:
dmitry 2020-07-01 01:43:24 +03:00
commit 0645dac76e
8 changed files with 89 additions and 24 deletions

View file

@ -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;

View file

@ -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,

View file

@ -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);
}

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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.