REFACTOR "STASH" (nowhere near working btw)
This commit is contained in:
parent
8dfe3b2f25
commit
ab3942d3b5
25 changed files with 1021 additions and 845 deletions
|
|
@ -1,4 +1,4 @@
|
|||
#include "lib/client.h"
|
||||
#include "client.h"
|
||||
|
||||
void applybounds(Client *c, struct wlr_box *bbox) {
|
||||
/* set minimum possible */
|
||||
|
|
@ -15,34 +15,6 @@ void applybounds(Client *c, struct wlr_box *bbox) {
|
|||
c->geom.y = bbox->y;
|
||||
}
|
||||
|
||||
void applyrules(Client *c) {
|
||||
/* rule matching */
|
||||
const char *appid, *title;
|
||||
uint32_t newtags = 0;
|
||||
int i;
|
||||
const Rule *r;
|
||||
Monitor *mon = selmon, *m;
|
||||
|
||||
appid = client_get_appid(c);
|
||||
title = client_get_title(c);
|
||||
|
||||
for (r = rules; r < END(rules); r++) {
|
||||
if ((!r->title || strstr(title, r->title)) &&
|
||||
(!r->id || strstr(appid, r->id))) {
|
||||
c->isfloating = r->isfloating;
|
||||
newtags |= r->tags;
|
||||
i = 0;
|
||||
wl_list_for_each(m, &mons, link) {
|
||||
if (r->monitor == i++)
|
||||
mon = m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c->isfloating |= client_is_float_type(c);
|
||||
setmon(c, mon, newtags);
|
||||
}
|
||||
|
||||
void focusclient(Client *c, int lift) {
|
||||
struct wlr_surface *old = seat->keyboard_state.focused_surface;
|
||||
int unused_lx, unused_ly, old_client_type;
|
||||
|
|
@ -278,39 +250,6 @@ void view(const Arg *arg) {
|
|||
printstatus();
|
||||
}
|
||||
|
||||
void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc,
|
||||
LayerSurface **pl, double *nx, double *ny) {
|
||||
struct wlr_scene_node *node, *pnode;
|
||||
struct wlr_surface *surface = NULL;
|
||||
Client *c = NULL;
|
||||
LayerSurface *l = NULL;
|
||||
int layer;
|
||||
|
||||
for (layer = NUM_LAYERS - 1; !surface && layer >= 0; layer--) {
|
||||
if (!(node = wlr_scene_node_at(&layers[layer]->node, x, y, nx, ny)))
|
||||
continue;
|
||||
|
||||
if (node->type == WLR_SCENE_NODE_BUFFER)
|
||||
surface =
|
||||
wlr_scene_surface_try_from_buffer(wlr_scene_buffer_from_node(node))
|
||||
->surface;
|
||||
/* Walk the tree to find a node that knows the client */
|
||||
for (pnode = node; pnode && !c; pnode = &pnode->parent->node)
|
||||
c = pnode->data;
|
||||
if (c && c->type == LayerShell) {
|
||||
c = NULL;
|
||||
l = pnode->data;
|
||||
}
|
||||
}
|
||||
|
||||
if (psurface)
|
||||
*psurface = surface;
|
||||
if (pc)
|
||||
*pc = c;
|
||||
if (pl)
|
||||
*pl = l;
|
||||
}
|
||||
|
||||
void zoom(const Arg *arg) {
|
||||
Client *c, *sel = focustop(selmon);
|
||||
|
||||
|
|
|
|||
406
src/lib/client.h
406
src/lib/client.h
|
|
@ -7,6 +7,9 @@
|
|||
#ifndef CRYWL_CLIENT_H
|
||||
#define CRYWL_CLIENT_H
|
||||
|
||||
#include "../wayland.h"
|
||||
#include "../util.h"
|
||||
|
||||
enum { XDGShell, LayerShell, X11 }; /* client types */
|
||||
|
||||
typedef struct Monitor Monitor; // forward declare
|
||||
|
|
@ -52,392 +55,21 @@ typedef struct {
|
|||
} Client;
|
||||
|
||||
/* ===== Function Declarations ===== */
|
||||
static void applybounds(Client *c, struct wlr_box *bbox);
|
||||
static void applyrules(Client *c);
|
||||
static void focusclient(Client *c, int lift);
|
||||
static void killclient(const Arg *arg);
|
||||
static void resize(Client *c, struct wlr_box geo, int interact);
|
||||
static void setfloating(Client *c, int floating);
|
||||
static void setfullscreen(Client *c, int fullscreen);
|
||||
static void setpsel(struct wl_listener *listener, void *data);
|
||||
static void setsel(struct wl_listener *listener, void *data);
|
||||
static void togglefloating(const Arg *arg);
|
||||
static void togglefullscreen(const Arg *arg);
|
||||
static void toggletag(const Arg *arg);
|
||||
static void toggleview(const Arg *arg);
|
||||
static void updatetitle(struct wl_listener *listener, void *data);
|
||||
static void urgent(struct wl_listener *listener, void *data);
|
||||
static void view(const Arg *arg);
|
||||
static void xytonode(double x, double y, struct wlr_surface **psurface,
|
||||
Client **pc, LayerSurface **pl, double *nx, double *ny);
|
||||
static void zoom(const Arg *arg);
|
||||
|
||||
/* Leave these functions first; they're used in the others */
|
||||
static inline int client_is_x11(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
return c->type == X11;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct wlr_surface *client_surface(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return c->surface.xwayland->surface;
|
||||
#endif
|
||||
return c->surface.xdg->surface;
|
||||
}
|
||||
|
||||
static inline int toplevel_from_wlr_surface(struct wlr_surface *s, Client **pc,
|
||||
LayerSurface **pl) {
|
||||
struct wlr_xdg_surface *xdg_surface, *tmp_xdg_surface;
|
||||
struct wlr_surface *root_surface;
|
||||
struct wlr_layer_surface_v1 *layer_surface;
|
||||
Client *c = NULL;
|
||||
LayerSurface *l = NULL;
|
||||
int type = -1;
|
||||
#ifdef XWAYLAND
|
||||
struct wlr_xwayland_surface *xsurface;
|
||||
#endif
|
||||
|
||||
if (!s)
|
||||
return -1;
|
||||
root_surface = wlr_surface_get_root_surface(s);
|
||||
|
||||
#ifdef XWAYLAND
|
||||
if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(root_surface))) {
|
||||
c = xsurface->data;
|
||||
type = c->type;
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((layer_surface =
|
||||
wlr_layer_surface_v1_try_from_wlr_surface(root_surface))) {
|
||||
l = layer_surface->data;
|
||||
type = LayerShell;
|
||||
goto end;
|
||||
}
|
||||
|
||||
xdg_surface = wlr_xdg_surface_try_from_wlr_surface(root_surface);
|
||||
while (xdg_surface) {
|
||||
tmp_xdg_surface = NULL;
|
||||
switch (xdg_surface->role) {
|
||||
case WLR_XDG_SURFACE_ROLE_POPUP:
|
||||
if (!xdg_surface->popup || !xdg_surface->popup->parent)
|
||||
return -1;
|
||||
|
||||
tmp_xdg_surface =
|
||||
wlr_xdg_surface_try_from_wlr_surface(xdg_surface->popup->parent);
|
||||
|
||||
if (!tmp_xdg_surface)
|
||||
return toplevel_from_wlr_surface(xdg_surface->popup->parent, pc, pl);
|
||||
|
||||
xdg_surface = tmp_xdg_surface;
|
||||
break;
|
||||
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
|
||||
c = xdg_surface->data;
|
||||
type = c->type;
|
||||
goto end;
|
||||
case WLR_XDG_SURFACE_ROLE_NONE:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (pl)
|
||||
*pl = l;
|
||||
if (pc)
|
||||
*pc = c;
|
||||
return type;
|
||||
}
|
||||
|
||||
/* The others */
|
||||
static inline void client_activate_surface(struct wlr_surface *s,
|
||||
int activated) {
|
||||
struct wlr_xdg_toplevel *toplevel;
|
||||
#ifdef XWAYLAND
|
||||
struct wlr_xwayland_surface *xsurface;
|
||||
if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(s))) {
|
||||
wlr_xwayland_surface_activate(xsurface, activated);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if ((toplevel = wlr_xdg_toplevel_try_from_wlr_surface(s)))
|
||||
wlr_xdg_toplevel_set_activated(toplevel, activated);
|
||||
}
|
||||
|
||||
static inline uint32_t client_set_bounds(Client *c, int32_t width,
|
||||
int32_t height) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return 0;
|
||||
#endif
|
||||
if (wl_resource_get_version(c->surface.xdg->toplevel->resource) >=
|
||||
XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION &&
|
||||
width >= 0 && height >= 0 &&
|
||||
(c->bounds.width != width || c->bounds.height != height)) {
|
||||
c->bounds.width = width;
|
||||
c->bounds.height = height;
|
||||
return wlr_xdg_toplevel_set_bounds(c->surface.xdg->toplevel, width, height);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline const char *client_get_appid(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return c->surface.xwayland->class ? c->surface.xwayland->class : "broken";
|
||||
#endif
|
||||
return c->surface.xdg->toplevel->app_id ? c->surface.xdg->toplevel->app_id
|
||||
: "broken";
|
||||
}
|
||||
|
||||
static inline void client_get_clip(Client *c, struct wlr_box *clip) {
|
||||
*clip = (struct wlr_box){
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = c->geom.width - c->bw,
|
||||
.height = c->geom.height - c->bw,
|
||||
};
|
||||
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return;
|
||||
#endif
|
||||
|
||||
clip->x = c->surface.xdg->geometry.x;
|
||||
clip->y = c->surface.xdg->geometry.y;
|
||||
}
|
||||
|
||||
static inline void client_get_geometry(Client *c, struct wlr_box *geom) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c)) {
|
||||
geom->x = c->surface.xwayland->x;
|
||||
geom->y = c->surface.xwayland->y;
|
||||
geom->width = c->surface.xwayland->width;
|
||||
geom->height = c->surface.xwayland->height;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
*geom = c->surface.xdg->geometry;
|
||||
}
|
||||
|
||||
static inline Client *client_get_parent(Client *c) {
|
||||
Client *p = NULL;
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c)) {
|
||||
if (c->surface.xwayland->parent)
|
||||
toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL);
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
if (c->surface.xdg->toplevel->parent)
|
||||
toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface,
|
||||
&p, NULL);
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline int client_has_children(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return !wl_list_empty(&c->surface.xwayland->children);
|
||||
#endif
|
||||
/* surface.xdg->link is never empty because it always contains at least the
|
||||
* surface itself. */
|
||||
return wl_list_length(&c->surface.xdg->link) > 1;
|
||||
}
|
||||
|
||||
static inline const char *client_get_title(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return c->surface.xwayland->title ? c->surface.xwayland->title : "broken";
|
||||
#endif
|
||||
return c->surface.xdg->toplevel->title ? c->surface.xdg->toplevel->title
|
||||
: "broken";
|
||||
}
|
||||
|
||||
static inline int client_is_float_type(Client *c) {
|
||||
struct wlr_xdg_toplevel *toplevel;
|
||||
struct wlr_xdg_toplevel_state state;
|
||||
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c)) {
|
||||
struct wlr_xwayland_surface *surface = c->surface.xwayland;
|
||||
xcb_size_hints_t *size_hints = surface->size_hints;
|
||||
if (surface->modal)
|
||||
return 1;
|
||||
|
||||
if (wlr_xwayland_surface_has_window_type(
|
||||
surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_DIALOG) ||
|
||||
wlr_xwayland_surface_has_window_type(
|
||||
surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_SPLASH) ||
|
||||
wlr_xwayland_surface_has_window_type(
|
||||
surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_TOOLBAR) ||
|
||||
wlr_xwayland_surface_has_window_type(
|
||||
surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_UTILITY)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return size_hints && size_hints->min_width > 0 &&
|
||||
size_hints->min_height > 0 &&
|
||||
(size_hints->max_width == size_hints->min_width ||
|
||||
size_hints->max_height == size_hints->min_height);
|
||||
}
|
||||
#endif
|
||||
|
||||
toplevel = c->surface.xdg->toplevel;
|
||||
state = toplevel->current;
|
||||
return toplevel->parent || (state.min_width != 0 && state.min_height != 0 &&
|
||||
(state.min_width == state.max_width ||
|
||||
state.min_height == state.max_height));
|
||||
}
|
||||
|
||||
static inline int client_is_rendered_on_mon(Client *c, Monitor *m) {
|
||||
/* This is needed for when you don't want to check formal assignment,
|
||||
* but rather actual displaying of the pixels.
|
||||
* Usually VISIBLEON suffices and is also faster. */
|
||||
struct wlr_surface_output *s;
|
||||
int unused_lx, unused_ly;
|
||||
if (!wlr_scene_node_coords(&c->scene->node, &unused_lx, &unused_ly))
|
||||
return 0;
|
||||
wl_list_for_each(s, &client_surface(c)->current_outputs,
|
||||
link) if (s->output == m->wlr_output) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int client_is_stopped(Client *c) {
|
||||
int pid;
|
||||
siginfo_t in = {0};
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
wl_client_get_credentials(c->surface.xdg->client->client, &pid, NULL, NULL);
|
||||
if (waitid(P_PID, pid, &in, WNOHANG | WCONTINUED | WSTOPPED | WNOWAIT) < 0) {
|
||||
/* This process is not our child process, while is very unlikely that
|
||||
* it is stopped, in order to do not skip frames, assume that it is. */
|
||||
if (errno == ECHILD)
|
||||
return 1;
|
||||
} else if (in.si_pid) {
|
||||
if (in.si_code == CLD_STOPPED || in.si_code == CLD_TRAPPED)
|
||||
return 1;
|
||||
if (in.si_code == CLD_CONTINUED)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int client_is_unmanaged(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return c->surface.xwayland->override_redirect;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void client_notify_enter(struct wlr_surface *s,
|
||||
struct wlr_keyboard *kb) {
|
||||
if (kb)
|
||||
wlr_seat_keyboard_notify_enter(seat, s, kb->keycodes, kb->num_keycodes,
|
||||
&kb->modifiers);
|
||||
else
|
||||
wlr_seat_keyboard_notify_enter(seat, s, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static inline void client_send_close(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c)) {
|
||||
wlr_xwayland_surface_close(c->surface.xwayland);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
wlr_xdg_toplevel_send_close(c->surface.xdg->toplevel);
|
||||
}
|
||||
|
||||
static inline void client_set_border_color(Client *c,
|
||||
const float color[static 4]) {
|
||||
int i;
|
||||
for (i = 0; i < 4; i++)
|
||||
wlr_scene_rect_set_color(c->border[i], color);
|
||||
}
|
||||
|
||||
static inline void client_set_fullscreen(Client *c, int fullscreen) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c)) {
|
||||
wlr_xwayland_surface_set_fullscreen(c->surface.xwayland, fullscreen);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
wlr_xdg_toplevel_set_fullscreen(c->surface.xdg->toplevel, fullscreen);
|
||||
}
|
||||
|
||||
static inline void client_set_scale(struct wlr_surface *s, float scale) {
|
||||
wlr_fractional_scale_v1_notify_scale(s, scale);
|
||||
wlr_surface_set_preferred_buffer_scale(s, (int32_t)ceilf(scale));
|
||||
}
|
||||
|
||||
static inline uint32_t client_set_size(Client *c, uint32_t width,
|
||||
uint32_t height) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c)) {
|
||||
wlr_xwayland_surface_configure(c->surface.xwayland, c->geom.x + c->bw,
|
||||
c->geom.y + c->bw, width, height);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if ((int32_t)width == c->surface.xdg->toplevel->current.width &&
|
||||
(int32_t)height == c->surface.xdg->toplevel->current.height)
|
||||
return 0;
|
||||
return wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, (int32_t)width,
|
||||
(int32_t)height);
|
||||
}
|
||||
|
||||
static inline void client_set_tiled(Client *c, uint32_t edges) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c)) {
|
||||
wlr_xwayland_surface_set_maximized(
|
||||
c->surface.xwayland, edges != WLR_EDGE_NONE, edges != WLR_EDGE_NONE);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (wl_resource_get_version(c->surface.xdg->toplevel->resource) >=
|
||||
XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) {
|
||||
wlr_xdg_toplevel_set_tiled(c->surface.xdg->toplevel, edges);
|
||||
} else {
|
||||
wlr_xdg_toplevel_set_maximized(c->surface.xdg->toplevel,
|
||||
edges != WLR_EDGE_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void client_set_suspended(Client *c, int suspended) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return;
|
||||
#endif
|
||||
|
||||
wlr_xdg_toplevel_set_suspended(c->surface.xdg->toplevel, suspended);
|
||||
}
|
||||
|
||||
static inline int client_wants_focus(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
return client_is_unmanaged(c) &&
|
||||
wlr_xwayland_surface_override_redirect_wants_focus(
|
||||
c->surface.xwayland) &&
|
||||
wlr_xwayland_surface_icccm_input_model(c->surface.xwayland) !=
|
||||
WLR_ICCCM_INPUT_MODEL_NONE;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int client_wants_fullscreen(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return c->surface.xwayland->fullscreen;
|
||||
#endif
|
||||
return c->surface.xdg->toplevel->requested.fullscreen;
|
||||
}
|
||||
void applybounds(Client *c, struct wlr_box *bbox);
|
||||
void focusclient(Client *c, int lift);
|
||||
void killclient(const Arg *arg);
|
||||
void resize(Client *c, struct wlr_box geo, int interact);
|
||||
void setfloating(Client *c, int floating);
|
||||
void setfullscreen(Client *c, int fullscreen);
|
||||
void setpsel(struct wl_listener *listener, void *data);
|
||||
void setsel(struct wl_listener *listener, void *data);
|
||||
void togglefloating(const Arg *arg);
|
||||
void togglefullscreen(const Arg *arg);
|
||||
void toggletag(const Arg *arg);
|
||||
void toggleview(const Arg *arg);
|
||||
void updatetitle(struct wl_listener *listener, void *data);
|
||||
void urgent(struct wl_listener *listener, void *data);
|
||||
void view(const Arg *arg);
|
||||
void zoom(const Arg *arg);
|
||||
|
||||
#endif /* CRYWL_CLIENT_H */
|
||||
|
|
|
|||
376
src/lib/clientutil.h
Normal file
376
src/lib/clientutil.h
Normal file
|
|
@ -0,0 +1,376 @@
|
|||
#ifndef CRYWL_CLIENTUTIL_H
|
||||
#define CRYWL_CLIENTUTIL_H
|
||||
|
||||
#include "sys/wait.h"
|
||||
|
||||
#include "layers.h"
|
||||
|
||||
/* Leave these functions first; they're used in the others */
|
||||
static inline int client_is_x11(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
return c->type == X11;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline struct wlr_surface *client_surface(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return c->surface.xwayland->surface;
|
||||
#endif
|
||||
return c->surface.xdg->surface;
|
||||
}
|
||||
|
||||
static inline int toplevel_from_wlr_surface(struct wlr_surface *s, Client **pc,
|
||||
LayerSurface **pl) {
|
||||
struct wlr_xdg_surface *xdg_surface, *tmp_xdg_surface;
|
||||
struct wlr_surface *root_surface;
|
||||
struct wlr_layer_surface_v1 *layer_surface;
|
||||
Client *c = NULL;
|
||||
LayerSurface *l = NULL;
|
||||
int type = -1;
|
||||
#ifdef XWAYLAND
|
||||
struct wlr_xwayland_surface *xsurface;
|
||||
#endif
|
||||
|
||||
if (!s)
|
||||
return -1;
|
||||
root_surface = wlr_surface_get_root_surface(s);
|
||||
|
||||
#ifdef XWAYLAND
|
||||
if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(root_surface))) {
|
||||
c = xsurface->data;
|
||||
type = c->type;
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
|
||||
if ((layer_surface =
|
||||
wlr_layer_surface_v1_try_from_wlr_surface(root_surface))) {
|
||||
l = layer_surface->data;
|
||||
type = LayerShell;
|
||||
goto end;
|
||||
}
|
||||
|
||||
xdg_surface = wlr_xdg_surface_try_from_wlr_surface(root_surface);
|
||||
while (xdg_surface) {
|
||||
tmp_xdg_surface = NULL;
|
||||
switch (xdg_surface->role) {
|
||||
case WLR_XDG_SURFACE_ROLE_POPUP:
|
||||
if (!xdg_surface->popup || !xdg_surface->popup->parent)
|
||||
return -1;
|
||||
|
||||
tmp_xdg_surface =
|
||||
wlr_xdg_surface_try_from_wlr_surface(xdg_surface->popup->parent);
|
||||
|
||||
if (!tmp_xdg_surface)
|
||||
return toplevel_from_wlr_surface(xdg_surface->popup->parent, pc, pl);
|
||||
|
||||
xdg_surface = tmp_xdg_surface;
|
||||
break;
|
||||
case WLR_XDG_SURFACE_ROLE_TOPLEVEL:
|
||||
c = xdg_surface->data;
|
||||
type = c->type;
|
||||
goto end;
|
||||
case WLR_XDG_SURFACE_ROLE_NONE:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
if (pl)
|
||||
*pl = l;
|
||||
if (pc)
|
||||
*pc = c;
|
||||
return type;
|
||||
}
|
||||
|
||||
/* The others */
|
||||
static inline void client_activate_surface(struct wlr_surface *s,
|
||||
int activated) {
|
||||
struct wlr_xdg_toplevel *toplevel;
|
||||
#ifdef XWAYLAND
|
||||
struct wlr_xwayland_surface *xsurface;
|
||||
if ((xsurface = wlr_xwayland_surface_try_from_wlr_surface(s))) {
|
||||
wlr_xwayland_surface_activate(xsurface, activated);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if ((toplevel = wlr_xdg_toplevel_try_from_wlr_surface(s)))
|
||||
wlr_xdg_toplevel_set_activated(toplevel, activated);
|
||||
}
|
||||
|
||||
static inline uint32_t client_set_bounds(Client *c, int32_t width,
|
||||
int32_t height) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return 0;
|
||||
#endif
|
||||
if (wl_resource_get_version(c->surface.xdg->toplevel->resource) >=
|
||||
XDG_TOPLEVEL_CONFIGURE_BOUNDS_SINCE_VERSION &&
|
||||
width >= 0 && height >= 0 &&
|
||||
(c->bounds.width != width || c->bounds.height != height)) {
|
||||
c->bounds.width = width;
|
||||
c->bounds.height = height;
|
||||
return wlr_xdg_toplevel_set_bounds(c->surface.xdg->toplevel, width, height);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline const char *client_get_appid(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return c->surface.xwayland->class ? c->surface.xwayland->class : "broken";
|
||||
#endif
|
||||
return c->surface.xdg->toplevel->app_id ? c->surface.xdg->toplevel->app_id
|
||||
: "broken";
|
||||
}
|
||||
|
||||
static inline void client_get_clip(Client *c, struct wlr_box *clip) {
|
||||
*clip = (struct wlr_box){
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = c->geom.width - c->bw,
|
||||
.height = c->geom.height - c->bw,
|
||||
};
|
||||
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return;
|
||||
#endif
|
||||
|
||||
clip->x = c->surface.xdg->geometry.x;
|
||||
clip->y = c->surface.xdg->geometry.y;
|
||||
}
|
||||
|
||||
static inline void client_get_geometry(Client *c, struct wlr_box *geom) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c)) {
|
||||
geom->x = c->surface.xwayland->x;
|
||||
geom->y = c->surface.xwayland->y;
|
||||
geom->width = c->surface.xwayland->width;
|
||||
geom->height = c->surface.xwayland->height;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
*geom = c->surface.xdg->geometry;
|
||||
}
|
||||
|
||||
static inline Client *client_get_parent(Client *c) {
|
||||
Client *p = NULL;
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c)) {
|
||||
if (c->surface.xwayland->parent)
|
||||
toplevel_from_wlr_surface(c->surface.xwayland->parent->surface, &p, NULL);
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
if (c->surface.xdg->toplevel->parent)
|
||||
toplevel_from_wlr_surface(c->surface.xdg->toplevel->parent->base->surface,
|
||||
&p, NULL);
|
||||
return p;
|
||||
}
|
||||
|
||||
static inline int client_has_children(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return !wl_list_empty(&c->surface.xwayland->children);
|
||||
#endif
|
||||
/* surface.xdg->link is never empty because it always contains at least the
|
||||
* surface itself. */
|
||||
return wl_list_length(&c->surface.xdg->link) > 1;
|
||||
}
|
||||
|
||||
static inline const char *client_get_title(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return c->surface.xwayland->title ? c->surface.xwayland->title : "broken";
|
||||
#endif
|
||||
return c->surface.xdg->toplevel->title ? c->surface.xdg->toplevel->title
|
||||
: "broken";
|
||||
}
|
||||
|
||||
static inline int client_is_float_type(Client *c) {
|
||||
struct wlr_xdg_toplevel *toplevel;
|
||||
struct wlr_xdg_toplevel_state state;
|
||||
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c)) {
|
||||
struct wlr_xwayland_surface *surface = c->surface.xwayland;
|
||||
xcb_size_hints_t *size_hints = surface->size_hints;
|
||||
if (surface->modal)
|
||||
return 1;
|
||||
|
||||
if (wlr_xwayland_surface_has_window_type(
|
||||
surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_DIALOG) ||
|
||||
wlr_xwayland_surface_has_window_type(
|
||||
surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_SPLASH) ||
|
||||
wlr_xwayland_surface_has_window_type(
|
||||
surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_TOOLBAR) ||
|
||||
wlr_xwayland_surface_has_window_type(
|
||||
surface, WLR_XWAYLAND_NET_WM_WINDOW_TYPE_UTILITY)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return size_hints && size_hints->min_width > 0 &&
|
||||
size_hints->min_height > 0 &&
|
||||
(size_hints->max_width == size_hints->min_width ||
|
||||
size_hints->max_height == size_hints->min_height);
|
||||
}
|
||||
#endif
|
||||
|
||||
toplevel = c->surface.xdg->toplevel;
|
||||
state = toplevel->current;
|
||||
return toplevel->parent || (state.min_width != 0 && state.min_height != 0 &&
|
||||
(state.min_width == state.max_width ||
|
||||
state.min_height == state.max_height));
|
||||
}
|
||||
|
||||
static inline int client_is_rendered_on_mon(Client *c, Monitor *m) {
|
||||
/* This is needed for when you don't want to check formal assignment,
|
||||
* but rather actual displaying of the pixels.
|
||||
* Usually VISIBLEON suffices and is also faster. */
|
||||
struct wlr_surface_output *s;
|
||||
int unused_lx, unused_ly;
|
||||
if (!wlr_scene_node_coords(&c->scene->node, &unused_lx, &unused_ly))
|
||||
return 0;
|
||||
wl_list_for_each(s, &client_surface(c)->current_outputs,
|
||||
link) if (s->output == m->wlr_output) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int client_is_stopped(Client *c) {
|
||||
int pid;
|
||||
siginfo_t in = {0};
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
wl_client_get_credentials(c->surface.xdg->client->client, &pid, NULL, NULL);
|
||||
if (waitid(P_PID, pid, &in, WNOHANG | WCONTINUED | WSTOPPED | WNOWAIT) < 0) {
|
||||
/* This process is not our child process, while is very unlikely that
|
||||
* it is stopped, in order to do not skip frames, assume that it is. */
|
||||
if (errno == ECHILD)
|
||||
return 1;
|
||||
} else if (in.si_pid) {
|
||||
if (in.si_code == CLD_STOPPED || in.si_code == CLD_TRAPPED)
|
||||
return 1;
|
||||
if (in.si_code == CLD_CONTINUED)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int client_is_unmanaged(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return c->surface.xwayland->override_redirect;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void client_notify_enter(struct wlr_surface *s,
|
||||
struct wlr_keyboard *kb) {
|
||||
if (kb)
|
||||
wlr_seat_keyboard_notify_enter(seat, s, kb->keycodes, kb->num_keycodes,
|
||||
&kb->modifiers);
|
||||
else
|
||||
wlr_seat_keyboard_notify_enter(seat, s, NULL, 0, NULL);
|
||||
}
|
||||
|
||||
static inline void client_send_close(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c)) {
|
||||
wlr_xwayland_surface_close(c->surface.xwayland);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
wlr_xdg_toplevel_send_close(c->surface.xdg->toplevel);
|
||||
}
|
||||
|
||||
static inline void client_set_border_color(Client *c,
|
||||
const float color[static 4]) {
|
||||
int i;
|
||||
for (i = 0; i < 4; i++)
|
||||
wlr_scene_rect_set_color(c->border[i], color);
|
||||
}
|
||||
|
||||
static inline void client_set_fullscreen(Client *c, int fullscreen) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c)) {
|
||||
wlr_xwayland_surface_set_fullscreen(c->surface.xwayland, fullscreen);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
wlr_xdg_toplevel_set_fullscreen(c->surface.xdg->toplevel, fullscreen);
|
||||
}
|
||||
|
||||
static inline void client_set_scale(struct wlr_surface *s, float scale) {
|
||||
wlr_fractional_scale_v1_notify_scale(s, scale);
|
||||
wlr_surface_set_preferred_buffer_scale(s, (int32_t)ceilf(scale));
|
||||
}
|
||||
|
||||
static inline uint32_t client_set_size(Client *c, uint32_t width,
|
||||
uint32_t height) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c)) {
|
||||
wlr_xwayland_surface_configure(c->surface.xwayland, c->geom.x + c->bw,
|
||||
c->geom.y + c->bw, width, height);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
if ((int32_t)width == c->surface.xdg->toplevel->current.width &&
|
||||
(int32_t)height == c->surface.xdg->toplevel->current.height)
|
||||
return 0;
|
||||
return wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, (int32_t)width,
|
||||
(int32_t)height);
|
||||
}
|
||||
|
||||
static inline void client_set_tiled(Client *c, uint32_t edges) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c)) {
|
||||
wlr_xwayland_surface_set_maximized(
|
||||
c->surface.xwayland, edges != WLR_EDGE_NONE, edges != WLR_EDGE_NONE);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if (wl_resource_get_version(c->surface.xdg->toplevel->resource) >=
|
||||
XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) {
|
||||
wlr_xdg_toplevel_set_tiled(c->surface.xdg->toplevel, edges);
|
||||
} else {
|
||||
wlr_xdg_toplevel_set_maximized(c->surface.xdg->toplevel,
|
||||
edges != WLR_EDGE_NONE);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void client_set_suspended(Client *c, int suspended) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return;
|
||||
#endif
|
||||
|
||||
wlr_xdg_toplevel_set_suspended(c->surface.xdg->toplevel, suspended);
|
||||
}
|
||||
|
||||
static inline int client_wants_focus(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
return client_is_unmanaged(c) &&
|
||||
wlr_xwayland_surface_override_redirect_wants_focus(
|
||||
c->surface.xwayland) &&
|
||||
wlr_xwayland_surface_icccm_input_model(c->surface.xwayland) !=
|
||||
WLR_ICCCM_INPUT_MODEL_NONE;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int client_wants_fullscreen(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return c->surface.xwayland->fullscreen;
|
||||
#endif
|
||||
return c->surface.xdg->toplevel->requested.fullscreen;
|
||||
}
|
||||
|
||||
#endif /* CRYWL_CLIENTUTIL_H */
|
||||
|
|
@ -1,3 +1,10 @@
|
|||
#include <stddef.h>
|
||||
|
||||
#include "cursor.h"
|
||||
#include "clientutil.h"
|
||||
|
||||
/* Applies a constraint to the pointer cursor, deactivating the old one.
|
||||
* Noop occurs if constraint matches the current applied constraint. */
|
||||
void cursorconstrain(struct wlr_pointer_constraint_v1 *constraint) {
|
||||
if (active_constraint == constraint)
|
||||
return;
|
||||
|
|
@ -9,15 +16,6 @@ void cursorconstrain(struct wlr_pointer_constraint_v1 *constraint) {
|
|||
wlr_pointer_constraint_v1_send_activated(constraint);
|
||||
}
|
||||
|
||||
void cursorframe(struct wl_listener *listener, void *data) {
|
||||
/* This event is forwarded by the cursor when a pointer emits a frame
|
||||
* event. Frame events are sent after regular pointer events to group
|
||||
* multiple events together. For instance, two axis events may happen at the
|
||||
* same time, in which case a frame event won't be sent in between. */
|
||||
/* Notify the client with pointer focus of the frame event. */
|
||||
wlr_seat_pointer_notify_frame(seat);
|
||||
}
|
||||
|
||||
void cursorwarptohint(void) {
|
||||
Client *c = NULL;
|
||||
double sx = active_constraint->current.cursor_hint.x;
|
||||
|
|
@ -30,33 +28,3 @@ void cursorwarptohint(void) {
|
|||
wlr_seat_pointer_warp(active_constraint->seat, sx, sy);
|
||||
}
|
||||
}
|
||||
|
||||
void setcursor(struct wl_listener *listener, void *data) {
|
||||
/* This event is raised by the seat when a client provides a cursor image */
|
||||
struct wlr_seat_pointer_request_set_cursor_event *event = data;
|
||||
/* If we're "grabbing" the cursor, don't use the client's image, we will
|
||||
* restore it after "grabbing" sending a leave event, followed by a enter
|
||||
* event, which will result in the client requesting set the cursor surface */
|
||||
if (cursor_mode != CurNormal && cursor_mode != CurPressed)
|
||||
return;
|
||||
/* This can be sent by any client, so we check to make sure this one
|
||||
* actually has pointer focus first. If so, we can tell the cursor to
|
||||
* use the provided surface as the cursor image. It will set the
|
||||
* hardware cursor on the output that it's currently on and continue to
|
||||
* do so as the cursor moves between outputs. */
|
||||
if (event->seat_client == seat->pointer_state.focused_client)
|
||||
wlr_cursor_set_surface(cursor, event->surface, event->hotspot_x,
|
||||
event->hotspot_y);
|
||||
}
|
||||
|
||||
void setcursorshape(struct wl_listener *listener, void *data) {
|
||||
struct wlr_cursor_shape_manager_v1_request_set_shape_event *event = data;
|
||||
if (cursor_mode != CurNormal && cursor_mode != CurPressed)
|
||||
return;
|
||||
/* This can be sent by any client, so we check to make sure this one
|
||||
* actually has pointer focus first. If so, we can tell the cursor to
|
||||
* use the provided cursor shape. */
|
||||
if (event->seat_client == seat->pointer_state.focused_client)
|
||||
wlr_cursor_set_xcursor(cursor, cursor_mgr,
|
||||
wlr_cursor_shape_v1_name(event->shape));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
#ifndef CRYWL_CURSOR_H
|
||||
#define CRYWL_CURSOR_H
|
||||
|
||||
#include <wlr/types/wlr_pointer_constraints_v1.h>
|
||||
|
||||
enum { CurNormal, CurPressed, CurMove, CurResize }; /* cursor */
|
||||
|
||||
struct wlr_cursor *cursor;
|
||||
unsigned int cursor_mode;
|
||||
struct wlr_pointer_constraint_v1 *active_constraint;
|
||||
|
||||
/* ===== Function Declarations ===== */
|
||||
static void cursorconstrain(struct wlr_pointer_constraint_v1 *constraint);
|
||||
static void cursorframe(struct wl_listener *listener, void *data);
|
||||
static void cursorwarptohint(void);
|
||||
static void setcursor(struct wl_listener *listener, void *data);
|
||||
static void setcursorshape(struct wl_listener *listener, void *data);
|
||||
void cursorconstrain(struct wlr_pointer_constraint_v1 *constraint);
|
||||
void cursorwarptohint(void);
|
||||
|
||||
#endif /* CRYWL_CURSOR_H */
|
||||
|
|
|
|||
|
|
@ -1,25 +0,0 @@
|
|||
void createdecoration(struct wl_listener *listener, void *data) {
|
||||
struct wlr_xdg_toplevel_decoration_v1 *deco = data;
|
||||
Client *c = deco->toplevel->base->data;
|
||||
c->decoration = deco;
|
||||
|
||||
LISTEN(&deco->events.request_mode, &c->set_decoration_mode,
|
||||
requestdecorationmode);
|
||||
LISTEN(&deco->events.destroy, &c->destroy_decoration, destroydecoration);
|
||||
|
||||
requestdecorationmode(&c->set_decoration_mode, deco);
|
||||
}
|
||||
|
||||
void destroydecoration(struct wl_listener *listener, void *data) {
|
||||
Client *c = wl_container_of(listener, c, destroy_decoration);
|
||||
|
||||
wl_list_remove(&c->destroy_decoration.link);
|
||||
wl_list_remove(&c->set_decoration_mode.link);
|
||||
}
|
||||
|
||||
void requestdecorationmode(struct wl_listener *listener, void *data) {
|
||||
Client *c = wl_container_of(listener, c, set_decoration_mode);
|
||||
if (c->surface.xdg->initialized)
|
||||
wlr_xdg_toplevel_decoration_v1_set_mode(
|
||||
c->decoration, WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
||||
}
|
||||
|
|
@ -1,9 +1,22 @@
|
|||
#ifndef CRYWL_DECORATION_H
|
||||
#define CRYWL_DECORATION_H
|
||||
|
||||
/* ===== Function Declarations ===== */
|
||||
static void createdecoration(struct wl_listener *listener, void *data);
|
||||
static void destroydecoration(struct wl_listener *listener, void *data);
|
||||
static void requestdecorationmode(struct wl_listener *listener, void *data);
|
||||
#include <wlr/types/wlr_xdg_decoration_v1.h>
|
||||
|
||||
#include "client.h"
|
||||
|
||||
static inline void destroydecoration(struct wl_listener *listener, void *data) {
|
||||
Client *c = wl_container_of(listener, c, destroy_decoration);
|
||||
|
||||
wl_list_remove(&c->destroy_decoration.link);
|
||||
wl_list_remove(&c->set_decoration_mode.link);
|
||||
}
|
||||
|
||||
static inline void requestdecorationmode(struct wl_listener *listener, void *data) {
|
||||
Client *c = wl_container_of(listener, c, set_decoration_mode);
|
||||
if (c->surface.xdg->initialized)
|
||||
wlr_xdg_toplevel_decoration_v1_set_mode(
|
||||
c->decoration, WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
||||
}
|
||||
|
||||
#endif /* CRYWL_DECORATION_H */
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
#ifndef CRYWL_DRAG_H
|
||||
#define CRYWL_DRAG_H
|
||||
|
||||
/* ===== Function Declarations ===== */
|
||||
static void destroydragicon(struct wl_listener *listener, void *data);
|
||||
static void requeststartdrag(struct wl_listener *listener, void *data);
|
||||
static void startdrag(struct wl_listener *listener, void *data);
|
||||
|
||||
#endif /* CRYWL_DRAG_H */
|
||||
114
src/lib/input.c
114
src/lib/input.c
|
|
@ -1,55 +1,16 @@
|
|||
void buttonpress(struct wl_listener *listener, void *data) {
|
||||
struct wlr_pointer_button_event *event = data;
|
||||
struct wlr_keyboard *keyboard;
|
||||
uint32_t mods;
|
||||
Client *c;
|
||||
const Button *b;
|
||||
#include <libinput.h>
|
||||
#include <wlr/backend/libinput.h>
|
||||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_data_device.h>
|
||||
#include <wlr/types/wlr_idle_notify_v1.h>
|
||||
#include <wlr/types/wlr_keyboard_group.h>
|
||||
|
||||
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||
#include "../util.h"
|
||||
#include "input.h"
|
||||
|
||||
switch (event->state) {
|
||||
case WL_POINTER_BUTTON_STATE_PRESSED:
|
||||
cursor_mode = CurPressed;
|
||||
selmon = xytomon(cursor->x, cursor->y);
|
||||
if (locked)
|
||||
break;
|
||||
|
||||
/* Change focus if the button was _pressed_ over a client */
|
||||
xytonode(cursor->x, cursor->y, NULL, &c, NULL, NULL, NULL);
|
||||
if (c && (!client_is_unmanaged(c) || client_wants_focus(c)))
|
||||
focusclient(c, 1);
|
||||
|
||||
keyboard = wlr_seat_get_keyboard(seat);
|
||||
mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
|
||||
for (b = buttons; b < END(buttons); b++) {
|
||||
if (CLEANMASK(mods) == CLEANMASK(b->mod) && event->button == b->button &&
|
||||
b->func) {
|
||||
b->func(&b->arg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WL_POINTER_BUTTON_STATE_RELEASED:
|
||||
/* If you released any buttons, we exit interactive move/resize mode. */
|
||||
/* TODO: should reset to the pointer focus's current setcursor */
|
||||
if (!locked && cursor_mode != CurNormal && cursor_mode != CurPressed) {
|
||||
wlr_cursor_set_xcursor(cursor, cursor_mgr, "default");
|
||||
cursor_mode = CurNormal;
|
||||
/* Drop the window off on its new monitor */
|
||||
selmon = xytomon(cursor->x, cursor->y);
|
||||
setmon(grabc, selmon, 0);
|
||||
grabc = NULL;
|
||||
return;
|
||||
}
|
||||
cursor_mode = CurNormal;
|
||||
break;
|
||||
}
|
||||
/* If the event wasn't handled by the compositor, notify the client with
|
||||
* pointer focus that a button press has occurred */
|
||||
wlr_seat_pointer_notify_button(seat, event->time_msec, event->button,
|
||||
event->state);
|
||||
}
|
||||
static KeyboardGroup *kb_group;
|
||||
|
||||
/* ===== EVENTS ===== */
|
||||
void createkeyboard(struct wlr_keyboard *keyboard) {
|
||||
/* Set the keymap to match the group keymap */
|
||||
wlr_keyboard_set_keymap(keyboard, kb_group->wlr_group->keyboard.keymap);
|
||||
|
|
@ -289,39 +250,6 @@ int keyrepeat(void *data) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void motionabsolute(struct wl_listener *listener, void *data) {
|
||||
/* This event is forwarded by the cursor when a pointer emits an _absolute_
|
||||
* motion event, from 0..1 on each axis. This happens, for example, when
|
||||
* wlroots is running under a Wayland window rather than KMS+DRM, and you
|
||||
* move the mouse over the window. You could enter the window from any edge,
|
||||
* so we have to warp the mouse there. Also, some hardware emits these events.
|
||||
*/
|
||||
struct wlr_pointer_motion_absolute_event *event = data;
|
||||
double lx, ly, dx, dy;
|
||||
|
||||
if (!event->time_msec) /* this is 0 with virtual pointers */
|
||||
wlr_cursor_warp_absolute(cursor, &event->pointer->base, event->x, event->y);
|
||||
|
||||
wlr_cursor_absolute_to_layout_coords(cursor, &event->pointer->base, event->x,
|
||||
event->y, &lx, &ly);
|
||||
dx = lx - cursor->x;
|
||||
dy = ly - cursor->y;
|
||||
motionnotify(event->time_msec, &event->pointer->base, dx, dy, dx, dy);
|
||||
}
|
||||
|
||||
void motionrelative(struct wl_listener *listener, void *data) {
|
||||
/* This event is forwarded by the cursor when a pointer emits a _relative_
|
||||
* pointer motion event (i.e. a delta) */
|
||||
struct wlr_pointer_motion_event *event = data;
|
||||
/* The cursor doesn't move unless we tell it to. The cursor automatically
|
||||
* handles constraining the motion to the output layout, as well as any
|
||||
* special configuration applied for the specific input device which
|
||||
* generated the event. You can pass NULL for the device if you want to move
|
||||
* the cursor around without any input. */
|
||||
motionnotify(event->time_msec, &event->pointer->base, event->delta_x,
|
||||
event->delta_y, event->unaccel_dx, event->unaccel_dy);
|
||||
}
|
||||
|
||||
void moveresize(const Arg *arg) {
|
||||
if (cursor_mode != CurNormal && cursor_mode != CurPressed)
|
||||
return;
|
||||
|
|
@ -372,25 +300,3 @@ void pointerfocus(Client *c, struct wlr_surface *surface, double sx, double sy,
|
|||
wlr_seat_pointer_notify_enter(seat, surface, sx, sy);
|
||||
wlr_seat_pointer_notify_motion(seat, time, sx, sy);
|
||||
}
|
||||
|
||||
void virtualkeyboard(struct wl_listener *listener, void *data) {
|
||||
struct wlr_virtual_keyboard_v1 *kb = data;
|
||||
/* virtual keyboards shouldn't share keyboard group */
|
||||
KeyboardGroup *group = createkeyboardgroup();
|
||||
/* Set the keymap to match the group keymap */
|
||||
wlr_keyboard_set_keymap(&kb->keyboard, group->wlr_group->keyboard.keymap);
|
||||
LISTEN(&kb->keyboard.base.events.destroy, &group->destroy,
|
||||
destroykeyboardgroup);
|
||||
|
||||
/* Add the new keyboard to the group */
|
||||
wlr_keyboard_group_add_keyboard(group->wlr_group, &kb->keyboard);
|
||||
}
|
||||
|
||||
void virtualpointer(struct wl_listener *listener, void *data) {
|
||||
struct wlr_virtual_pointer_v1_new_pointer_event *event = data;
|
||||
struct wlr_input_device *device = &event->new_pointer->pointer.base;
|
||||
|
||||
wlr_cursor_attach_input_device(cursor, device);
|
||||
if (event->suggested_output)
|
||||
wlr_cursor_map_input_to_output(cursor, device, event->suggested_output);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
#ifndef CRYWL_INPUT_H
|
||||
#define CRYWL_INPUT_H
|
||||
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
#include <wlr/types/wlr_keyboard.h>
|
||||
#include <wlr/types/wlr_pointer.h>
|
||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||
|
||||
#include "client.h"
|
||||
|
||||
typedef struct {
|
||||
unsigned int mod;
|
||||
unsigned int button;
|
||||
|
|
@ -33,8 +40,11 @@ typedef struct {
|
|||
struct wl_listener destroy;
|
||||
} PointerConstraint;
|
||||
|
||||
/* ===== Event Handlers ===== */
|
||||
static void virtualkeyboard(struct wl_listener *listener, void *data);
|
||||
static void virtualpointer(struct wl_listener *listener, void *data);
|
||||
|
||||
/* ===== Function Declarations ===== */
|
||||
static void buttonpress(struct wl_listener *listener, void *data);
|
||||
static void createkeyboard(struct wlr_keyboard *keyboard);
|
||||
static KeyboardGroup *createkeyboardgroup(void);
|
||||
static void createpointer(struct wlr_pointer *pointer);
|
||||
|
|
@ -46,12 +56,8 @@ static int keybinding(uint32_t mods, xkb_keysym_t sym);
|
|||
static void keypress(struct wl_listener *listener, void *data);
|
||||
static void keypressmod(struct wl_listener *listener, void *data);
|
||||
static int keyrepeat(void *data);
|
||||
static void motionabsolute(struct wl_listener *listener, void *data);
|
||||
static void motionrelative(struct wl_listener *listener, void *data);
|
||||
static void moveresize(const Arg *arg);
|
||||
static void pointerfocus(Client *c, struct wlr_surface *surface, double sx,
|
||||
double sy, uint32_t time);
|
||||
static void virtualkeyboard(struct wl_listener *listener, void *data);
|
||||
static void virtualpointer(struct wl_listener *listener, void *data);
|
||||
|
||||
#endif /* CRYWL_INPUT_H */
|
||||
|
|
|
|||
101
src/lib/layers.c
101
src/lib/layers.c
|
|
@ -1,5 +1,71 @@
|
|||
#include "lib/layers.h"
|
||||
#include "layers.h"
|
||||
|
||||
void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||
LayerSurface *l = wl_container_of(listener, l, surface_commit);
|
||||
struct wlr_layer_surface_v1 *layer_surface = l->layer_surface;
|
||||
struct wlr_scene_tree *scene_layer =
|
||||
layers[layermap[layer_surface->current.layer]];
|
||||
struct wlr_layer_surface_v1_state old_state;
|
||||
|
||||
if (l->layer_surface->initial_commit) {
|
||||
client_set_scale(layer_surface->surface, l->mon->wlr_output->scale);
|
||||
|
||||
/* Temporarily set the layer's current state to pending
|
||||
* so that we can easily arrange it */
|
||||
old_state = l->layer_surface->current;
|
||||
l->layer_surface->current = l->layer_surface->pending;
|
||||
arrangelayers(l->mon);
|
||||
l->layer_surface->current = old_state;
|
||||
return;
|
||||
}
|
||||
|
||||
if (layer_surface->current.committed == 0 &&
|
||||
l->mapped == layer_surface->surface->mapped)
|
||||
return;
|
||||
l->mapped = layer_surface->surface->mapped;
|
||||
|
||||
if (scene_layer != l->scene->node.parent) {
|
||||
wlr_scene_node_reparent(&l->scene->node, scene_layer);
|
||||
wl_list_remove(&l->link);
|
||||
wl_list_insert(&l->mon->layers[layer_surface->current.layer], &l->link);
|
||||
wlr_scene_node_reparent(
|
||||
&l->popups->node,
|
||||
(layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP
|
||||
? layers[LyrTop]
|
||||
: scene_layer));
|
||||
}
|
||||
|
||||
arrangelayers(l->mon);
|
||||
}
|
||||
|
||||
void unmaplayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||
LayerSurface *l = wl_container_of(listener, l, unmap);
|
||||
|
||||
l->mapped = 0;
|
||||
wlr_scene_node_set_enabled(&l->scene->node, 0);
|
||||
if (l == exclusive_focus)
|
||||
exclusive_focus = NULL;
|
||||
if (l->layer_surface->output && (l->mon = l->layer_surface->output->data))
|
||||
arrangelayers(l->mon);
|
||||
if (l->layer_surface->surface == seat->keyboard_state.focused_surface)
|
||||
focusclient(focustop(selmon), 1);
|
||||
motionnotify(0, NULL, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void destroylayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||
LayerSurface *l = wl_container_of(listener, l, destroy);
|
||||
|
||||
wl_list_remove(&l->link);
|
||||
wl_list_remove(&l->destroy.link);
|
||||
wl_list_remove(&l->unmap.link);
|
||||
wl_list_remove(&l->surface_commit.link);
|
||||
wlr_scene_node_destroy(&l->scene->node);
|
||||
wlr_scene_node_destroy(&l->popups->node);
|
||||
free(l);
|
||||
}
|
||||
|
||||
/* Binds commitlayersurfacenotify, unmaplayersurfacenotify, destroylayersurfacenotify
|
||||
*/
|
||||
void createlayersurface(struct wl_listener *listener, void *data) {
|
||||
struct wlr_layer_surface_v1 *layer_surface = data;
|
||||
LayerSurface *l;
|
||||
|
|
@ -34,3 +100,36 @@ void createlayersurface(struct wl_listener *listener, void *data) {
|
|||
wl_list_insert(&l->mon->layers[layer_surface->pending.layer], &l->link);
|
||||
wlr_surface_send_enter(surface, layer_surface->output);
|
||||
}
|
||||
|
||||
void xytonode(double x, double y, struct wlr_surface **psurface, Client **pc,
|
||||
LayerSurface **pl, double *nx, double *ny) {
|
||||
struct wlr_scene_node *node, *pnode;
|
||||
struct wlr_surface *surface = NULL;
|
||||
Client *c = NULL;
|
||||
LayerSurface *l = NULL;
|
||||
int layer;
|
||||
|
||||
for (layer = NUM_LAYERS - 1; !surface && layer >= 0; layer--) {
|
||||
if (!(node = wlr_scene_node_at(&layers[layer]->node, x, y, nx, ny)))
|
||||
continue;
|
||||
|
||||
if (node->type == WLR_SCENE_NODE_BUFFER)
|
||||
surface =
|
||||
wlr_scene_surface_try_from_buffer(wlr_scene_buffer_from_node(node))
|
||||
->surface;
|
||||
/* Walk the tree to find a node that knows the client */
|
||||
for (pnode = node; pnode && !c; pnode = &pnode->parent->node)
|
||||
c = pnode->data;
|
||||
if (c && c->type == LayerShell) {
|
||||
c = NULL;
|
||||
l = pnode->data;
|
||||
}
|
||||
}
|
||||
|
||||
if (psurface)
|
||||
*psurface = surface;
|
||||
if (pc)
|
||||
*pc = c;
|
||||
if (pl)
|
||||
*pl = l;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,19 +1,7 @@
|
|||
#ifndef CRYWL_LAYERS_H
|
||||
#define CRYWL_LAYERS_H
|
||||
|
||||
#include "lib/monitor.h"
|
||||
|
||||
enum {
|
||||
LyrBg,
|
||||
LyrBottom,
|
||||
LyrTile,
|
||||
LyrFloat,
|
||||
LyrTop,
|
||||
LyrFS,
|
||||
LyrOverlay,
|
||||
LyrBlock,
|
||||
NUM_LAYERS
|
||||
}; /* scene layers */
|
||||
#include "monitor.h"
|
||||
|
||||
typedef struct {
|
||||
/* Must keep this field first */
|
||||
|
|
@ -32,7 +20,14 @@ typedef struct {
|
|||
struct wl_listener surface_commit;
|
||||
} LayerSurface;
|
||||
|
||||
/* ===== Function Declarations ===== */
|
||||
/* ===== Event Handlers ===== */
|
||||
static void commitlayersurfacenotify(struct wl_listener *listener, void *data);
|
||||
static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);
|
||||
static void destroylayersurfacenotify(struct wl_listener *listener, void *data);
|
||||
// createlayersurface uses the (commit|unmap|destroy)layersurfacenotify callbacks
|
||||
static void createlayersurface(struct wl_listener *listener, void *data);
|
||||
|
||||
void xytonode(double x, double y, struct wlr_surface **psurface,
|
||||
Client **pc, LayerSurface **pl, double *nx, double *ny);
|
||||
|
||||
#endif /* CRYWL_LAYERS_H */
|
||||
|
|
|
|||
|
|
@ -1,14 +0,0 @@
|
|||
#ifndef CRYWL_MACROS_H
|
||||
#define CRYWL_MACROS_H
|
||||
|
||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||
#define CLEANMASK(mask) (mask & ~WLR_MODIFIER_CAPS)
|
||||
#define VISIBLEON(C, M) ((M) && (C)->mon == (M) && ((C)->tags & (M)->tagset[(M)->seltags]))
|
||||
#define LENGTH(X) (sizeof X / sizeof X[0])
|
||||
#define END(A) ((A) + LENGTH(A))
|
||||
#define TAGMASK ((1u << TAGCOUNT) - 1)
|
||||
#define LISTEN(E, L, H) wl_signal_add((E), ((L)->notify = (H), (L)))
|
||||
#define LISTEN_STATIC(E, H) do { struct wl_listener *_l = ecalloc(1, sizeof(*_l)); _l->notify = (H); wl_signal_add((E), _l); } while (0)
|
||||
|
||||
#endif /* CRYWL_MACROS_H */
|
||||
|
|
@ -1,4 +1,33 @@
|
|||
#include "lib/monitor.h"
|
||||
#include "monitor.h"
|
||||
#include "clientutil.h"
|
||||
|
||||
void applyrules(Client *c) {
|
||||
/* rule matching */
|
||||
const char *appid, *title;
|
||||
uint32_t newtags = 0;
|
||||
int i;
|
||||
const Rule *r;
|
||||
Monitor *mon = selmon, *m;
|
||||
|
||||
appid = client_get_appid(c);
|
||||
title = client_get_title(c);
|
||||
|
||||
for (r = rules; r < END(rules); r++) {
|
||||
if ((!r->title || strstr(title, r->title)) &&
|
||||
(!r->id || strstr(appid, r->id))) {
|
||||
c->isfloating = r->isfloating;
|
||||
newtags |= r->tags;
|
||||
i = 0;
|
||||
wl_list_for_each(m, &mons, link) {
|
||||
if (r->monitor == i++)
|
||||
mon = m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
c->isfloating |= client_is_float_type(c);
|
||||
setmon(c, mon, newtags);
|
||||
}
|
||||
|
||||
void arrange(Monitor *m) {
|
||||
Client *c;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef CRYWL_MONITOR_H
|
||||
#define CRYWL_MONITOR_H
|
||||
|
||||
#include "lib/client.h"
|
||||
#include "client.h"
|
||||
|
||||
// client.h contains a forward declaration of Monitor
|
||||
typedef struct {
|
||||
|
|
@ -51,33 +51,31 @@ typedef struct {
|
|||
int monitor;
|
||||
} Rule;
|
||||
|
||||
|
||||
/* ===== Fucntion Declarations ===== */
|
||||
static void arrange(Monitor *m);
|
||||
static void arrangelayer(Monitor *m, struct wl_list *list,
|
||||
struct wlr_box *usable_area, int exclusive);
|
||||
static void arrangelayers(Monitor *m);
|
||||
static void cleanupmon(struct wl_listener *listener, void *data);
|
||||
static void closemon(Monitor *m);
|
||||
static void createmon(struct wl_listener *listener, void *data);
|
||||
static Monitor *dirtomon(enum wlr_direction dir);
|
||||
static void focusmon(const Arg *arg);
|
||||
static void focusstack(const Arg *arg);
|
||||
static Client *focustop(Monitor *m);
|
||||
static void gpureset(struct wl_listener *listener, void *data);
|
||||
static void incnmaster(const Arg *arg);
|
||||
static void monocle(Monitor *m);
|
||||
static void rendermon(struct wl_listener *listener, void *data);
|
||||
static void requestmonstate(struct wl_listener *listener, void *data);
|
||||
static void setlayout(const Arg *arg);
|
||||
static void setmfact(const Arg *arg);
|
||||
static void setmon(Client *c, Monitor *m, uint32_t newtags);
|
||||
static void tag(const Arg *arg);
|
||||
static void tagmon(const Arg *arg);
|
||||
static void tile(Monitor *m);
|
||||
static void updatemons(struct wl_listener *listener, void *data);
|
||||
static Monitor *xytomon(double x, double y);
|
||||
|
||||
|
||||
/* ===== Function Declarations ===== */
|
||||
void applyrules(Client *c);
|
||||
void arrange(Monitor *m);
|
||||
void arrangelayer(Monitor *m, struct wl_list *list,
|
||||
struct wlr_box *usable_area, int exclusive);
|
||||
void arrangelayers(Monitor *m);
|
||||
void cleanupmon(struct wl_listener *listener, void *data);
|
||||
void closemon(Monitor *m);
|
||||
void createmon(struct wl_listener *listener, void *data);
|
||||
Monitor *dirtomon(enum wlr_direction dir);
|
||||
void focusmon(const Arg *arg);
|
||||
void focusstack(const Arg *arg);
|
||||
Client *focustop(Monitor *m);
|
||||
void gpureset(struct wl_listener *listener, void *data);
|
||||
void incnmaster(const Arg *arg);
|
||||
void monocle(Monitor *m);
|
||||
void rendermon(struct wl_listener *listener, void *data);
|
||||
void requestmonstate(struct wl_listener *listener, void *data);
|
||||
void setlayout(const Arg *arg);
|
||||
void setmfact(const Arg *arg);
|
||||
void setmon(Client *c, Monitor *m, uint32_t newtags);
|
||||
void tag(const Arg *arg);
|
||||
void tagmon(const Arg *arg);
|
||||
void tile(Monitor *m);
|
||||
void updatemons(struct wl_listener *listener, void *data);
|
||||
Monitor *xytomon(double x, double y);
|
||||
|
||||
#endif /* CRYWL_MONITOR_H */
|
||||
|
|
|
|||
|
|
@ -1,54 +1,3 @@
|
|||
void axisnotify(struct wl_listener *listener, void *data) {
|
||||
/* This event is forwarded by the cursor when a pointer emits an axis event,
|
||||
* for example when you move the scroll wheel. */
|
||||
struct wlr_pointer_axis_event *event = data;
|
||||
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||
/* TODO: allow usage of scroll wheel for mousebindings, it can be implemented
|
||||
* by checking the event's orientation and the delta of the event */
|
||||
/* Notify the client with pointer focus of the axis event. */
|
||||
wlr_seat_pointer_notify_axis(seat, event->time_msec, event->orientation,
|
||||
event->delta, event->delta_discrete,
|
||||
event->source, event->relative_direction);
|
||||
}
|
||||
|
||||
void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||
LayerSurface *l = wl_container_of(listener, l, surface_commit);
|
||||
struct wlr_layer_surface_v1 *layer_surface = l->layer_surface;
|
||||
struct wlr_scene_tree *scene_layer =
|
||||
layers[layermap[layer_surface->current.layer]];
|
||||
struct wlr_layer_surface_v1_state old_state;
|
||||
|
||||
if (l->layer_surface->initial_commit) {
|
||||
client_set_scale(layer_surface->surface, l->mon->wlr_output->scale);
|
||||
|
||||
/* Temporarily set the layer's current state to pending
|
||||
* so that we can easily arrange it */
|
||||
old_state = l->layer_surface->current;
|
||||
l->layer_surface->current = l->layer_surface->pending;
|
||||
arrangelayers(l->mon);
|
||||
l->layer_surface->current = old_state;
|
||||
return;
|
||||
}
|
||||
|
||||
if (layer_surface->current.committed == 0 &&
|
||||
l->mapped == layer_surface->surface->mapped)
|
||||
return;
|
||||
l->mapped = layer_surface->surface->mapped;
|
||||
|
||||
if (scene_layer != l->scene->node.parent) {
|
||||
wlr_scene_node_reparent(&l->scene->node, scene_layer);
|
||||
wl_list_remove(&l->link);
|
||||
wl_list_insert(&l->mon->layers[layer_surface->current.layer], &l->link);
|
||||
wlr_scene_node_reparent(
|
||||
&l->popups->node,
|
||||
(layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP
|
||||
? layers[LyrTop]
|
||||
: scene_layer));
|
||||
}
|
||||
|
||||
arrangelayers(l->mon);
|
||||
}
|
||||
|
||||
void commitnotify(struct wl_listener *listener, void *data) {
|
||||
Client *c = wl_container_of(listener, c, commit);
|
||||
|
||||
|
|
@ -101,18 +50,6 @@ void createnotify(struct wl_listener *listener, void *data) {
|
|||
LISTEN(&toplevel->events.set_title, &c->set_title, updatetitle);
|
||||
}
|
||||
|
||||
void destroylayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||
LayerSurface *l = wl_container_of(listener, l, destroy);
|
||||
|
||||
wl_list_remove(&l->link);
|
||||
wl_list_remove(&l->destroy.link);
|
||||
wl_list_remove(&l->unmap.link);
|
||||
wl_list_remove(&l->surface_commit.link);
|
||||
wlr_scene_node_destroy(&l->scene->node);
|
||||
wlr_scene_node_destroy(&l->popups->node);
|
||||
free(l);
|
||||
}
|
||||
|
||||
void destroynotify(struct wl_listener *listener, void *data) {
|
||||
/* Called when the xdg_toplevel is destroyed. */
|
||||
Client *c = wl_container_of(listener, c, destroy);
|
||||
|
|
@ -316,20 +253,6 @@ void motionnotify(uint32_t time, struct wlr_input_device *device, double dx,
|
|||
pointerfocus(c, surface, sx, sy, time);
|
||||
}
|
||||
|
||||
void unmaplayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||
LayerSurface *l = wl_container_of(listener, l, unmap);
|
||||
|
||||
l->mapped = 0;
|
||||
wlr_scene_node_set_enabled(&l->scene->node, 0);
|
||||
if (l == exclusive_focus)
|
||||
exclusive_focus = NULL;
|
||||
if (l->layer_surface->output && (l->mon = l->layer_surface->output->data))
|
||||
arrangelayers(l->mon);
|
||||
if (l->layer_surface->surface == seat->keyboard_state.focused_surface)
|
||||
focusclient(focustop(selmon), 1);
|
||||
motionnotify(0, NULL, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void unmapnotify(struct wl_listener *listener, void *data) {
|
||||
/* Called when the surface is unmapped, and should no longer be shown. */
|
||||
Client *c = wl_container_of(listener, c, unmap);
|
||||
|
|
|
|||
|
|
@ -2,11 +2,8 @@
|
|||
#define CRYWL_NOTIFY_H
|
||||
|
||||
/* ===== Function Declarations ===== */
|
||||
static void axisnotify(struct wl_listener *listener, void *data);
|
||||
static void commitlayersurfacenotify(struct wl_listener *listener, void *data);
|
||||
static void commitnotify(struct wl_listener *listener, void *data);
|
||||
static void createnotify(struct wl_listener *listener, void *data);
|
||||
static void destroylayersurfacenotify(struct wl_listener *listener, void *data);
|
||||
static void destroynotify(struct wl_listener *listener, void *data);
|
||||
static void fullscreennotify(struct wl_listener *listener, void *data);
|
||||
static void mapnotify(struct wl_listener *listener, void *data);
|
||||
|
|
@ -14,7 +11,6 @@ static void maximizenotify(struct wl_listener *listener, void *data);
|
|||
static void motionnotify(uint32_t time, struct wlr_input_device *device,
|
||||
double sx, double sy, double sx_unaccel,
|
||||
double sy_unaccel);
|
||||
static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);
|
||||
static void unmapnotify(struct wl_listener *listener, void *data);
|
||||
|
||||
#endif /* CRYWL_NOTIFY_H */
|
||||
|
|
|
|||
18
src/listeners/decoration.h
Normal file
18
src/listeners/decoration.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef CRYWM_LSTN_DECORATION_H
|
||||
#define CRYWM_LSTN_DECORATION_H
|
||||
|
||||
#include "../lib/decoration.h"
|
||||
|
||||
static void createdecoration(struct wl_listener *listener, void *data) {
|
||||
struct wlr_xdg_toplevel_decoration_v1 *deco = data;
|
||||
Client *c = deco->toplevel->base->data;
|
||||
c->decoration = deco;
|
||||
|
||||
LISTEN(&deco->events.request_mode, &c->set_decoration_mode,
|
||||
requestdecorationmode);
|
||||
LISTEN(&deco->events.destroy, &c->destroy_decoration, destroydecoration);
|
||||
|
||||
requestdecorationmode(&c->set_decoration_mode, deco);
|
||||
}
|
||||
|
||||
#endif /* CRYWM_LSTN_DECORATION_H */
|
||||
|
|
@ -1,4 +1,11 @@
|
|||
void destroydragicon(struct wl_listener *listener, void *data) {
|
||||
#ifndef CRYWL_LSTN_DRAG_H
|
||||
#define CRYWL_LSTN_DRAG_H
|
||||
|
||||
#include "../lib/clientutil.h"
|
||||
#include "../lib/notify.h"
|
||||
|
||||
/* Helper for the startdrag() listener */
|
||||
static void destroydragicon(struct wl_listener *listener, void *data) {
|
||||
/* Focus enter isn't sent during drag, so refocus the focused node. */
|
||||
focusclient(focustop(selmon), 1);
|
||||
motionnotify(0, NULL, 0, 0, 0, 0);
|
||||
|
|
@ -6,7 +13,9 @@ void destroydragicon(struct wl_listener *listener, void *data) {
|
|||
free(listener);
|
||||
}
|
||||
|
||||
void requeststartdrag(struct wl_listener *listener, void *data) {
|
||||
/* ===== LISTENERS ===== */
|
||||
|
||||
static void requeststartdrag(struct wl_listener *listener, void *data) {
|
||||
struct wlr_seat_request_start_drag_event *event = data;
|
||||
|
||||
if (wlr_seat_validate_pointer_grab_serial(seat, event->origin, event->serial))
|
||||
|
|
@ -15,7 +24,7 @@ void requeststartdrag(struct wl_listener *listener, void *data) {
|
|||
wlr_data_source_destroy(event->drag->source);
|
||||
}
|
||||
|
||||
void startdrag(struct wl_listener *listener, void *data) {
|
||||
static void startdrag(struct wl_listener *listener, void *data) {
|
||||
struct wlr_drag *drag = data;
|
||||
if (!drag->icon)
|
||||
return;
|
||||
|
|
@ -24,3 +33,4 @@ void startdrag(struct wl_listener *listener, void *data) {
|
|||
LISTEN_STATIC(&drag->icon->events.destroy, destroydragicon);
|
||||
}
|
||||
|
||||
#endif /* CRYWL_LSTN_DRAG_H */
|
||||
169
src/listeners/input.h
Normal file
169
src/listeners/input.h
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
#ifndef CRYWL_LSTN_INPUT_H
|
||||
#define CRYWL_LSTN_INPUT_H
|
||||
|
||||
#include "../lib/clientutil.h"
|
||||
#include "../lib/input.h"
|
||||
#include "../lib/cursor.h"
|
||||
#include "../lib/notify.h"
|
||||
|
||||
static inline void axisnotify(struct wl_listener *listener, void *data) {
|
||||
/* This event is forwarded by the cursor when a pointer emits an axis event,
|
||||
* for example when you move the scroll wheel. */
|
||||
struct wlr_pointer_axis_event *event = data;
|
||||
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||
/* TODO: allow usage of scroll wheel for mousebindings, it can be implemented
|
||||
* by checking the event's orientation and the delta of the event */
|
||||
/* Notify the client with pointer focus of the axis event. */
|
||||
wlr_seat_pointer_notify_axis(seat, event->time_msec, event->orientation,
|
||||
event->delta, event->delta_discrete,
|
||||
event->source, event->relative_direction);
|
||||
}
|
||||
|
||||
static inline void motionabsolute(struct wl_listener *listener, void *data) {
|
||||
/* This event is forwarded by the cursor when a pointer emits an _absolute_
|
||||
* motion event, from 0..1 on each axis. This happens, for example, when
|
||||
* wlroots is running under a Wayland window rather than KMS+DRM, and you
|
||||
* move the mouse over the window. You could enter the window from any edge,
|
||||
* so we have to warp the mouse there. Also, some hardware emits these events.
|
||||
*/
|
||||
struct wlr_pointer_motion_absolute_event *event = data;
|
||||
double lx, ly, dx, dy;
|
||||
|
||||
if (!event->time_msec) /* this is 0 with virtual pointers */
|
||||
wlr_cursor_warp_absolute(cursor, &event->pointer->base, event->x, event->y);
|
||||
|
||||
wlr_cursor_absolute_to_layout_coords(cursor, &event->pointer->base, event->x,
|
||||
event->y, &lx, &ly);
|
||||
dx = lx - cursor->x;
|
||||
dy = ly - cursor->y;
|
||||
motionnotify(event->time_msec, &event->pointer->base, dx, dy, dx, dy);
|
||||
}
|
||||
|
||||
static inline void motionrelative(struct wl_listener *listener, void *data) {
|
||||
/* This event is forwarded by the cursor when a pointer emits a _relative_
|
||||
* pointer motion event (i.e. a delta) */
|
||||
struct wlr_pointer_motion_event *event = data;
|
||||
/* The cursor doesn't move unless we tell it to. The cursor automatically
|
||||
* handles constraining the motion to the output layout, as well as any
|
||||
* special configuration applied for the specific input device which
|
||||
* generated the event. You can pass NULL for the device if you want to move
|
||||
* the cursor around without any input. */
|
||||
motionnotify(event->time_msec, &event->pointer->base, event->delta_x,
|
||||
event->delta_y, event->unaccel_dx, event->unaccel_dy);
|
||||
}
|
||||
|
||||
static inline void virtualkeyboard(struct wl_listener *listener, void *data) {
|
||||
struct wlr_virtual_keyboard_v1 *kb = data;
|
||||
/* virtual keyboards shouldn't share keyboard group */
|
||||
KeyboardGroup *group = createkeyboardgroup();
|
||||
/* Set the keymap to match the group keymap */
|
||||
wlr_keyboard_set_keymap(&kb->keyboard, group->wlr_group->keyboard.keymap);
|
||||
LISTEN(&kb->keyboard.base.events.destroy, &group->destroy,
|
||||
destroykeyboardgroup);
|
||||
|
||||
/* Add the new keyboard to the group */
|
||||
wlr_keyboard_group_add_keyboard(group->wlr_group, &kb->keyboard);
|
||||
}
|
||||
|
||||
static inline void virtualpointer(struct wl_listener *listener, void *data) {
|
||||
struct wlr_virtual_pointer_v1_new_pointer_event *event = data;
|
||||
struct wlr_input_device *device = &event->new_pointer->pointer.base;
|
||||
|
||||
wlr_cursor_attach_input_device(cursor, device);
|
||||
if (event->suggested_output)
|
||||
wlr_cursor_map_input_to_output(cursor, device, event->suggested_output);
|
||||
}
|
||||
|
||||
|
||||
static inline void buttonpress(struct wl_listener *listener, void *data) {
|
||||
struct wlr_pointer_button_event *event = data;
|
||||
struct wlr_keyboard *keyboard;
|
||||
uint32_t mods;
|
||||
Client *c;
|
||||
const Button *b;
|
||||
|
||||
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
||||
|
||||
switch (event->state) {
|
||||
case WL_POINTER_BUTTON_STATE_PRESSED:
|
||||
cursor_mode = CurPressed;
|
||||
selmon = xytomon(cursor->x, cursor->y);
|
||||
if (locked)
|
||||
break;
|
||||
|
||||
/* Change focus if the button was _pressed_ over a client */
|
||||
xytonode(cursor->x, cursor->y, NULL, &c, NULL, NULL, NULL);
|
||||
if (c && (!client_is_unmanaged(c) || client_wants_focus(c)))
|
||||
focusclient(c, 1);
|
||||
|
||||
keyboard = wlr_seat_get_keyboard(seat);
|
||||
mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
|
||||
for (b = buttons; b < END(buttons); b++) {
|
||||
if (CLEANMASK(mods) == CLEANMASK(b->mod) && event->button == b->button &&
|
||||
b->func) {
|
||||
b->func(&b->arg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WL_POINTER_BUTTON_STATE_RELEASED:
|
||||
/* If you released any buttons, we exit interactive move/resize mode. */
|
||||
/* TODO: should reset to the pointer focus's current setcursor */
|
||||
if (!locked && cursor_mode != CurNormal && cursor_mode != CurPressed) {
|
||||
wlr_cursor_set_xcursor(cursor, cursor_mgr, "default");
|
||||
cursor_mode = CurNormal;
|
||||
/* Drop the window off on its new monitor */
|
||||
selmon = xytomon(cursor->x, cursor->y);
|
||||
setmon(grabc, selmon, 0);
|
||||
grabc = NULL;
|
||||
return;
|
||||
}
|
||||
cursor_mode = CurNormal;
|
||||
break;
|
||||
}
|
||||
/* If the event wasn't handled by the compositor, notify the client with
|
||||
* pointer focus that a button press has occurred */
|
||||
wlr_seat_pointer_notify_button(seat, event->time_msec, event->button,
|
||||
event->state);
|
||||
}
|
||||
|
||||
static inline void cursorframe(struct wl_listener *listener, void *data) {
|
||||
/* This event is forwarded by the cursor when a pointer emits a frame
|
||||
* event. Frame events are sent after regular pointer events to group
|
||||
* multiple events together. For instance, two axis events may happen at the
|
||||
* same time, in which case a frame event won't be sent in between. */
|
||||
/* Notify the client with pointer focus of the frame event. */
|
||||
wlr_seat_pointer_notify_frame(seat);
|
||||
}
|
||||
|
||||
static inline void setcursor(struct wl_listener *listener, void *data) {
|
||||
/* This event is raised by the seat when a client provides a cursor image */
|
||||
struct wlr_seat_pointer_request_set_cursor_event *event = data;
|
||||
/* If we're "grabbing" the cursor, don't use the client's image, we will
|
||||
* restore it after "grabbing" sending a leave event, followed by a enter
|
||||
* event, which will result in the client requesting set the cursor surface */
|
||||
if (cursor_mode != CurNormal && cursor_mode != CurPressed)
|
||||
return;
|
||||
/* This can be sent by any client, so we check to make sure this one
|
||||
* actually has pointer focus first. If so, we can tell the cursor to
|
||||
* use the provided surface as the cursor image. It will set the
|
||||
* hardware cursor on the output that it's currently on and continue to
|
||||
* do so as the cursor moves between outputs. */
|
||||
if (event->seat_client == seat->pointer_state.focused_client)
|
||||
wlr_cursor_set_surface(cursor, event->surface, event->hotspot_x,
|
||||
event->hotspot_y);
|
||||
}
|
||||
|
||||
static inline void setcursorshape(struct wl_listener *listener, void *data) {
|
||||
struct wlr_cursor_shape_manager_v1_request_set_shape_event *event = data;
|
||||
if (cursor_mode != CurNormal && cursor_mode != CurPressed)
|
||||
return;
|
||||
/* This can be sent by any client, so we check to make sure this one
|
||||
* actually has pointer focus first. If so, we can tell the cursor to
|
||||
* use the provided cursor shape. */
|
||||
if (event->seat_client == seat->pointer_state.focused_client)
|
||||
wlr_cursor_set_xcursor(cursor, cursor_mgr,
|
||||
wlr_cursor_shape_v1_name(event->shape));
|
||||
}
|
||||
|
||||
#endif /* CRYWL_LSTN_INPUT_H */
|
||||
23
src/listeners/listeners.h
Normal file
23
src/listeners/listeners.h
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef CRYWL_LSTN_ALL_H
|
||||
#define CRYWL_LSTN_ALL_H
|
||||
|
||||
#include "input.h"
|
||||
#include "decoration.h"
|
||||
#include "drag.h"
|
||||
|
||||
static struct wl_listener cursor_button = {.notify = buttonpress};
|
||||
static struct wl_listener cursor_frame = {.notify = cursorframe};
|
||||
static struct wl_listener request_cursor = {.notify = setcursor};
|
||||
static struct wl_listener request_set_cursor_shape = {.notify = setcursorshape};
|
||||
|
||||
static struct wl_listener cursor_axis = {.notify = axisnotify};
|
||||
static struct wl_listener cursor_motion = {.notify = motionrelative};
|
||||
static struct wl_listener cursor_motion_absolute = {.notify = motionabsolute};
|
||||
static struct wl_listener new_virtual_keyboard = {.notify = virtualkeyboard};
|
||||
static struct wl_listener new_virtual_pointer = {.notify = virtualpointer};
|
||||
|
||||
static struct wl_listener new_xdg_decoration = {.notify = createdecoration};
|
||||
|
||||
static struct wl_listener start_drag = {.notify = startdrag};
|
||||
|
||||
#endif /*CRYWL_LSTN_ALL_H*/
|
||||
62
src/main.c
62
src/main.c
|
|
@ -69,64 +69,9 @@
|
|||
#endif
|
||||
|
||||
#include "util.h"
|
||||
#include "lib/layers.h"
|
||||
|
||||
/* variables */
|
||||
static int locked;
|
||||
static void *exclusive_focus;
|
||||
static struct wl_event_loop *event_loop;
|
||||
static struct wlr_backend *backend;
|
||||
static struct wlr_scene *scene;
|
||||
static struct wlr_scene_tree *layers[NUM_LAYERS];
|
||||
static struct wlr_scene_tree *drag_icon;
|
||||
/* Map from ZWLR_LAYER_SHELL_* constants to Lyr* enum */
|
||||
static const int layermap[] = {LyrBg, LyrBottom, LyrTop, LyrOverlay};
|
||||
static struct wlr_renderer *drw;
|
||||
static struct wlr_allocator *alloc;
|
||||
static struct wlr_compositor *compositor;
|
||||
static struct wlr_session *session;
|
||||
|
||||
static struct wlr_xdg_shell *xdg_shell;
|
||||
static struct wlr_xdg_activation_v1 *activation;
|
||||
static struct wlr_xdg_decoration_manager_v1 *xdg_decoration_mgr;
|
||||
static struct wl_list clients; /* tiling order */
|
||||
static struct wl_list fstack; /* focus order */
|
||||
static struct wlr_idle_notifier_v1 *idle_notifier;
|
||||
static struct wlr_idle_inhibit_manager_v1 *idle_inhibit_mgr;
|
||||
static struct wlr_layer_shell_v1 *layer_shell;
|
||||
static struct wlr_output_manager_v1 *output_mgr;
|
||||
static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr;
|
||||
static struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr;
|
||||
static struct wlr_cursor_shape_manager_v1 *cursor_shape_mgr;
|
||||
static struct wlr_output_power_manager_v1 *power_mgr;
|
||||
|
||||
static struct wlr_pointer_constraints_v1 *pointer_constraints;
|
||||
static struct wlr_relative_pointer_manager_v1 *relative_pointer_mgr;
|
||||
static struct wlr_pointer_constraint_v1 *active_constraint;
|
||||
|
||||
static struct wlr_cursor *cursor;
|
||||
static struct wlr_xcursor_manager *cursor_mgr;
|
||||
|
||||
static struct wlr_scene_rect *root_bg;
|
||||
static struct wlr_session_lock_manager_v1 *session_lock_mgr;
|
||||
static struct wlr_scene_rect *locked_bg;
|
||||
static struct wlr_session_lock_v1 *cur_lock;
|
||||
|
||||
static struct wlr_seat *seat;
|
||||
static KeyboardGroup *kb_group;
|
||||
static unsigned int cursor_mode;
|
||||
static Client *grabc;
|
||||
static int grabcx, grabcy; /* client-relative */
|
||||
|
||||
static struct wlr_output_layout *output_layout;
|
||||
static struct wlr_box sgeom;
|
||||
static struct wl_list mons;
|
||||
static Monitor *selmon;
|
||||
|
||||
/* global event handlers */
|
||||
static struct wl_listener cursor_axis = {.notify = axisnotify};
|
||||
static struct wl_listener cursor_button = {.notify = buttonpress};
|
||||
static struct wl_listener cursor_frame = {.notify = cursorframe};
|
||||
static struct wl_listener cursor_motion = {.notify = motionrelative};
|
||||
static struct wl_listener cursor_motion_absolute = {.notify = motionabsolute};
|
||||
static struct wl_listener gpu_reset = {.notify = gpureset};
|
||||
|
|
@ -140,27 +85,20 @@ static struct wl_listener new_pointer_constraint = {
|
|||
static struct wl_listener new_output = {.notify = createmon};
|
||||
static struct wl_listener new_xdg_toplevel = {.notify = createnotify};
|
||||
static struct wl_listener new_xdg_popup = {.notify = createpopup};
|
||||
static struct wl_listener new_xdg_decoration = {.notify = createdecoration};
|
||||
static struct wl_listener new_layer_surface = {.notify = createlayersurface};
|
||||
static struct wl_listener output_mgr_apply = {.notify = outputmgrapply};
|
||||
static struct wl_listener output_mgr_test = {.notify = outputmgrtest};
|
||||
static struct wl_listener output_power_mgr_set_mode = {.notify =
|
||||
powermgrsetmode};
|
||||
static struct wl_listener request_activate = {.notify = urgent};
|
||||
static struct wl_listener request_cursor = {.notify = setcursor};
|
||||
static struct wl_listener request_set_psel = {.notify = setpsel};
|
||||
static struct wl_listener request_set_sel = {.notify = setsel};
|
||||
static struct wl_listener request_set_cursor_shape = {.notify = setcursorshape};
|
||||
static struct wl_listener request_start_drag = {.notify = requeststartdrag};
|
||||
static struct wl_listener start_drag = {.notify = startdrag};
|
||||
static struct wl_listener new_session_lock = {.notify = locksession};
|
||||
|
||||
/* configuration, allows nested code to access above variables */
|
||||
#include "config.h"
|
||||
|
||||
/* attempt to encapsulate suck into one file */
|
||||
#include "client.h"
|
||||
|
||||
/* function implementations */
|
||||
int main(int argc, char *argv[]) {
|
||||
char *startup_cmd = NULL;
|
||||
|
|
|
|||
53
src/shared.c
Normal file
53
src/shared.c
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#define IGNORE_EXTERNS
|
||||
#include "shared.h"
|
||||
|
||||
/* variables */
|
||||
int locked;
|
||||
void *exclusive_focus;
|
||||
struct wl_event_loop *event_loop;
|
||||
struct wlr_backend *backend;
|
||||
struct wlr_scene *scene;
|
||||
struct wlr_scene_tree *layers[NUM_LAYERS];
|
||||
struct wlr_scene_tree *drag_icon;
|
||||
/* Map from ZWLR_LAYER_SHELL_* constants to Lyr* enum */
|
||||
const int layermap[] = {LyrBg, LyrBottom, LyrTop, LyrOverlay};
|
||||
struct wlr_renderer *drw;
|
||||
struct wlr_allocator *alloc;
|
||||
struct wlr_compositor *compositor;
|
||||
struct wlr_session *session;
|
||||
|
||||
struct wlr_xdg_shell *xdg_shell;
|
||||
struct wlr_xdg_activation_v1 *activation;
|
||||
struct wlr_xdg_decoration_manager_v1 *xdg_decoration_mgr;
|
||||
struct wl_list clients; /* tiling order */
|
||||
struct wl_list fstack; /* focus order */
|
||||
struct wlr_idle_notifier_v1 *idle_notifier;
|
||||
struct wlr_idle_inhibit_manager_v1 *idle_inhibit_mgr;
|
||||
struct wlr_layer_shell_v1 *layer_shell;
|
||||
struct wlr_output_manager_v1 *output_mgr;
|
||||
struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr;
|
||||
struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr;
|
||||
struct wlr_cursor_shape_manager_v1 *cursor_shape_mgr;
|
||||
struct wlr_output_power_manager_v1 *power_mgr;
|
||||
|
||||
struct wlr_pointer_constraints_v1 *pointer_constraints;
|
||||
struct wlr_relative_pointer_manager_v1 *relative_pointer_mgr;
|
||||
struct wlr_pointer_constraint_v1 *active_constraint;
|
||||
|
||||
struct wlr_cursor *cursor;
|
||||
struct wlr_xcursor_manager *cursor_mgr;
|
||||
|
||||
struct wlr_scene_rect *root_bg;
|
||||
struct wlr_session_lock_manager_v1 *session_lock_mgr;
|
||||
struct wlr_scene_rect *locked_bg;
|
||||
struct wlr_session_lock_v1 *cur_lock;
|
||||
|
||||
struct wlr_seat *seat;
|
||||
unsigned int cursor_mode;
|
||||
Client *grabc;
|
||||
int grabcx, grabcy; /* client-relative */
|
||||
|
||||
struct wlr_output_layout *output_layout;
|
||||
struct wlr_box sgeom;
|
||||
struct wl_list mons;
|
||||
Monitor *selmon;
|
||||
67
src/shared.h
Normal file
67
src/shared.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
#ifndef CRYWL_SHARED_H
|
||||
#define CRYWL_SHARED_H
|
||||
|
||||
enum {
|
||||
LyrBg,
|
||||
LyrBottom,
|
||||
LyrTile,
|
||||
LyrFloat,
|
||||
LyrTop,
|
||||
LyrFS,
|
||||
LyrOverlay,
|
||||
LyrBlock,
|
||||
NUM_LAYERS
|
||||
}; /* scene layers */
|
||||
|
||||
#ifndef IGNORE_EXTERNS
|
||||
/* variables */
|
||||
extern int locked;
|
||||
extern void *exclusive_focus;
|
||||
extern struct wl_event_loop *event_loop;
|
||||
extern struct wlr_backend *backend;
|
||||
extern struct wlr_scene *scene;
|
||||
extern struct wlr_scene_tree *layers[NUM_LAYERS];
|
||||
extern struct wlr_scene_tree *drag_icon;
|
||||
/* Map from ZWLR_LAYER_SHELL_* constants to Lyr* enum */
|
||||
extern const int layermap[];
|
||||
extern struct wlr_renderer *drw;
|
||||
extern struct wlr_allocator *alloc;
|
||||
extern struct wlr_compositor *compositor;
|
||||
extern struct wlr_session *session;
|
||||
|
||||
extern struct wlr_xdg_shell *xdg_shell;
|
||||
extern struct wlr_xdg_activation_v1 *activation;
|
||||
extern struct wlr_xdg_decoration_manager_v1 *xdg_decoration_mgr;
|
||||
extern struct wl_list clients; /* tiling order */
|
||||
extern struct wl_list fstack; /* focus order */
|
||||
extern struct wlr_idle_notifier_v1 *idle_notifier;
|
||||
extern struct wlr_idle_inhibit_manager_v1 *idle_inhibit_mgr;
|
||||
extern struct wlr_layer_shell_v1 *layer_shell;
|
||||
extern struct wlr_output_manager_v1 *output_mgr;
|
||||
extern struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr;
|
||||
extern struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr;
|
||||
extern struct wlr_cursor_shape_manager_v1 *cursor_shape_mgr;
|
||||
extern struct wlr_output_power_manager_v1 *power_mgr;
|
||||
|
||||
extern struct wlr_pointer_constraints_v1 *pointer_constraints;
|
||||
extern struct wlr_relative_pointer_manager_v1 *relative_pointer_mgr;
|
||||
|
||||
extern struct wlr_xcursor_manager *cursor_mgr;
|
||||
|
||||
extern struct wlr_scene_rect *root_bg;
|
||||
extern struct wlr_session_lock_manager_v1 *session_lock_mgr;
|
||||
extern struct wlr_scene_rect *locked_bg;
|
||||
extern struct wlr_session_lock_v1 *cur_lock;
|
||||
|
||||
extern struct wlr_seat *seat;
|
||||
extern unsigned int cursor_mode;
|
||||
extern Client *grabc;
|
||||
extern int grabcx, grabcy; /* client-relative */
|
||||
|
||||
extern struct wlr_output_layout *output_layout;
|
||||
extern struct wlr_box sgeom;
|
||||
extern struct wl_list mons;
|
||||
extern Monitor *selmon;
|
||||
#endif /* IGNORE_EXTERNS */
|
||||
|
||||
#endif /* CRYWL_SHARED_H */
|
||||
63
src/wayland.h
Normal file
63
src/wayland.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
#ifndef CRYWL_WL_LINK
|
||||
#define CRYWL_WL_LINK
|
||||
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/backend.h>
|
||||
#include <wlr/backend/libinput.h>
|
||||
#include <wlr/render/allocator.h>
|
||||
#include <wlr/render/wlr_renderer.h>
|
||||
#include <wlr/types/wlr_alpha_modifier_v1.h>
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_cursor.h>
|
||||
#include <wlr/types/wlr_cursor_shape_v1.h>
|
||||
#include <wlr/types/wlr_data_control_v1.h>
|
||||
#include <wlr/types/wlr_data_device.h>
|
||||
#include <wlr/types/wlr_drm.h>
|
||||
#include <wlr/types/wlr_export_dmabuf_v1.h>
|
||||
#include <wlr/types/wlr_fractional_scale_v1.h>
|
||||
#include <wlr/types/wlr_gamma_control_v1.h>
|
||||
#include <wlr/types/wlr_idle_inhibit_v1.h>
|
||||
#include <wlr/types/wlr_idle_notify_v1.h>
|
||||
#include <wlr/types/wlr_input_device.h>
|
||||
#include <wlr/types/wlr_keyboard.h>
|
||||
#include <wlr/types/wlr_keyboard_group.h>
|
||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||
#include <wlr/types/wlr_linux_dmabuf_v1.h>
|
||||
#include <wlr/types/wlr_linux_drm_syncobj_v1.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_output_management_v1.h>
|
||||
#include <wlr/types/wlr_output_power_management_v1.h>
|
||||
#include <wlr/types/wlr_pointer.h>
|
||||
#include <wlr/types/wlr_pointer_constraints_v1.h>
|
||||
#include <wlr/types/wlr_presentation_time.h>
|
||||
#include <wlr/types/wlr_primary_selection.h>
|
||||
#include <wlr/types/wlr_primary_selection_v1.h>
|
||||
#include <wlr/types/wlr_relative_pointer_v1.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_screencopy_v1.h>
|
||||
#include <wlr/types/wlr_seat.h>
|
||||
#include <wlr/types/wlr_server_decoration.h>
|
||||
#include <wlr/types/wlr_session_lock_v1.h>
|
||||
#include <wlr/types/wlr_single_pixel_buffer_v1.h>
|
||||
#include <wlr/types/wlr_subcompositor.h>
|
||||
#include <wlr/types/wlr_viewporter.h>
|
||||
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
||||
#include <wlr/types/wlr_virtual_pointer_v1.h>
|
||||
#include <wlr/types/wlr_xcursor_manager.h>
|
||||
#include <wlr/types/wlr_xdg_activation_v1.h>
|
||||
#include <wlr/types/wlr_xdg_decoration_v1.h>
|
||||
#include <wlr/types/wlr_xdg_output_v1.h>
|
||||
#include <wlr/types/wlr_xdg_shell.h>
|
||||
#include <wlr/util/log.h>
|
||||
#include <wlr/util/region.h>
|
||||
#include <xkbcommon/xkbcommon.h>
|
||||
|
||||
#ifdef XWAYLAND
|
||||
#include <wlr/xwayland.h>
|
||||
#include <xcb/xcb.h>
|
||||
#include <xcb/xcb_icccm.h>
|
||||
#endif /* XWAYLAND */
|
||||
|
||||
#endif /* CRYWL_WL_LINK */
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue