desktop: add means of grabbing the surface at (x,y)

This commit is contained in:
Jente Hidskes 2020-07-06 22:47:46 +02:00
parent a7c44caeb6
commit d683e2904f
No known key found for this signature in database
GPG key ID: 04BE5A29F32D91EA
5 changed files with 56 additions and 0 deletions

View file

@ -31,6 +31,28 @@
#include "util.h" #include "util.h"
#include "view.h" #include "view.h"
void
cage_output_surface_at(struct cg_output *output, double lx, double ly, struct wlr_surface **surface, double *sx,
double *sy)
{
struct cg_view *view;
wl_list_for_each (view, &output->views, link) {
// TODO: this only works because all views are currently maximized on a single output.
// When multi-monitor setups and dialogs are added, this will need extending.
double view_sx = lx;
double view_sy = ly;
double _sx, _sy;
struct wlr_surface *_surface = cage_view_wlr_surface_at(view, view_sx, view_sy, &_sx, &_sy);
if (_surface != NULL) {
*sx = _sx;
*sy = _sy;
*surface = _surface;
break;
}
}
}
void void
cage_output_damage_whole(struct cg_output *output) cage_output_damage_whole(struct cg_output *output)
{ {

View file

@ -25,6 +25,11 @@ struct cg_output {
struct wl_list link; // cg_server::outputs struct wl_list link; // cg_server::outputs
}; };
/**
* Iterates over all the views on an output and attempts to find the surface under the cursor.
*/
void cage_output_surface_at(struct cg_output *output, double lx, double ly, struct wlr_surface **surface, double *sx,
double *sy);
void cage_output_damage_whole(struct cg_output *output); void cage_output_damage_whole(struct cg_output *output);
void cage_output_damage_region(struct cg_output *output, struct wlr_box *region); void cage_output_damage_region(struct cg_output *output, struct wlr_box *region);
void cage_output_damage_surface(struct cg_output *output, struct wlr_surface *surface, int sx, int sy); void cage_output_damage_surface(struct cg_output *output, struct wlr_surface *surface, int sx, int sy);

View file

@ -112,6 +112,17 @@ cage_view_damage_part(struct cg_view *view)
cage_view_for_each_surface(view, damage_surface_iterator, NULL); cage_view_for_each_surface(view, damage_surface_iterator, NULL);
} }
struct wlr_surface *
cage_view_wlr_surface_at(struct cg_view *view, double sx, double sy, double *sub_x, double *sub_y)
{
assert(view != NULL);
assert(sub_x != NULL);
assert(sub_y != NULL);
assert(view->impl->wlr_surface_at != NULL);
return view->impl->wlr_surface_at(view, sx, sy, sub_x, sub_y);
}
void void
cage_view_activate(struct cg_view *view, bool activate) cage_view_activate(struct cg_view *view, bool activate)
{ {

View file

@ -74,6 +74,15 @@ struct cg_view_impl {
* Activate a view. * Activate a view.
*/ */
void (*activate)(struct cg_view *view, bool activate); void (*activate)(struct cg_view *view, bool activate);
/**
* XDG toplevels may have nested surfaces, such as popup windows
* for context menus or tooltips. This tests if any of those are
* underneath the coordinates lx and ly (in output Layout Coordinates).
* If so, it sets the surface pointer to that wlr_surface and the
* sx and sy coordinates to the coordinates relative to that
* surface's top-left corner. */
struct wlr_surface *(*wlr_surface_at)(struct cg_view *view, double sx, double sy, double *sub_x, double *sub_y);
}; };
bool cage_view_is_primary(struct cg_view *view); bool cage_view_is_primary(struct cg_view *view);
@ -82,6 +91,7 @@ void cage_view_for_each_surface(struct cg_view *view, wlr_surface_iterator_func_
char *cage_view_get_title(struct cg_view *view); char *cage_view_get_title(struct cg_view *view);
void cage_view_damage_whole(struct cg_view *view); void cage_view_damage_whole(struct cg_view *view);
void cage_view_damage_part(struct cg_view *view); void cage_view_damage_part(struct cg_view *view);
struct wlr_surface *cage_view_wlr_surface_at(struct cg_view *view, double sx, double sy, double *sub_x, double *sub_y);
void cage_view_activate(struct cg_view *view, bool activate); void cage_view_activate(struct cg_view *view, bool activate);
bool cage_view_is_mapped(struct cg_view *view); bool cage_view_is_mapped(struct cg_view *view);
void cage_view_unmap(struct cg_view *view); void cage_view_unmap(struct cg_view *view);

View file

@ -66,6 +66,13 @@ get_title(struct cg_view *view)
return xdg_shell_view->xdg_surface->toplevel->title; return xdg_shell_view->xdg_surface->toplevel->title;
} }
static struct wlr_surface *
wlr_surface_at(struct cg_view *view, double sx, double sy, double *sub_x, double *sub_y)
{
struct cg_xdg_shell_view *xdg_shell_view = xdg_shell_view_from_view(view);
return wlr_xdg_surface_surface_at(xdg_shell_view->xdg_surface, sx, sy, sub_x, sub_y);
}
static void static void
activate(struct cg_view *view, bool activate) activate(struct cg_view *view, bool activate)
{ {
@ -153,6 +160,7 @@ static const struct cg_view_impl xdg_shell_view_impl = {
.is_primary = is_primary, .is_primary = is_primary,
.get_title = get_title, .get_title = get_title,
.activate = activate, .activate = activate,
.wlr_surface_at = wlr_surface_at,
}; };
void void