mirror of
https://github.com/swaywm/sway.git
synced 2025-11-18 06:59:48 -05:00
Merge branch 'wlroots' into fix-focus-inactive
This commit is contained in:
commit
65f254f3fb
33 changed files with 1357 additions and 995 deletions
|
|
@ -163,6 +163,7 @@ static struct cmd_handler command_handlers[] = {
|
|||
{ "kill", cmd_kill },
|
||||
{ "layout", cmd_layout },
|
||||
{ "move", cmd_move },
|
||||
{ "opacity", cmd_opacity },
|
||||
{ "reload", cmd_reload },
|
||||
{ "split", cmd_split },
|
||||
{ "splith", cmd_splith },
|
||||
|
|
|
|||
39
sway/commands/opacity.c
Normal file
39
sway/commands/opacity.c
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include "sway/commands.h"
|
||||
#include "sway/tree/view.h"
|
||||
#include "log.h"
|
||||
|
||||
static bool parse_opacity(const char *opacity, float *val) {
|
||||
char *err;
|
||||
*val = strtof(opacity, &err);
|
||||
if (*val < 0 || *val > 1 || *err) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct cmd_results *cmd_opacity(int argc, char **argv) {
|
||||
struct cmd_results *error = NULL;
|
||||
if ((error = checkarg(argc, "layout", EXPECTED_EQUAL_TO, 1))) {
|
||||
return error;
|
||||
}
|
||||
|
||||
struct sway_container *con =
|
||||
config->handler_context.current_container;
|
||||
|
||||
float opacity = 0.0f;
|
||||
|
||||
if (!parse_opacity(argv[0], &opacity)) {
|
||||
return cmd_results_new(CMD_INVALID, "opacity <value>",
|
||||
"Invalid value (expected 0..1): %s", argv[0]);
|
||||
}
|
||||
|
||||
con->alpha = opacity;
|
||||
|
||||
if (con->type == C_VIEW) {
|
||||
view_damage_whole(con->sway_view);
|
||||
}
|
||||
|
||||
return cmd_results_new(CMD_SUCCESS, NULL, NULL);
|
||||
}
|
||||
|
|
@ -75,7 +75,7 @@ static bool surface_intersect_output(struct wlr_surface *surface,
|
|||
|
||||
static void render_surface(struct wlr_surface *surface,
|
||||
struct wlr_output *wlr_output, struct timespec *when,
|
||||
double ox, double oy, float rotation) {
|
||||
double ox, double oy, float rotation, float alpha) {
|
||||
struct wlr_renderer *renderer =
|
||||
wlr_backend_get_renderer(wlr_output->backend);
|
||||
|
||||
|
|
@ -95,8 +95,8 @@ static void render_surface(struct wlr_surface *surface,
|
|||
wlr_matrix_project_box(matrix, &box, transform, rotation,
|
||||
wlr_output->transform_matrix);
|
||||
|
||||
// TODO: configurable alpha
|
||||
wlr_render_texture_with_matrix(renderer, surface->texture, matrix, 1.0f);
|
||||
wlr_render_texture_with_matrix(renderer, surface->texture,
|
||||
matrix, alpha);
|
||||
|
||||
wlr_surface_send_frame_done(surface, when);
|
||||
}
|
||||
|
|
@ -110,13 +110,13 @@ static void render_surface(struct wlr_surface *surface,
|
|||
surface->current->width, surface->current->height, rotation);
|
||||
|
||||
render_surface(subsurface->surface, wlr_output, when,
|
||||
ox + sx, oy + sy, rotation);
|
||||
ox + sx, oy + sy, rotation, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface,
|
||||
struct wlr_output *wlr_output, struct timespec *when, double base_x,
|
||||
double base_y, float rotation) {
|
||||
double base_y, float rotation, float alpha) {
|
||||
double width = surface->surface->current->width;
|
||||
double height = surface->surface->current->height;
|
||||
|
||||
|
|
@ -136,19 +136,19 @@ static void render_xdg_v6_popups(struct wlr_xdg_surface_v6 *surface,
|
|||
width, height, rotation);
|
||||
|
||||
render_surface(popup->surface, wlr_output, when,
|
||||
base_x + popup_sx, base_y + popup_sy, rotation);
|
||||
base_x + popup_sx, base_y + popup_sy, rotation, alpha);
|
||||
render_xdg_v6_popups(popup, wlr_output, when,
|
||||
base_x + popup_sx, base_y + popup_sy, rotation);
|
||||
base_x + popup_sx, base_y + popup_sy, rotation, alpha);
|
||||
}
|
||||
}
|
||||
|
||||
static void render_wl_shell_surface(struct wlr_wl_shell_surface *surface,
|
||||
struct wlr_output *wlr_output, struct timespec *when,
|
||||
double lx, double ly, float rotation,
|
||||
double lx, double ly, float rotation, float alpha,
|
||||
bool is_child) {
|
||||
if (is_child || surface->state != WLR_WL_SHELL_SURFACE_STATE_POPUP) {
|
||||
render_surface(surface->surface, wlr_output, when,
|
||||
lx, ly, rotation);
|
||||
lx, ly, rotation, alpha);
|
||||
|
||||
double width = surface->surface->current->width;
|
||||
double height = surface->surface->current->height;
|
||||
|
|
@ -164,7 +164,7 @@ static void render_wl_shell_surface(struct wlr_wl_shell_surface *surface,
|
|||
width, height, rotation);
|
||||
|
||||
render_wl_shell_surface(popup, wlr_output, when,
|
||||
lx + popup_x, ly + popup_y, rotation, true);
|
||||
lx + popup_x, ly + popup_y, rotation, alpha, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -181,29 +181,28 @@ static void render_view(struct sway_container *view, void *data) {
|
|||
struct wlr_output *wlr_output = output->wlr_output;
|
||||
struct sway_view *sway_view = view->sway_view;
|
||||
struct wlr_surface *surface = sway_view->surface;
|
||||
float alpha = sway_view->swayc->alpha;
|
||||
|
||||
if (!surface) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (sway_view->type) {
|
||||
case SWAY_XDG_SHELL_V6_VIEW: {
|
||||
case SWAY_VIEW_XDG_SHELL_V6: {
|
||||
int window_offset_x = view->sway_view->wlr_xdg_surface_v6->geometry.x;
|
||||
int window_offset_y = view->sway_view->wlr_xdg_surface_v6->geometry.y;
|
||||
render_surface(surface, wlr_output, when,
|
||||
view->x - window_offset_x, view->y - window_offset_y, 0);
|
||||
view->x - window_offset_x, view->y - window_offset_y, 0, alpha);
|
||||
render_xdg_v6_popups(sway_view->wlr_xdg_surface_v6, wlr_output,
|
||||
when, view->x - window_offset_x, view->y - window_offset_y, 0);
|
||||
when, view->x - window_offset_x, view->y - window_offset_y, 0, alpha);
|
||||
break;
|
||||
}
|
||||
case SWAY_WL_SHELL_VIEW:
|
||||
case SWAY_VIEW_WL_SHELL:
|
||||
render_wl_shell_surface(sway_view->wlr_wl_shell_surface, wlr_output,
|
||||
when, view->x, view->y, 0, false);
|
||||
when, view->x, view->y, 0, alpha, false);
|
||||
break;
|
||||
case SWAY_XWAYLAND_VIEW:
|
||||
render_surface(surface, wlr_output, when, view->x, view->y, 0);
|
||||
break;
|
||||
default:
|
||||
case SWAY_VIEW_XWAYLAND:
|
||||
render_surface(surface, wlr_output, when, view->x, view->y, 0, alpha);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -214,7 +213,7 @@ static void render_layer(struct sway_output *output, struct timespec *when,
|
|||
wl_list_for_each(sway_layer, layer, link) {
|
||||
struct wlr_layer_surface *layer = sway_layer->layer_surface;
|
||||
render_surface(layer->surface, output->wlr_output, when,
|
||||
sway_layer->geo.x, sway_layer->geo.y, 0);
|
||||
sway_layer->geo.x, sway_layer->geo.y, 0, 1.0f);
|
||||
wlr_surface_send_frame_done(layer->surface, when);
|
||||
}
|
||||
}
|
||||
|
|
@ -288,7 +287,7 @@ static void render_output(struct sway_output *output, struct timespec *when,
|
|||
}
|
||||
|
||||
render_surface(xsurface->surface, wlr_output, &output->last_frame,
|
||||
view_box.x - output_box->x, view_box.y - output_box->y, 0);
|
||||
view_box.x - output_box->x, view_box.y - output_box->y, 0, 1.0f);
|
||||
}
|
||||
|
||||
// TODO: Consider revising this when fullscreen windows are supported
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include "log.h"
|
||||
|
||||
static bool assert_wl_shell(struct sway_view *view) {
|
||||
return sway_assert(view->type == SWAY_WL_SHELL_VIEW,
|
||||
return sway_assert(view->type == SWAY_VIEW_WL_SHELL,
|
||||
"Expecting wl_shell view!");
|
||||
}
|
||||
|
||||
|
|
@ -97,7 +97,7 @@ void handle_wl_shell_surface(struct wl_listener *listener, void *data) {
|
|||
return;
|
||||
}
|
||||
|
||||
struct sway_view *view = view_create(SWAY_WL_SHELL_VIEW, &view_impl);
|
||||
struct sway_view *view = view_create(SWAY_VIEW_WL_SHELL, &view_impl);
|
||||
if (!sway_assert(view, "Failed to allocate view")) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include "log.h"
|
||||
|
||||
static bool assert_xdg(struct sway_view *view) {
|
||||
return sway_assert(view->type == SWAY_XDG_SHELL_V6_VIEW,
|
||||
return sway_assert(view->type == SWAY_VIEW_XDG_SHELL_V6,
|
||||
"Expected xdg shell v6 view!");
|
||||
}
|
||||
|
||||
|
|
@ -126,7 +126,7 @@ void handle_xdg_shell_v6_surface(struct wl_listener *listener, void *data) {
|
|||
return;
|
||||
}
|
||||
|
||||
struct sway_view *view = view_create(SWAY_XDG_SHELL_V6_VIEW, &view_impl);
|
||||
struct sway_view *view = view_create(SWAY_VIEW_XDG_SHELL_V6, &view_impl);
|
||||
if (!sway_assert(view, "Failed to allocate view")) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ static void create_unmanaged(struct wlr_xwayland_surface *xsurface) {
|
|||
|
||||
|
||||
static bool assert_xwayland(struct sway_view *view) {
|
||||
return sway_assert(view->type == SWAY_XWAYLAND_VIEW,
|
||||
return sway_assert(view->type == SWAY_VIEW_XWAYLAND,
|
||||
"Expected xwayland view!");
|
||||
}
|
||||
|
||||
|
|
@ -185,7 +185,7 @@ void handle_xwayland_surface(struct wl_listener *listener, void *data) {
|
|||
return;
|
||||
}
|
||||
|
||||
struct sway_view *view = view_create(SWAY_XWAYLAND_VIEW, &view_impl);
|
||||
struct sway_view *view = view_create(SWAY_VIEW_XWAYLAND, &view_impl);
|
||||
if (!sway_assert(view, "Failed to allocate view")) {
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,8 +146,10 @@ static void cursor_send_pointer_motion(struct sway_cursor *cursor,
|
|||
|
||||
// send pointer enter/leave
|
||||
if (surface != NULL) {
|
||||
wlr_seat_pointer_notify_enter(seat, surface, sx, sy);
|
||||
wlr_seat_pointer_notify_motion(seat, time, sx, sy);
|
||||
if (seat_is_input_allowed(cursor->seat, surface)) {
|
||||
wlr_seat_pointer_notify_enter(seat, surface, sx, sy);
|
||||
wlr_seat_pointer_notify_motion(seat, time, sx, sy);
|
||||
}
|
||||
} else {
|
||||
wlr_seat_pointer_clear_focus(seat);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <libinput.h>
|
||||
#include <math.h>
|
||||
#include <wlr/backend/libinput.h>
|
||||
#include <wlr/types/wlr_input_inhibitor.h>
|
||||
#include "sway/config.h"
|
||||
#include "sway/input/input-manager.h"
|
||||
#include "sway/input/seat.h"
|
||||
|
|
@ -263,6 +264,32 @@ static void handle_new_input(struct wl_listener *listener, void *data) {
|
|||
input_device->device_destroy.notify = handle_device_destroy;
|
||||
}
|
||||
|
||||
static void handle_inhibit_activate(struct wl_listener *listener, void *data) {
|
||||
struct sway_input_manager *input_manager = wl_container_of(
|
||||
listener, input_manager, inhibit_activate);
|
||||
struct sway_seat *seat;
|
||||
wl_list_for_each(seat, &input_manager->seats, link) {
|
||||
seat_set_exclusive_client(seat, input_manager->inhibit->active_client);
|
||||
}
|
||||
}
|
||||
|
||||
static void handle_inhibit_deactivate(struct wl_listener *listener, void *data) {
|
||||
struct sway_input_manager *input_manager = wl_container_of(
|
||||
listener, input_manager, inhibit_deactivate);
|
||||
struct sway_seat *seat;
|
||||
wl_list_for_each(seat, &input_manager->seats, link) {
|
||||
seat_set_exclusive_client(seat, NULL);
|
||||
struct sway_container *previous = seat_get_focus(seat);
|
||||
if (previous) {
|
||||
wlr_log(L_DEBUG, "Returning focus to %p %s '%s'", previous,
|
||||
container_type_to_str(previous->type), previous->name);
|
||||
// Hack to get seat to re-focus the return value of get_focus
|
||||
seat_set_focus(seat, previous->parent);
|
||||
seat_set_focus(seat, previous);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct sway_input_manager *input_manager_create(
|
||||
struct sway_server *server) {
|
||||
struct sway_input_manager *input =
|
||||
|
|
@ -281,6 +308,14 @@ struct sway_input_manager *input_manager_create(
|
|||
input->new_input.notify = handle_new_input;
|
||||
wl_signal_add(&server->backend->events.new_input, &input->new_input);
|
||||
|
||||
input->inhibit = wlr_input_inhibit_manager_create(server->wl_display);
|
||||
input->inhibit_activate.notify = handle_inhibit_activate;
|
||||
wl_signal_add(&input->inhibit->events.activate,
|
||||
&input->inhibit_activate);
|
||||
input->inhibit_deactivate.notify = handle_inhibit_deactivate;
|
||||
wl_signal_add(&input->inhibit->events.deactivate,
|
||||
&input->inhibit_deactivate);
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#define _XOPEN_SOURCE 700
|
||||
#define _POSIX_C_SOURCE 199309L
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_xcursor_manager.h>
|
||||
|
|
@ -9,6 +11,7 @@
|
|||
#include "sway/input/input-manager.h"
|
||||
#include "sway/input/keyboard.h"
|
||||
#include "sway/ipc-server.h"
|
||||
#include "sway/layers.h"
|
||||
#include "sway/output.h"
|
||||
#include "sway/tree/container.h"
|
||||
#include "sway/tree/view.h"
|
||||
|
|
@ -63,7 +66,7 @@ static void seat_send_focus(struct sway_seat *seat,
|
|||
return;
|
||||
}
|
||||
struct sway_view *view = con->sway_view;
|
||||
if (view->type == SWAY_XWAYLAND_VIEW) {
|
||||
if (view->type == SWAY_VIEW_XWAYLAND) {
|
||||
struct wlr_xwayland *xwayland =
|
||||
seat->input->server->xwayland;
|
||||
wlr_xwayland_set_seat(xwayland, seat->wlr_seat);
|
||||
|
|
@ -350,6 +353,12 @@ void seat_configure_xcursor(struct sway_seat *seat) {
|
|||
seat->cursor->cursor->y);
|
||||
}
|
||||
|
||||
bool seat_is_input_allowed(struct sway_seat *seat,
|
||||
struct wlr_surface *surface) {
|
||||
struct wl_client *client = wl_resource_get_client(surface->resource);
|
||||
return !seat->exclusive_client || seat->exclusive_client == client;
|
||||
}
|
||||
|
||||
void seat_set_focus_warp(struct sway_seat *seat,
|
||||
struct sway_container *container, bool warp) {
|
||||
if (seat->focused_layer) {
|
||||
|
|
@ -371,6 +380,12 @@ void seat_set_focus_warp(struct sway_seat *seat,
|
|||
wl_list_remove(&seat_con->link);
|
||||
wl_list_insert(&seat->focus_stack, &seat_con->link);
|
||||
|
||||
if (container->type == C_VIEW && !seat_is_input_allowed(
|
||||
seat, container->sway_view->surface)) {
|
||||
wlr_log(L_DEBUG, "Refusing to set focus, input is inhibited");
|
||||
return;
|
||||
}
|
||||
|
||||
if (container->type == C_VIEW) {
|
||||
seat_send_focus(seat, container);
|
||||
}
|
||||
|
|
@ -424,11 +439,18 @@ void seat_set_focus(struct sway_seat *seat,
|
|||
|
||||
void seat_set_focus_layer(struct sway_seat *seat,
|
||||
struct wlr_layer_surface *layer) {
|
||||
if (!layer) {
|
||||
if (!layer && seat->focused_layer) {
|
||||
seat->focused_layer = NULL;
|
||||
struct sway_container *previous = seat_get_focus(seat);
|
||||
if (previous) {
|
||||
wlr_log(L_DEBUG, "Returning focus to %p %s '%s'", previous,
|
||||
container_type_to_str(previous->type), previous->name);
|
||||
// Hack to get seat to re-focus the return value of get_focus
|
||||
seat_set_focus(seat, previous->parent);
|
||||
seat_set_focus(seat, previous);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (seat->focused_layer == layer) {
|
||||
} else if (!layer || seat->focused_layer == layer) {
|
||||
return;
|
||||
}
|
||||
if (seat->has_focus) {
|
||||
|
|
@ -453,6 +475,51 @@ void seat_set_focus_layer(struct sway_seat *seat,
|
|||
}
|
||||
}
|
||||
|
||||
void seat_set_exclusive_client(struct sway_seat *seat,
|
||||
struct wl_client *client) {
|
||||
if (!client) {
|
||||
seat->exclusive_client = client;
|
||||
// Triggers a refocus of the topmost surface layer if necessary
|
||||
// TODO: Make layer surface focus per-output based on cursor position
|
||||
for (int i = 0; i < root_container.children->length; ++i) {
|
||||
struct sway_container *output = root_container.children->items[i];
|
||||
if (!sway_assert(output->type == C_OUTPUT,
|
||||
"root container has non-output child")) {
|
||||
continue;
|
||||
}
|
||||
arrange_layers(output->sway_output);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (seat->focused_layer) {
|
||||
if (wl_resource_get_client(seat->focused_layer->resource) != client) {
|
||||
seat_set_focus_layer(seat, NULL);
|
||||
}
|
||||
}
|
||||
if (seat->has_focus) {
|
||||
struct sway_container *focus = seat_get_focus(seat);
|
||||
if (focus->type == C_VIEW && wl_resource_get_client(
|
||||
focus->sway_view->surface->resource) != client) {
|
||||
seat_set_focus(seat, NULL);
|
||||
}
|
||||
}
|
||||
if (seat->wlr_seat->pointer_state.focused_client) {
|
||||
if (seat->wlr_seat->pointer_state.focused_client->client != client) {
|
||||
wlr_seat_pointer_clear_focus(seat->wlr_seat);
|
||||
}
|
||||
}
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
struct wlr_touch_point *point;
|
||||
wl_list_for_each(point, &seat->wlr_seat->touch_state.touch_points, link) {
|
||||
if (point->client->client != client) {
|
||||
wlr_seat_touch_point_clear_focus(seat->wlr_seat,
|
||||
now.tv_nsec / 1000, point->touch_id);
|
||||
}
|
||||
}
|
||||
seat->exclusive_client = client;
|
||||
}
|
||||
|
||||
struct sway_container *seat_get_focus_inactive(struct sway_seat *seat,
|
||||
struct sway_container *container) {
|
||||
return seat_get_focus_by_type(seat, container, C_TYPES);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ sway_sources = files(
|
|||
'commands/focus.c',
|
||||
'commands/focus_follows_mouse.c',
|
||||
'commands/kill.c',
|
||||
'commands/opacity.c',
|
||||
'commands/include.c',
|
||||
'commands/input.c',
|
||||
'commands/layout.c',
|
||||
|
|
|
|||
|
|
@ -413,6 +413,10 @@ The default colors are:
|
|||
However, any mark that starts with an underscore will not be drawn even if the
|
||||
option is on. The default option is _on_.
|
||||
|
||||
**opacity** <value>::
|
||||
Set the opacity of the window between 0 (completely transparent) and 1
|
||||
(completely opaque).
|
||||
|
||||
**unmark** <identifier>::
|
||||
**Unmark** will remove _identifier_ from the list of current marks on a window. If
|
||||
no _identifier_ is specified, then **unmark** will remove all marks.
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ struct sway_container *container_create(enum sway_container_type type) {
|
|||
c->layout = L_NONE;
|
||||
c->workspace_layout = L_NONE;
|
||||
c->type = type;
|
||||
c->alpha = 1.0f;
|
||||
|
||||
if (type != C_VIEW) {
|
||||
c->children = create_list();
|
||||
}
|
||||
|
|
@ -416,51 +418,33 @@ struct sway_container *container_at(struct sway_container *parent,
|
|||
double view_sx = ox - swayc->x;
|
||||
double view_sy = oy - swayc->y;
|
||||
|
||||
double _sx, _sy;
|
||||
struct wlr_surface *_surface;
|
||||
switch (sview->type) {
|
||||
case SWAY_WL_SHELL_VIEW:
|
||||
break;
|
||||
case SWAY_XDG_SHELL_V6_VIEW:
|
||||
// the top left corner of the sway container is the
|
||||
// coordinate of the top left corner of the window geometry
|
||||
view_sx += sview->wlr_xdg_surface_v6->geometry.x;
|
||||
view_sy += sview->wlr_xdg_surface_v6->geometry.y;
|
||||
case SWAY_VIEW_XWAYLAND:
|
||||
_surface = wlr_surface_surface_at(sview->surface,
|
||||
view_sx, view_sy, &_sx, &_sy);
|
||||
break;
|
||||
case SWAY_VIEW_WL_SHELL:
|
||||
_surface = wlr_wl_shell_surface_surface_at(
|
||||
sview->wlr_wl_shell_surface,
|
||||
view_sx, view_sy, &_sx, &_sy);
|
||||
break;
|
||||
case SWAY_VIEW_XDG_SHELL_V6:
|
||||
// the top left corner of the sway container is the
|
||||
// coordinate of the top left corner of the window geometry
|
||||
view_sx += sview->wlr_xdg_surface_v6->geometry.x;
|
||||
view_sy += sview->wlr_xdg_surface_v6->geometry.y;
|
||||
|
||||
// check for popups
|
||||
double popup_sx, popup_sy;
|
||||
struct wlr_xdg_surface_v6 *popup =
|
||||
wlr_xdg_surface_v6_popup_at(sview->wlr_xdg_surface_v6,
|
||||
view_sx, view_sy, &popup_sx, &popup_sy);
|
||||
|
||||
if (popup) {
|
||||
*sx = view_sx - popup_sx;
|
||||
*sy = view_sy - popup_sy;
|
||||
*surface = popup->surface;
|
||||
return swayc;
|
||||
}
|
||||
break;
|
||||
case SWAY_XWAYLAND_VIEW:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
_surface = wlr_xdg_surface_v6_surface_at(
|
||||
sview->wlr_xdg_surface_v6,
|
||||
view_sx, view_sy, &_sx, &_sy);
|
||||
break;
|
||||
}
|
||||
|
||||
// check for subsurfaces
|
||||
double sub_x, sub_y;
|
||||
struct wlr_subsurface *subsurface =
|
||||
wlr_surface_subsurface_at(sview->surface,
|
||||
view_sx, view_sy, &sub_x, &sub_y);
|
||||
if (subsurface) {
|
||||
*sx = view_sx - sub_x;
|
||||
*sy = view_sy - sub_y;
|
||||
*surface = subsurface->surface;
|
||||
return swayc;
|
||||
}
|
||||
|
||||
if (wlr_surface_point_accepts_input(
|
||||
sview->surface, view_sx, view_sy)) {
|
||||
*sx = view_sx;
|
||||
*sy = view_sy;
|
||||
*surface = swayc->sway_view->surface;
|
||||
if (_surface) {
|
||||
*sx = _sx;
|
||||
*sy = _sy;
|
||||
*surface = _surface;
|
||||
return swayc;
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue