REFACTOR "STASH" (nowhere near working btw)

This commit is contained in:
Emile Clark-Boman 2025-08-28 00:15:29 +10:00
parent 8dfe3b2f25
commit ab3942d3b5
25 changed files with 1021 additions and 845 deletions

View file

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

View file

@ -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
View 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 */

View file

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

View file

@ -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 */

View file

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

View file

@ -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 */

View file

@ -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 */

View file

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

View file

@ -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 */

View file

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

View file

@ -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 */

View file

@ -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 */

View file

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

View file

@ -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 */

View file

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

View file

@ -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 */

View 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 */

View file

@ -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
View 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
View 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*/

View file

@ -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
View 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
View 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
View 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 */