REFACTOR (wl_listeners isolated)
This commit is contained in:
parent
ab3942d3b5
commit
b92eb285c0
31 changed files with 620 additions and 473 deletions
|
|
@ -1,3 +1,7 @@
|
|||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||
|
||||
|
||||
#include "client.h"
|
||||
|
||||
void applybounds(Client *c, struct wlr_box *bbox) {
|
||||
|
|
@ -225,20 +229,6 @@ void updatetitle(struct wl_listener *listener, void *data) {
|
|||
printstatus();
|
||||
}
|
||||
|
||||
void urgent(struct wl_listener *listener, void *data) {
|
||||
struct wlr_xdg_activation_v1_request_activate_event *event = data;
|
||||
Client *c = NULL;
|
||||
toplevel_from_wlr_surface(event->surface, &c, NULL);
|
||||
if (!c || c == focustop(selmon))
|
||||
return;
|
||||
|
||||
c->isurgent = 1;
|
||||
printstatus();
|
||||
|
||||
if (client_surface(c)->mapped)
|
||||
client_set_border_color(c, urgentcolor);
|
||||
}
|
||||
|
||||
void view(const Arg *arg) {
|
||||
if (!selmon || (arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@
|
|||
#ifndef CRYWL_CLIENT_H
|
||||
#define CRYWL_CLIENT_H
|
||||
|
||||
#include "../wayland.h"
|
||||
#include <wlr/util/box.h>
|
||||
|
||||
#include "../util.h"
|
||||
|
||||
enum { XDGShell, LayerShell, X11 }; /* client types */
|
||||
|
|
@ -61,14 +62,11 @@ 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);
|
||||
|
||||
|
|
|
|||
|
|
@ -305,42 +305,6 @@ void handlesig(int signo) {
|
|||
quit(NULL);
|
||||
}
|
||||
|
||||
void printstatus(void) {
|
||||
Monitor *m = NULL;
|
||||
Client *c;
|
||||
uint32_t occ, urg, sel;
|
||||
|
||||
wl_list_for_each(m, &mons, link) {
|
||||
occ = urg = 0;
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (c->mon != m)
|
||||
continue;
|
||||
occ |= c->tags;
|
||||
if (c->isurgent)
|
||||
urg |= c->tags;
|
||||
}
|
||||
if ((c = focustop(m))) {
|
||||
printf("%s title %s\n", m->wlr_output->name, client_get_title(c));
|
||||
printf("%s appid %s\n", m->wlr_output->name, client_get_appid(c));
|
||||
printf("%s fullscreen %d\n", m->wlr_output->name, c->isfullscreen);
|
||||
printf("%s floating %d\n", m->wlr_output->name, c->isfloating);
|
||||
sel = c->tags;
|
||||
} else {
|
||||
printf("%s title \n", m->wlr_output->name);
|
||||
printf("%s appid \n", m->wlr_output->name);
|
||||
printf("%s fullscreen \n", m->wlr_output->name);
|
||||
printf("%s floating \n", m->wlr_output->name);
|
||||
sel = 0;
|
||||
}
|
||||
|
||||
printf("%s selmon %u\n", m->wlr_output->name, m == selmon);
|
||||
printf("%s tags %" PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32 "\n",
|
||||
m->wlr_output->name, occ, m->tagset[m->seltags], sel, urg);
|
||||
printf("%s layout %s\n", m->wlr_output->name, m->ltsymbol);
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
void run(char *startup_cmd) {
|
||||
/* Add a Unix socket to the Wayland display. */
|
||||
const char *socket = wl_display_add_socket_auto(dpy);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include <stddef.h>
|
||||
|
||||
#include <wlr/types/wlr_cursor.h>
|
||||
|
||||
#include "cursor.h"
|
||||
#include "clientutil.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,10 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include <wlr/types/wlr_compositor.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_idle_notify_v1.h>
|
||||
#include <wlr/types/wlr_idle_inhibit_v1.h>
|
||||
|
||||
void checkidleinhibitor(struct wlr_surface *exclude) {
|
||||
int inhibited = 0, unused_lx, unused_ly;
|
||||
struct wlr_idle_inhibitor_v1 *inhibitor;
|
||||
|
|
@ -17,13 +24,7 @@ void checkidleinhibitor(struct wlr_surface *exclude) {
|
|||
wlr_idle_notifier_v1_set_inhibited(idle_notifier, inhibited);
|
||||
}
|
||||
|
||||
void createidleinhibitor(struct wl_listener *listener, void *data) {
|
||||
struct wlr_idle_inhibitor_v1 *idle_inhibitor = data;
|
||||
LISTEN_STATIC(&idle_inhibitor->events.destroy, destroyidleinhibitor);
|
||||
|
||||
checkidleinhibitor(NULL);
|
||||
}
|
||||
|
||||
/* Helper listener used by `listeners/idle.h:createidleinhibitor` */
|
||||
void destroyidleinhibitor(struct wl_listener *listener, void *data) {
|
||||
/* `data` is the wlr_surface of the idle inhibitor being destroyed,
|
||||
* at this point the idle inhibitor is still in the list of the manager */
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
#ifndef CRYWL_IDLE_H
|
||||
#define CRYWL_IDLE_H
|
||||
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||
|
||||
/* ===== Function Declarations ===== */
|
||||
static void checkidleinhibitor(struct wlr_surface *exclude);
|
||||
static void createidleinhibitor(struct wl_listener *listener, void *data);
|
||||
static void destroyidleinhibitor(struct wl_listener *listener, void *data);
|
||||
void checkidleinhibitor(struct wlr_surface *exclude);
|
||||
void destroyidleinhibitor(struct wl_listener *listener, void *data);
|
||||
|
||||
#endif /* CRYWL_IDLE_H */
|
||||
|
|
|
|||
|
|
@ -65,14 +65,6 @@ void createpointer(struct wlr_pointer *pointer) {
|
|||
wlr_cursor_attach_input_device(cursor, &pointer->base);
|
||||
}
|
||||
|
||||
void createpointerconstraint(struct wl_listener *listener, void *data) {
|
||||
PointerConstraint *pointer_constraint =
|
||||
ecalloc(1, sizeof(*pointer_constraint));
|
||||
pointer_constraint->constraint = data;
|
||||
LISTEN(&pointer_constraint->constraint->events.destroy,
|
||||
&pointer_constraint->destroy, destroypointerconstraint);
|
||||
}
|
||||
|
||||
KeyboardGroup *createkeyboardgroup(void) {
|
||||
KeyboardGroup *group = ecalloc(1, sizeof(*group));
|
||||
struct xkb_context *context;
|
||||
|
|
@ -134,34 +126,6 @@ void destroykeyboardgroup(struct wl_listener *listener, void *data) {
|
|||
free(group);
|
||||
}
|
||||
|
||||
void inputdevice(struct wl_listener *listener, void *data) {
|
||||
/* This event is raised by the backend when a new input device becomes
|
||||
* available. */
|
||||
struct wlr_input_device *device = data;
|
||||
uint32_t caps;
|
||||
|
||||
switch (device->type) {
|
||||
case WLR_INPUT_DEVICE_KEYBOARD:
|
||||
createkeyboard(wlr_keyboard_from_input_device(device));
|
||||
break;
|
||||
case WLR_INPUT_DEVICE_POINTER:
|
||||
createpointer(wlr_pointer_from_input_device(device));
|
||||
break;
|
||||
default:
|
||||
/* TODO handle other input device types */
|
||||
break;
|
||||
}
|
||||
|
||||
/* We need to let the wlr_seat know what our capabilities are, which is
|
||||
* communiciated to the client. In dwl we always have a cursor, even if
|
||||
* there are no pointer devices, so we always include that capability. */
|
||||
/* TODO do we actually require a cursor? */
|
||||
caps = WL_SEAT_CAPABILITY_POINTER;
|
||||
if (!wl_list_empty(&kb_group->wlr_group->devices))
|
||||
caps |= WL_SEAT_CAPABILITY_KEYBOARD;
|
||||
wlr_seat_set_capabilities(seat, caps);
|
||||
}
|
||||
|
||||
int keybinding(uint32_t mods, xkb_keysym_t sym) {
|
||||
/*
|
||||
* Here we handle compositor keybindings. This is when the compositor is
|
||||
|
|
|
|||
|
|
@ -40,18 +40,12 @@ 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 createkeyboard(struct wlr_keyboard *keyboard);
|
||||
static KeyboardGroup *createkeyboardgroup(void);
|
||||
static void createpointer(struct wlr_pointer *pointer);
|
||||
static void createpointerconstraint(struct wl_listener *listener, void *data);
|
||||
static void destroypointerconstraint(struct wl_listener *listener, void *data);
|
||||
static void destroykeyboardgroup(struct wl_listener *listener, void *data);
|
||||
static void inputdevice(struct wl_listener *listener, void *data);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,9 @@
|
|||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||
|
||||
#include "layers.h"
|
||||
#include "notify.h"
|
||||
#include "clientutil.h"
|
||||
|
||||
void commitlayersurfacenotify(struct wl_listener *listener, void *data) {
|
||||
LayerSurface *l = wl_container_of(listener, l, surface_commit);
|
||||
|
|
@ -64,43 +69,6 @@ void destroylayersurfacenotify(struct wl_listener *listener, void *data) {
|
|||
free(l);
|
||||
}
|
||||
|
||||
/* Binds commitlayersurfacenotify, unmaplayersurfacenotify, destroylayersurfacenotify
|
||||
*/
|
||||
void createlayersurface(struct wl_listener *listener, void *data) {
|
||||
struct wlr_layer_surface_v1 *layer_surface = data;
|
||||
LayerSurface *l;
|
||||
struct wlr_surface *surface = layer_surface->surface;
|
||||
struct wlr_scene_tree *scene_layer =
|
||||
layers[layermap[layer_surface->pending.layer]];
|
||||
|
||||
if (!layer_surface->output &&
|
||||
!(layer_surface->output = selmon ? selmon->wlr_output : NULL)) {
|
||||
wlr_layer_surface_v1_destroy(layer_surface);
|
||||
return;
|
||||
}
|
||||
|
||||
l = layer_surface->data = ecalloc(1, sizeof(*l));
|
||||
l->type = LayerShell;
|
||||
LISTEN(&surface->events.commit, &l->surface_commit, commitlayersurfacenotify);
|
||||
LISTEN(&surface->events.unmap, &l->unmap, unmaplayersurfacenotify);
|
||||
LISTEN(&layer_surface->events.destroy, &l->destroy,
|
||||
destroylayersurfacenotify);
|
||||
|
||||
l->layer_surface = layer_surface;
|
||||
l->mon = layer_surface->output->data;
|
||||
l->scene_layer =
|
||||
wlr_scene_layer_surface_v1_create(scene_layer, layer_surface);
|
||||
l->scene = l->scene_layer->tree;
|
||||
l->popups = surface->data = wlr_scene_tree_create(
|
||||
layer_surface->current.layer < ZWLR_LAYER_SHELL_V1_LAYER_TOP
|
||||
? layers[LyrTop]
|
||||
: scene_layer);
|
||||
l->scene->node.data = l->popups->node.data = l;
|
||||
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -24,8 +24,6 @@ typedef struct {
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -1,3 +1,15 @@
|
|||
#include <stdlib.h>
|
||||
|
||||
#include <wlr/types/wlr_output.h>
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
#include <wlr/types/wlr_seat.h>
|
||||
#include <wlr/types/wlr_session_lock_v1.h>
|
||||
|
||||
#include "clientutil.h"
|
||||
#include "lock.h"
|
||||
#include "monitor.h"
|
||||
#include "notify.h"
|
||||
|
||||
void createlocksurface(struct wl_listener *listener, void *data) {
|
||||
SessionLock *lock = wl_container_of(listener, lock, new_surface);
|
||||
struct wlr_session_lock_surface_v1 *lock_surface = data;
|
||||
|
|
@ -61,29 +73,6 @@ void destroysessionlock(struct wl_listener *listener, void *data) {
|
|||
destroylock(lock, 0);
|
||||
}
|
||||
|
||||
void locksession(struct wl_listener *listener, void *data) {
|
||||
struct wlr_session_lock_v1 *session_lock = data;
|
||||
SessionLock *lock;
|
||||
wlr_scene_node_set_enabled(&locked_bg->node, 1);
|
||||
if (cur_lock) {
|
||||
wlr_session_lock_v1_destroy(session_lock);
|
||||
return;
|
||||
}
|
||||
lock = session_lock->data = ecalloc(1, sizeof(*lock));
|
||||
focusclient(NULL, 0);
|
||||
|
||||
lock->scene = wlr_scene_tree_create(layers[LyrBlock]);
|
||||
cur_lock = lock->lock = session_lock;
|
||||
locked = 1;
|
||||
|
||||
LISTEN(&session_lock->events.new_surface, &lock->new_surface,
|
||||
createlocksurface);
|
||||
LISTEN(&session_lock->events.destroy, &lock->destroy, destroysessionlock);
|
||||
LISTEN(&session_lock->events.unlock, &lock->unlock, unlocksession);
|
||||
|
||||
wlr_session_lock_v1_send_locked(session_lock);
|
||||
}
|
||||
|
||||
void unlocksession(struct wl_listener *listener, void *data) {
|
||||
SessionLock *lock = wl_container_of(listener, lock, unlock);
|
||||
destroylock(lock, 1);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef CRYWL_LOCK_H
|
||||
#define CRYWL_LOCK_H
|
||||
|
||||
#include <wayland-server-core.h>
|
||||
|
||||
typedef struct {
|
||||
struct wlr_scene_tree *scene;
|
||||
|
||||
|
|
@ -15,7 +17,6 @@ static void createlocksurface(struct wl_listener *listener, void *data);
|
|||
static void destroylock(SessionLock *lock, int unlocked);
|
||||
static void destroylocksurface(struct wl_listener *listener, void *data);
|
||||
static void destroysessionlock(struct wl_listener *listener, void *data);
|
||||
static void locksession(struct wl_listener *listener, void *data);
|
||||
static void unlocksession(struct wl_listener *listener, void *data);
|
||||
|
||||
#endif /* CRYWL_LOCK_H */
|
||||
|
|
|
|||
44
src/lib/logging.c
Normal file
44
src/lib/logging.c
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include <wayland-server-core.h>
|
||||
#include <wlr/types/wlr_output.h>
|
||||
|
||||
#include "monitor.h"
|
||||
#include "clientutil.h"
|
||||
|
||||
void printstatus(void) {
|
||||
Monitor *m = NULL;
|
||||
Client *c;
|
||||
uint32_t occ, urg, sel;
|
||||
|
||||
wl_list_for_each(m, &mons, link) {
|
||||
occ = urg = 0;
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (c->mon != m)
|
||||
continue;
|
||||
occ |= c->tags;
|
||||
if (c->isurgent)
|
||||
urg |= c->tags;
|
||||
}
|
||||
if ((c = focustop(m))) {
|
||||
printf("%s title %s\n", m->wlr_output->name, client_get_title(c));
|
||||
printf("%s appid %s\n", m->wlr_output->name, client_get_appid(c));
|
||||
printf("%s fullscreen %d\n", m->wlr_output->name, c->isfullscreen);
|
||||
printf("%s floating %d\n", m->wlr_output->name, c->isfloating);
|
||||
sel = c->tags;
|
||||
} else {
|
||||
printf("%s title \n", m->wlr_output->name);
|
||||
printf("%s appid \n", m->wlr_output->name);
|
||||
printf("%s fullscreen \n", m->wlr_output->name);
|
||||
printf("%s floating \n", m->wlr_output->name);
|
||||
sel = 0;
|
||||
}
|
||||
|
||||
printf("%s selmon %u\n", m->wlr_output->name, m == selmon);
|
||||
printf("%s tags %" PRIu32 " %" PRIu32 " %" PRIu32 " %" PRIu32 "\n",
|
||||
m->wlr_output->name, occ, m->tagset[m->seltags], sel, urg);
|
||||
printf("%s layout %s\n", m->wlr_output->name, m->ltsymbol);
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
8
src/lib/logging.h
Normal file
8
src/lib/logging.h
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef CRYWL_LOGGING_H
|
||||
#define CRYWL_LOGGING_H
|
||||
|
||||
/* ===== Functional Declarations ===== */
|
||||
static void printstatus(void);
|
||||
|
||||
#endif /* CRYWL_LOGGING_H */
|
||||
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
void outputmgrapply(struct wl_listener *listener, void *data) {
|
||||
struct wlr_output_configuration_v1 *config = data;
|
||||
outputmgrapplyortest(config, 0);
|
||||
}
|
||||
|
||||
void outputmgrapplyortest(struct wlr_output_configuration_v1 *config,
|
||||
int test) {
|
||||
/*
|
||||
* Called when a client such as wlr-randr requests a change in output
|
||||
* configuration. This is only one way that the layout can be changed,
|
||||
* so any Monitor information should be updated by updatemons() after an
|
||||
* output_layout.change event, not here.
|
||||
*/
|
||||
struct wlr_output_configuration_head_v1 *config_head;
|
||||
int ok = 1;
|
||||
|
||||
wl_list_for_each(config_head, &config->heads, link) {
|
||||
struct wlr_output *wlr_output = config_head->state.output;
|
||||
Monitor *m = wlr_output->data;
|
||||
struct wlr_output_state state;
|
||||
|
||||
/* Ensure displays previously disabled by wlr-output-power-management-v1
|
||||
* are properly handled*/
|
||||
m->asleep = 0;
|
||||
|
||||
wlr_output_state_init(&state);
|
||||
wlr_output_state_set_enabled(&state, config_head->state.enabled);
|
||||
if (!config_head->state.enabled)
|
||||
goto apply_or_test;
|
||||
|
||||
if (config_head->state.mode)
|
||||
wlr_output_state_set_mode(&state, config_head->state.mode);
|
||||
else
|
||||
wlr_output_state_set_custom_mode(&state,
|
||||
config_head->state.custom_mode.width,
|
||||
config_head->state.custom_mode.height,
|
||||
config_head->state.custom_mode.refresh);
|
||||
|
||||
wlr_output_state_set_transform(&state, config_head->state.transform);
|
||||
wlr_output_state_set_scale(&state, config_head->state.scale);
|
||||
wlr_output_state_set_adaptive_sync_enabled(
|
||||
&state, config_head->state.adaptive_sync_enabled);
|
||||
|
||||
apply_or_test:
|
||||
ok &= test ? wlr_output_test_state(wlr_output, &state)
|
||||
: wlr_output_commit_state(wlr_output, &state);
|
||||
|
||||
/* Don't move monitors if position wouldn't change. This avoids
|
||||
* wlroots marking the output as manually configured.
|
||||
* wlr_output_layout_add does not like disabled outputs */
|
||||
if (!test && wlr_output->enabled &&
|
||||
(m->m.x != config_head->state.x || m->m.y != config_head->state.y))
|
||||
wlr_output_layout_add(output_layout, wlr_output, config_head->state.x,
|
||||
config_head->state.y);
|
||||
|
||||
wlr_output_state_finish(&state);
|
||||
}
|
||||
|
||||
if (ok)
|
||||
wlr_output_configuration_v1_send_succeeded(config);
|
||||
else
|
||||
wlr_output_configuration_v1_send_failed(config);
|
||||
wlr_output_configuration_v1_destroy(config);
|
||||
|
||||
/* https://codeberg.org/dwl/dwl/issues/577 */
|
||||
updatemons(NULL, NULL);
|
||||
}
|
||||
|
||||
void outputmgrtest(struct wl_listener *listener, void *data) {
|
||||
struct wlr_output_configuration_v1 *config = data;
|
||||
outputmgrapplyortest(config, 1);
|
||||
}
|
||||
|
||||
void powermgrsetmode(struct wl_listener *listener, void *data) {
|
||||
struct wlr_output_power_v1_set_mode_event *event = data;
|
||||
struct wlr_output_state state = {0};
|
||||
Monitor *m = event->output->data;
|
||||
|
||||
if (!m)
|
||||
return;
|
||||
|
||||
m->gamma_lut_changed = 1; /* Reapply gamma LUT when re-enabling the ouput */
|
||||
wlr_output_state_set_enabled(&state, event->mode);
|
||||
wlr_output_commit_state(m->wlr_output, &state);
|
||||
|
||||
m->asleep = !event->mode;
|
||||
updatemons(NULL, NULL);
|
||||
}
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
#ifndef CRYWL_MGRS_H
|
||||
#define CRYWL_MGRS_H
|
||||
|
||||
/* ===== Function Declarations ===== */
|
||||
static void outputmgrapply(struct wl_listener *listener, void *data);
|
||||
static void outputmgrapplyortest(struct wlr_output_configuration_v1 *config,
|
||||
int test);
|
||||
static void outputmgrtest(struct wl_listener *listener, void *data);
|
||||
static void powermgrsetmode(struct wl_listener *listener, void *data);
|
||||
|
||||
#endif /* CRYWL_MGRS_H */
|
||||
|
|
@ -1,3 +1,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <wlr/types/wlr_scene.h>
|
||||
|
||||
#include "monitor.h"
|
||||
#include "clientutil.h"
|
||||
|
||||
|
|
@ -184,84 +188,6 @@ void closemon(Monitor *m) {
|
|||
printstatus();
|
||||
}
|
||||
|
||||
void createmon(struct wl_listener *listener, void *data) {
|
||||
/* This event is raised by the backend when a new output (aka a display or
|
||||
* monitor) becomes available. */
|
||||
struct wlr_output *wlr_output = data;
|
||||
const MonitorRule *r;
|
||||
size_t i;
|
||||
struct wlr_output_state state;
|
||||
Monitor *m;
|
||||
|
||||
if (!wlr_output_init_render(wlr_output, alloc, drw))
|
||||
return;
|
||||
|
||||
m = wlr_output->data = ecalloc(1, sizeof(*m));
|
||||
m->wlr_output = wlr_output;
|
||||
|
||||
for (i = 0; i < LENGTH(m->layers); i++)
|
||||
wl_list_init(&m->layers[i]);
|
||||
|
||||
wlr_output_state_init(&state);
|
||||
/* Initialize monitor state using configured rules */
|
||||
m->tagset[0] = m->tagset[1] = 1;
|
||||
for (r = monrules; r < END(monrules); r++) {
|
||||
if (!r->name || strstr(wlr_output->name, r->name)) {
|
||||
m->m.x = r->x;
|
||||
m->m.y = r->y;
|
||||
m->mfact = r->mfact;
|
||||
m->nmaster = r->nmaster;
|
||||
m->lt[0] = r->lt;
|
||||
m->lt[1] = &layouts[LENGTH(layouts) > 1 && r->lt != &layouts[1]];
|
||||
strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol));
|
||||
wlr_output_state_set_scale(&state, r->scale);
|
||||
wlr_output_state_set_transform(&state, r->rr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* The mode is a tuple of (width, height, refresh rate), and each
|
||||
* monitor supports only a specific set of modes. We just pick the
|
||||
* monitor's preferred mode; a more sophisticated compositor would let
|
||||
* the user configure it. */
|
||||
wlr_output_state_set_mode(&state, wlr_output_preferred_mode(wlr_output));
|
||||
|
||||
/* Set up event listeners */
|
||||
LISTEN(&wlr_output->events.frame, &m->frame, rendermon);
|
||||
LISTEN(&wlr_output->events.destroy, &m->destroy, cleanupmon);
|
||||
LISTEN(&wlr_output->events.request_state, &m->request_state, requestmonstate);
|
||||
|
||||
wlr_output_state_set_enabled(&state, 1);
|
||||
wlr_output_commit_state(wlr_output, &state);
|
||||
wlr_output_state_finish(&state);
|
||||
|
||||
wl_list_insert(&mons, &m->link);
|
||||
printstatus();
|
||||
|
||||
/* The xdg-protocol specifies:
|
||||
*
|
||||
* If the fullscreened surface is not opaque, the compositor must make
|
||||
* sure that other screen content not part of the same surface tree (made
|
||||
* up of subsurfaces, popups or similarly coupled surfaces) are not
|
||||
* visible below the fullscreened surface.
|
||||
*
|
||||
*/
|
||||
/* updatemons() will resize and set correct position */
|
||||
m->fullscreen_bg = wlr_scene_rect_create(layers[LyrFS], 0, 0, fullscreen_bg);
|
||||
wlr_scene_node_set_enabled(&m->fullscreen_bg->node, 0);
|
||||
|
||||
/* Adds this to the output layout in the order it was configured.
|
||||
*
|
||||
* The output layout utility automatically adds a wl_output global to the
|
||||
* display, which Wayland clients can see to find out information about the
|
||||
* output (such as DPI, scale factor, manufacturer, etc).
|
||||
*/
|
||||
m->scene_output = wlr_scene_output_create(scene, wlr_output);
|
||||
if (m->m.x == -1 && m->m.y == -1)
|
||||
wlr_output_layout_add_auto(output_layout, wlr_output);
|
||||
else
|
||||
wlr_output_layout_add(output_layout, wlr_output, m->m.x, m->m.y);
|
||||
}
|
||||
|
||||
Monitor *dirtomon(enum wlr_direction dir) {
|
||||
struct wlr_output *next;
|
||||
|
|
@ -323,29 +249,6 @@ Client *focustop(Monitor *m) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void gpureset(struct wl_listener *listener, void *data) {
|
||||
struct wlr_renderer *old_drw = drw;
|
||||
struct wlr_allocator *old_alloc = alloc;
|
||||
struct Monitor *m;
|
||||
if (!(drw = wlr_renderer_autocreate(backend)))
|
||||
die("couldn't recreate renderer");
|
||||
|
||||
if (!(alloc = wlr_allocator_autocreate(backend, drw)))
|
||||
die("couldn't recreate allocator");
|
||||
|
||||
wl_list_remove(&gpu_reset.link);
|
||||
wl_signal_add(&drw->events.lost, &gpu_reset);
|
||||
|
||||
wlr_compositor_set_renderer(compositor, drw);
|
||||
|
||||
wl_list_for_each(m, &mons, link) {
|
||||
wlr_output_init_render(m->wlr_output, alloc, drw);
|
||||
}
|
||||
|
||||
wlr_allocator_destroy(old_alloc);
|
||||
wlr_renderer_destroy(old_drw);
|
||||
}
|
||||
|
||||
void incnmaster(const Arg *arg) {
|
||||
if (!arg || !selmon)
|
||||
return;
|
||||
|
|
@ -394,12 +297,6 @@ skip:
|
|||
wlr_output_state_finish(&pending);
|
||||
}
|
||||
|
||||
void requestmonstate(struct wl_listener *listener, void *data) {
|
||||
struct wlr_output_event_request_state *event = data;
|
||||
wlr_output_commit_state(event->output, event->state);
|
||||
updatemons(NULL, NULL);
|
||||
}
|
||||
|
||||
void setlayout(const Arg *arg) {
|
||||
if (!selmon)
|
||||
return;
|
||||
|
|
@ -506,113 +403,6 @@ void tile(Monitor *m) {
|
|||
}
|
||||
}
|
||||
|
||||
void updatemons(struct wl_listener *listener, void *data) {
|
||||
/*
|
||||
* Called whenever the output layout changes: adding or removing a
|
||||
* monitor, changing an output's mode or position, etc. This is where
|
||||
* the change officially happens and we update geometry, window
|
||||
* positions, focus, and the stored configuration in wlroots'
|
||||
* output-manager implementation.
|
||||
*/
|
||||
struct wlr_output_configuration_v1 *config =
|
||||
wlr_output_configuration_v1_create();
|
||||
Client *c;
|
||||
struct wlr_output_configuration_head_v1 *config_head;
|
||||
Monitor *m;
|
||||
|
||||
/* First remove from the layout the disabled monitors */
|
||||
wl_list_for_each(m, &mons, link) {
|
||||
if (m->wlr_output->enabled || m->asleep)
|
||||
continue;
|
||||
config_head =
|
||||
wlr_output_configuration_head_v1_create(config, m->wlr_output);
|
||||
config_head->state.enabled = 0;
|
||||
/* Remove this output from the layout to avoid cursor enter inside it */
|
||||
wlr_output_layout_remove(output_layout, m->wlr_output);
|
||||
closemon(m);
|
||||
m->m = m->w = (struct wlr_box){0};
|
||||
}
|
||||
/* Insert outputs that need to */
|
||||
wl_list_for_each(m, &mons, link) {
|
||||
if (m->wlr_output->enabled &&
|
||||
!wlr_output_layout_get(output_layout, m->wlr_output))
|
||||
wlr_output_layout_add_auto(output_layout, m->wlr_output);
|
||||
}
|
||||
|
||||
/* Now that we update the output layout we can get its box */
|
||||
wlr_output_layout_get_box(output_layout, NULL, &sgeom);
|
||||
|
||||
wlr_scene_node_set_position(&root_bg->node, sgeom.x, sgeom.y);
|
||||
wlr_scene_rect_set_size(root_bg, sgeom.width, sgeom.height);
|
||||
|
||||
/* Make sure the clients are hidden when dwl is locked */
|
||||
wlr_scene_node_set_position(&locked_bg->node, sgeom.x, sgeom.y);
|
||||
wlr_scene_rect_set_size(locked_bg, sgeom.width, sgeom.height);
|
||||
|
||||
wl_list_for_each(m, &mons, link) {
|
||||
if (!m->wlr_output->enabled)
|
||||
continue;
|
||||
config_head =
|
||||
wlr_output_configuration_head_v1_create(config, m->wlr_output);
|
||||
|
||||
/* Get the effective monitor geometry to use for surfaces */
|
||||
wlr_output_layout_get_box(output_layout, m->wlr_output, &m->m);
|
||||
m->w = m->m;
|
||||
wlr_scene_output_set_position(m->scene_output, m->m.x, m->m.y);
|
||||
|
||||
wlr_scene_node_set_position(&m->fullscreen_bg->node, m->m.x, m->m.y);
|
||||
wlr_scene_rect_set_size(m->fullscreen_bg, m->m.width, m->m.height);
|
||||
|
||||
if (m->lock_surface) {
|
||||
struct wlr_scene_tree *scene_tree = m->lock_surface->surface->data;
|
||||
wlr_scene_node_set_position(&scene_tree->node, m->m.x, m->m.y);
|
||||
wlr_session_lock_surface_v1_configure(m->lock_surface, m->m.width,
|
||||
m->m.height);
|
||||
}
|
||||
|
||||
/* Calculate the effective monitor geometry to use for clients */
|
||||
arrangelayers(m);
|
||||
/* Don't move clients to the left output when plugging monitors */
|
||||
arrange(m);
|
||||
/* make sure fullscreen clients have the right size */
|
||||
if ((c = focustop(m)) && c->isfullscreen)
|
||||
resize(c, m->m, 0);
|
||||
|
||||
/* Try to re-set the gamma LUT when updating monitors,
|
||||
* it's only really needed when enabling a disabled output, but meh. */
|
||||
m->gamma_lut_changed = 1;
|
||||
|
||||
config_head->state.x = m->m.x;
|
||||
config_head->state.y = m->m.y;
|
||||
|
||||
if (!selmon) {
|
||||
selmon = m;
|
||||
}
|
||||
}
|
||||
|
||||
if (selmon && selmon->wlr_output->enabled) {
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (!c->mon && client_surface(c)->mapped)
|
||||
setmon(c, selmon, c->tags);
|
||||
}
|
||||
focusclient(focustop(selmon), 1);
|
||||
if (selmon->lock_surface) {
|
||||
client_notify_enter(selmon->lock_surface->surface,
|
||||
wlr_seat_get_keyboard(seat));
|
||||
client_activate_surface(selmon->lock_surface->surface, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: figure out why the cursor image is at 0,0 after turning all
|
||||
* the monitors on.
|
||||
* Move the cursor image where it used to be. It does not generate a
|
||||
* wl_pointer.motion event for the clients, it's only the image what it's
|
||||
* at the wrong position after all. */
|
||||
wlr_cursor_move(cursor, NULL, 0, 0);
|
||||
|
||||
wlr_output_manager_v1_set_configuration(output_mgr, config);
|
||||
}
|
||||
|
||||
Monitor *xytomon(double x, double y) {
|
||||
struct wlr_output *o = wlr_output_layout_output_at(output_layout, x, y);
|
||||
return o ? o->data : NULL;
|
||||
|
|
|
|||
|
|
@ -59,23 +59,19 @@ void arrangelayer(Monitor *m, struct wl_list *list,
|
|||
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 */
|
||||
|
|
|
|||
|
|
@ -29,27 +29,6 @@ void commitnotify(struct wl_listener *listener, void *data) {
|
|||
c->resize = 0;
|
||||
}
|
||||
|
||||
void createnotify(struct wl_listener *listener, void *data) {
|
||||
/* This event is raised when a client creates a new toplevel (application
|
||||
* window). */
|
||||
struct wlr_xdg_toplevel *toplevel = data;
|
||||
Client *c = NULL;
|
||||
|
||||
/* Allocate a Client for this surface */
|
||||
c = toplevel->base->data = ecalloc(1, sizeof(*c));
|
||||
c->surface.xdg = toplevel->base;
|
||||
c->bw = borderpx;
|
||||
|
||||
LISTEN(&toplevel->base->surface->events.commit, &c->commit, commitnotify);
|
||||
LISTEN(&toplevel->base->surface->events.map, &c->map, mapnotify);
|
||||
LISTEN(&toplevel->base->surface->events.unmap, &c->unmap, unmapnotify);
|
||||
LISTEN(&toplevel->events.destroy, &c->destroy, destroynotify);
|
||||
LISTEN(&toplevel->events.request_fullscreen, &c->fullscreen,
|
||||
fullscreennotify);
|
||||
LISTEN(&toplevel->events.request_maximize, &c->maximize, maximizenotify);
|
||||
LISTEN(&toplevel->events.set_title, &c->set_title, updatetitle);
|
||||
}
|
||||
|
||||
void destroynotify(struct wl_listener *listener, void *data) {
|
||||
/* Called when the xdg_toplevel is destroyed. */
|
||||
Client *c = wl_container_of(listener, c, destroy);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
/* ===== Function Declarations ===== */
|
||||
static void commitnotify(struct wl_listener *listener, void *data);
|
||||
static void createnotify(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);
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
void commitpopup(struct wl_listener *listener, void *data) {
|
||||
struct wlr_surface *surface = data;
|
||||
struct wlr_xdg_popup *popup = wlr_xdg_popup_try_from_wlr_surface(surface);
|
||||
LayerSurface *l = NULL;
|
||||
Client *c = NULL;
|
||||
struct wlr_box box;
|
||||
int type = -1;
|
||||
|
||||
if (!popup->base->initial_commit)
|
||||
return;
|
||||
|
||||
type = toplevel_from_wlr_surface(popup->base->surface, &c, &l);
|
||||
if (!popup->parent || type < 0)
|
||||
return;
|
||||
popup->base->surface->data =
|
||||
wlr_scene_xdg_surface_create(popup->parent->data, popup->base);
|
||||
if ((l && !l->mon) || (c && !c->mon)) {
|
||||
wlr_xdg_popup_destroy(popup);
|
||||
return;
|
||||
}
|
||||
box = type == LayerShell ? l->mon->m : c->mon->w;
|
||||
box.x -= (type == LayerShell ? l->scene->node.x : c->geom.x);
|
||||
box.y -= (type == LayerShell ? l->scene->node.y : c->geom.y);
|
||||
wlr_xdg_popup_unconstrain_from_box(popup, &box);
|
||||
wl_list_remove(&listener->link);
|
||||
free(listener);
|
||||
}
|
||||
|
||||
void createpopup(struct wl_listener *listener, void *data) {
|
||||
/* This event is raised when a client (either xdg-shell or layer-shell)
|
||||
* creates a new popup. */
|
||||
struct wlr_xdg_popup *popup = data;
|
||||
LISTEN_STATIC(&popup->base->surface->events.commit, commitpopup);
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
#ifndef CRYWL_POPUP_H
|
||||
#define CRYWL_POPUP_H
|
||||
|
||||
/* ===== Function Declarations ===== */
|
||||
static void commitpopup(struct wl_listener *listener, void *data);
|
||||
static void createpopup(struct wl_listener *listener, void *data);
|
||||
|
||||
#endif /* CRYWL_POPUP_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue