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

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) { 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,

View file

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

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

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

View file

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

View file

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

View file

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