|
|
@@ -126,6 +126,9 @@ typedef struct {
|
|
|
|
struct wl_list flink;
|
|
|
|
struct wl_list flink;
|
|
|
|
struct wlr_box geom; /* layout-relative, includes border */
|
|
|
|
struct wlr_box geom; /* layout-relative, includes border */
|
|
|
|
struct wlr_box prev; /* layout-relative, includes border */
|
|
|
|
struct wlr_box prev; /* layout-relative, includes border */
|
|
|
|
|
|
|
|
struct wlr_box current; /* geom currently shown in the scene graph */
|
|
|
|
|
|
|
|
struct wlr_scene_node *snapshot; /* content shown while resizing */
|
|
|
|
|
|
|
|
uint32_t resize_serial; /* nonzero while waiting for a resized buffer */
|
|
|
|
struct wlr_box bounds; /* only width and height are used */
|
|
|
|
struct wlr_box bounds; /* only width and height are used */
|
|
|
|
union {
|
|
|
|
union {
|
|
|
|
struct wlr_xdg_surface *xdg;
|
|
|
|
struct wlr_xdg_surface *xdg;
|
|
|
@@ -211,6 +214,7 @@ struct Monitor {
|
|
|
|
struct wl_listener frame;
|
|
|
|
struct wl_listener frame;
|
|
|
|
struct wl_listener destroy;
|
|
|
|
struct wl_listener destroy;
|
|
|
|
struct wl_listener request_state;
|
|
|
|
struct wl_listener request_state;
|
|
|
|
|
|
|
|
struct wl_listener commit_lock_surface;
|
|
|
|
struct wl_listener destroy_lock_surface;
|
|
|
|
struct wl_listener destroy_lock_surface;
|
|
|
|
struct wlr_session_lock_surface_v1 *lock_surface;
|
|
|
|
struct wlr_session_lock_surface_v1 *lock_surface;
|
|
|
|
struct wlr_box m; /* monitor area, layout-relative */
|
|
|
|
struct wlr_box m; /* monitor area, layout-relative */
|
|
|
@@ -261,6 +265,7 @@ typedef struct {
|
|
|
|
|
|
|
|
|
|
|
|
/* function declarations */
|
|
|
|
/* function declarations */
|
|
|
|
static void applybounds(Client *c, struct wlr_box *bbox);
|
|
|
|
static void applybounds(Client *c, struct wlr_box *bbox);
|
|
|
|
|
|
|
|
static void applygeom(Client *c);
|
|
|
|
static void applyrules(Client *c);
|
|
|
|
static void applyrules(Client *c);
|
|
|
|
static void arrange(Monitor *m);
|
|
|
|
static void arrange(Monitor *m);
|
|
|
|
static void arrangelayer(Monitor *m, struct wl_list *list,
|
|
|
|
static void arrangelayer(Monitor *m, struct wl_list *list,
|
|
|
@@ -276,6 +281,7 @@ static void cleanupmon(struct wl_listener *listener, void *data);
|
|
|
|
static void cleanuplisteners(void);
|
|
|
|
static void cleanuplisteners(void);
|
|
|
|
static void closemon(Monitor *m);
|
|
|
|
static void closemon(Monitor *m);
|
|
|
|
static void commitlayersurfacenotify(struct wl_listener *listener, void *data);
|
|
|
|
static void commitlayersurfacenotify(struct wl_listener *listener, void *data);
|
|
|
|
|
|
|
|
static void commitlocksurface(struct wl_listener *listener, void *data);
|
|
|
|
static void commitnotify(struct wl_listener *listener, void *data);
|
|
|
|
static void commitnotify(struct wl_listener *listener, void *data);
|
|
|
|
static void commitpopup(struct wl_listener *listener, void *data);
|
|
|
|
static void commitpopup(struct wl_listener *listener, void *data);
|
|
|
|
static void createdecoration(struct wl_listener *listener, void *data);
|
|
|
|
static void createdecoration(struct wl_listener *listener, void *data);
|
|
|
@@ -303,7 +309,7 @@ static void destroypointerconstraint(struct wl_listener *listener, void *data);
|
|
|
|
static void destroysessionlock(struct wl_listener *listener, void *data);
|
|
|
|
static void destroysessionlock(struct wl_listener *listener, void *data);
|
|
|
|
static void destroykeyboardgroup(struct wl_listener *listener, void *data);
|
|
|
|
static void destroykeyboardgroup(struct wl_listener *listener, void *data);
|
|
|
|
static Monitor *dirtomon(enum wlr_direction dir);
|
|
|
|
static Monitor *dirtomon(enum wlr_direction dir);
|
|
|
|
static void focusclient(Client *c, int lift);
|
|
|
|
static void focusclient(Client *c, LayerSurface *l, int lift);
|
|
|
|
static void focusmon(const Arg *arg);
|
|
|
|
static void focusmon(const Arg *arg);
|
|
|
|
static void focusstack(const Arg *arg);
|
|
|
|
static void focusstack(const Arg *arg);
|
|
|
|
static Client *focustop(Monitor *m);
|
|
|
|
static Client *focustop(Monitor *m);
|
|
|
@@ -350,6 +356,8 @@ static void setmon(Client *c, Monitor *m, uint32_t newtags);
|
|
|
|
static void setpsel(struct wl_listener *listener, void *data);
|
|
|
|
static void setpsel(struct wl_listener *listener, void *data);
|
|
|
|
static void setsel(struct wl_listener *listener, void *data);
|
|
|
|
static void setsel(struct wl_listener *listener, void *data);
|
|
|
|
static void setup(void);
|
|
|
|
static void setup(void);
|
|
|
|
|
|
|
|
static struct wlr_scene_node *snapshot(struct wlr_scene_node *node,
|
|
|
|
|
|
|
|
struct wlr_scene_tree *parent, void *data);
|
|
|
|
static void spawn(const Arg *arg);
|
|
|
|
static void spawn(const Arg *arg);
|
|
|
|
static void startdrag(struct wl_listener *listener, void *data);
|
|
|
|
static void startdrag(struct wl_listener *listener, void *data);
|
|
|
|
static void tag(const Arg *arg);
|
|
|
|
static void tag(const Arg *arg);
|
|
|
@@ -359,6 +367,11 @@ static void togglefloating(const Arg *arg);
|
|
|
|
static void togglefullscreen(const Arg *arg);
|
|
|
|
static void togglefullscreen(const Arg *arg);
|
|
|
|
static void toggletag(const Arg *arg);
|
|
|
|
static void toggletag(const Arg *arg);
|
|
|
|
static void toggleview(const Arg *arg);
|
|
|
|
static void toggleview(const Arg *arg);
|
|
|
|
|
|
|
|
static void transactionapply(void);
|
|
|
|
|
|
|
|
static void transactioncheck(void *data);
|
|
|
|
|
|
|
|
static void transactioncommit(Client *c, int ready);
|
|
|
|
|
|
|
|
static void transactionschedule(void);
|
|
|
|
|
|
|
|
static int transactiontimeout(void *data);
|
|
|
|
static void unlocksession(struct wl_listener *listener, void *data);
|
|
|
|
static void unlocksession(struct wl_listener *listener, void *data);
|
|
|
|
static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);
|
|
|
|
static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);
|
|
|
|
static void unmapnotify(struct wl_listener *listener, void *data);
|
|
|
|
static void unmapnotify(struct wl_listener *listener, void *data);
|
|
|
@@ -376,7 +389,6 @@ static void zoom(const Arg *arg);
|
|
|
|
/* variables */
|
|
|
|
/* variables */
|
|
|
|
static pid_t child_pid = -1;
|
|
|
|
static pid_t child_pid = -1;
|
|
|
|
static int locked;
|
|
|
|
static int locked;
|
|
|
|
static void *exclusive_focus;
|
|
|
|
|
|
|
|
static Client *focused_client;
|
|
|
|
static Client *focused_client;
|
|
|
|
static struct wl_display *dpy;
|
|
|
|
static struct wl_display *dpy;
|
|
|
|
static struct wl_event_loop *event_loop;
|
|
|
|
static struct wl_event_loop *event_loop;
|
|
|
@@ -431,6 +443,14 @@ static struct wl_list mons;
|
|
|
|
static Monitor *selmon;
|
|
|
|
static Monitor *selmon;
|
|
|
|
static int consumed[KEY_MAX + 1];
|
|
|
|
static int consumed[KEY_MAX + 1];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Transactions: the scene graph is updated only once all visible clients have
|
|
|
|
|
|
|
|
* committed buffers with their new size, or after TRANSACTION_TIMEOUT ms */
|
|
|
|
|
|
|
|
#define TRANSACTION_TIMEOUT 100
|
|
|
|
|
|
|
|
static struct wl_event_source *transaction_idle;
|
|
|
|
|
|
|
|
static struct wl_event_source *transaction_timer;
|
|
|
|
|
|
|
|
static int transaction_waiting;
|
|
|
|
|
|
|
|
static struct wl_array ghosts; /* struct wlr_scene_node *, unmapped clients */
|
|
|
|
|
|
|
|
|
|
|
|
/* global event handlers */
|
|
|
|
/* global event handlers */
|
|
|
|
static struct wl_listener cursor_axis = {.notify = axisnotify};
|
|
|
|
static struct wl_listener cursor_axis = {.notify = axisnotify};
|
|
|
|
static struct wl_listener cursor_button = {.notify = buttonpress};
|
|
|
|
static struct wl_listener cursor_button = {.notify = buttonpress};
|
|
|
@@ -465,6 +485,7 @@ static struct wl_listener new_foreign_toplevel_capture_request = {.notify = capt
|
|
|
|
#ifdef XWAYLAND
|
|
|
|
#ifdef XWAYLAND
|
|
|
|
static void activatex11(struct wl_listener *listener, void *data);
|
|
|
|
static void activatex11(struct wl_listener *listener, void *data);
|
|
|
|
static void associatex11(struct wl_listener *listener, void *data);
|
|
|
|
static void associatex11(struct wl_listener *listener, void *data);
|
|
|
|
|
|
|
|
static void commitx11(struct wl_listener *listener, void *data);
|
|
|
|
static void configurex11(struct wl_listener *listener, void *data);
|
|
|
|
static void configurex11(struct wl_listener *listener, void *data);
|
|
|
|
static void createnotifyx11(struct wl_listener *listener, void *data);
|
|
|
|
static void createnotifyx11(struct wl_listener *listener, void *data);
|
|
|
|
static void dissociatex11(struct wl_listener *listener, void *data);
|
|
|
|
static void dissociatex11(struct wl_listener *listener, void *data);
|
|
|
@@ -515,6 +536,41 @@ applybounds(Client *c, struct wlr_box *bbox)
|
|
|
|
c->geom.y = bbox->y;
|
|
|
|
c->geom.y = bbox->y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
|
|
applygeom(Client *c)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
struct wlr_box clip;
|
|
|
|
|
|
|
|
Client *p = client_get_parent(c);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* We move all floating clients to LyrTile while in floating layout
|
|
|
|
|
|
|
|
* to avoid "real" floating clients be always on top */
|
|
|
|
|
|
|
|
wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen
|
|
|
|
|
|
|
|
|| (p && p->isfullscreen) ? LyrFS
|
|
|
|
|
|
|
|
: c->isfloating && c->mon->lt[c->mon->sellt]->arrange ? LyrFloat
|
|
|
|
|
|
|
|
: LyrTile]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
c->current = c->geom;
|
|
|
|
|
|
|
|
if (c->snapshot) {
|
|
|
|
|
|
|
|
wlr_scene_node_destroy(c->snapshot);
|
|
|
|
|
|
|
|
c->snapshot = NULL;
|
|
|
|
|
|
|
|
wlr_scene_node_set_enabled(&c->scene_surface->node, 1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Update scene-graph, including borders */
|
|
|
|
|
|
|
|
wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y);
|
|
|
|
|
|
|
|
wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw);
|
|
|
|
|
|
|
|
wlr_scene_rect_set_size(c->border[0], c->geom.width, c->bw);
|
|
|
|
|
|
|
|
wlr_scene_rect_set_size(c->border[1], c->geom.width, c->bw);
|
|
|
|
|
|
|
|
wlr_scene_rect_set_size(c->border[2], c->bw, c->geom.height - 2 * c->bw);
|
|
|
|
|
|
|
|
wlr_scene_rect_set_size(c->border[3], c->bw, c->geom.height - 2 * c->bw);
|
|
|
|
|
|
|
|
wlr_scene_node_set_position(&c->border[1]->node, 0, c->geom.height - c->bw);
|
|
|
|
|
|
|
|
wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw);
|
|
|
|
|
|
|
|
wlr_scene_node_set_position(&c->border[3]->node, c->geom.width - c->bw, c->bw);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
client_get_clip(c, &clip);
|
|
|
|
|
|
|
|
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
applyrules(Client *c)
|
|
|
|
applyrules(Client *c)
|
|
|
|
{
|
|
|
|
{
|
|
|
@@ -554,37 +610,18 @@ arrange(Monitor *m)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
wl_list_for_each(c, &clients, link) {
|
|
|
|
wl_list_for_each(c, &clients, link) {
|
|
|
|
if (c->mon == m) {
|
|
|
|
if (c->mon == m)
|
|
|
|
wlr_scene_node_set_enabled(&c->scene->node, VISIBLEON(c, m));
|
|
|
|
|
|
|
|
client_set_suspended(c, !VISIBLEON(c, m)
|
|
|
|
client_set_suspended(c, !VISIBLEON(c, m)
|
|
|
|
&& (!c->image_capture_source
|
|
|
|
&& (!c->image_capture_source
|
|
|
|
|| wl_list_empty(&c->image_capture_source->resources)));
|
|
|
|
|| wl_list_empty(&c->image_capture_source->resources)));
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
wlr_scene_node_set_enabled(&m->fullscreen_bg->node,
|
|
|
|
|
|
|
|
(c = focustop(m)) && c->isfullscreen);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol));
|
|
|
|
strncpy(m->ltsymbol, m->lt[m->sellt]->symbol, LENGTH(m->ltsymbol));
|
|
|
|
|
|
|
|
|
|
|
|
/* We move all clients (except fullscreen and unmanaged) to LyrTile while
|
|
|
|
|
|
|
|
* in floating layout to avoid "real" floating clients be always on top */
|
|
|
|
|
|
|
|
wl_list_for_each(c, &clients, link) {
|
|
|
|
|
|
|
|
if (c->mon != m || c->scene->node.parent == layers[LyrFS])
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wlr_scene_node_reparent(&c->scene->node,
|
|
|
|
|
|
|
|
(!m->lt[m->sellt]->arrange && c->isfloating)
|
|
|
|
|
|
|
|
? layers[LyrTile]
|
|
|
|
|
|
|
|
: (m->lt[m->sellt]->arrange && c->isfloating)
|
|
|
|
|
|
|
|
? layers[LyrFloat]
|
|
|
|
|
|
|
|
: c->scene->node.parent);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (m->lt[m->sellt]->arrange)
|
|
|
|
if (m->lt[m->sellt]->arrange)
|
|
|
|
m->lt[m->sellt]->arrange(m);
|
|
|
|
m->lt[m->sellt]->arrange(m);
|
|
|
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
|
|
|
|
|
|
|
checkidleinhibitor(NULL);
|
|
|
|
transactionschedule();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
@@ -641,10 +678,7 @@ arrangelayers(Monitor *m)
|
|
|
|
l->layer_surface->current.keyboard_interactive != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE ||
|
|
|
|
l->layer_surface->current.keyboard_interactive != ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE ||
|
|
|
|
!l->mapped)
|
|
|
|
!l->mapped)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
/* Deactivate the focused client. */
|
|
|
|
focusclient(NULL, l, 0);
|
|
|
|
focusclient(NULL, 0);
|
|
|
|
|
|
|
|
exclusive_focus = l;
|
|
|
|
|
|
|
|
client_notify_enter(l->layer_surface->surface, wlr_seat_get_keyboard(seat));
|
|
|
|
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -663,16 +697,18 @@ axisnotify(struct wl_listener *listener, void *data)
|
|
|
|
|
|
|
|
|
|
|
|
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
|
|
|
wlr_idle_notifier_v1_notify_activity(idle_notifier, seat);
|
|
|
|
|
|
|
|
|
|
|
|
if (event->orientation == WL_POINTER_AXIS_VERTICAL_SCROLL)
|
|
|
|
if (!locked) {
|
|
|
|
adir = event->delta > 0 ? AxisDown : AxisUp;
|
|
|
|
if (event->orientation == WL_POINTER_AXIS_VERTICAL_SCROLL)
|
|
|
|
else
|
|
|
|
adir = event->delta > 0 ? AxisDown : AxisUp;
|
|
|
|
adir = event->delta > 0 ? AxisRight : AxisLeft;
|
|
|
|
else
|
|
|
|
keyboard = wlr_seat_get_keyboard(seat);
|
|
|
|
adir = event->delta > 0 ? AxisRight : AxisLeft;
|
|
|
|
mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
|
|
|
|
keyboard = wlr_seat_get_keyboard(seat);
|
|
|
|
for (a = axes; a < END(axes); a++) {
|
|
|
|
mods = keyboard ? wlr_keyboard_get_modifiers(keyboard) : 0;
|
|
|
|
if (CLEANMASK(mods) == CLEANMASK(a->mod) && adir == a->dir && a->func) {
|
|
|
|
for (a = axes; a < END(axes); a++) {
|
|
|
|
a->func(&a->arg);
|
|
|
|
if (CLEANMASK(mods) == CLEANMASK(a->mod) && adir == a->dir && a->func) {
|
|
|
|
return;
|
|
|
|
a->func(&a->arg);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -705,10 +741,9 @@ buttonpress(struct wl_listener *listener, void *data)
|
|
|
|
or a layer surface with on-demand keyboard interactivity */
|
|
|
|
or a layer surface with on-demand keyboard interactivity */
|
|
|
|
xytonode(cursor->x, cursor->y, NULL, &c, &l, NULL, NULL);
|
|
|
|
xytonode(cursor->x, cursor->y, NULL, &c, &l, NULL, NULL);
|
|
|
|
if (c && (!client_is_unmanaged(c) || client_wants_focus(c))) {
|
|
|
|
if (c && (!client_is_unmanaged(c) || client_wants_focus(c))) {
|
|
|
|
focusclient(c, 1);
|
|
|
|
focusclient(c, NULL, 1);
|
|
|
|
} else if (l && l->layer_surface->current.keyboard_interactive) {
|
|
|
|
} else if (l && l->layer_surface->current.keyboard_interactive) {
|
|
|
|
focusclient(NULL, 0);
|
|
|
|
focusclient(NULL, l, 0);
|
|
|
|
client_notify_enter(l->layer_surface->surface, wlr_seat_get_keyboard(seat));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
keyboard = wlr_seat_get_keyboard(seat);
|
|
|
|
keyboard = wlr_seat_get_keyboard(seat);
|
|
|
@@ -810,6 +845,11 @@ cleanup(void)
|
|
|
|
* Destroy it until it's fixed on the wlroots side */
|
|
|
|
* Destroy it until it's fixed on the wlroots side */
|
|
|
|
wlr_backend_destroy(backend);
|
|
|
|
wlr_backend_destroy(backend);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (transaction_idle)
|
|
|
|
|
|
|
|
wl_event_source_remove(transaction_idle);
|
|
|
|
|
|
|
|
wl_event_source_remove(transaction_timer);
|
|
|
|
|
|
|
|
wl_array_release(&ghosts);
|
|
|
|
|
|
|
|
|
|
|
|
wl_display_destroy(dpy);
|
|
|
|
wl_display_destroy(dpy);
|
|
|
|
/* Destroy after the wayland display (when the monitors are already destroyed)
|
|
|
|
/* Destroy after the wayland display (when the monitors are already destroyed)
|
|
|
|
to avoid destroying them with an invalid scene output. */
|
|
|
|
to avoid destroying them with an invalid scene output. */
|
|
|
@@ -877,8 +917,10 @@ cleanuplisteners(void)
|
|
|
|
wl_list_remove(&new_session_lock.link);
|
|
|
|
wl_list_remove(&new_session_lock.link);
|
|
|
|
wl_list_remove(&new_foreign_toplevel_capture_request.link);
|
|
|
|
wl_list_remove(&new_foreign_toplevel_capture_request.link);
|
|
|
|
#ifdef XWAYLAND
|
|
|
|
#ifdef XWAYLAND
|
|
|
|
wl_list_remove(&new_xwayland_surface.link);
|
|
|
|
if (xwayland) {
|
|
|
|
wl_list_remove(&xwayland_ready.link);
|
|
|
|
wl_list_remove(&new_xwayland_surface.link);
|
|
|
|
|
|
|
|
wl_list_remove(&xwayland_ready.link);
|
|
|
|
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -907,7 +949,7 @@ closemon(Monitor *m)
|
|
|
|
if (c->mon == m)
|
|
|
|
if (c->mon == m)
|
|
|
|
setmon(c, selmon, c->tags);
|
|
|
|
setmon(c, selmon, c->tags);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
focusclient(focustop(selmon), 1);
|
|
|
|
focusclient(focustop(selmon), NULL, 1);
|
|
|
|
printstatus();
|
|
|
|
printstatus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -931,11 +973,6 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (layer_surface == exclusive_focus
|
|
|
|
|
|
|
|
&& layer_surface->current.keyboard_interactive !=
|
|
|
|
|
|
|
|
ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)
|
|
|
|
|
|
|
|
exclusive_focus = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (layer_surface->current.committed == 0 && l->mapped == layer_surface->surface->mapped)
|
|
|
|
if (layer_surface->current.committed == 0 && l->mapped == layer_surface->surface->mapped)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
l->mapped = layer_surface->surface->mapped;
|
|
|
|
l->mapped = layer_surface->surface->mapped;
|
|
|
@@ -951,6 +988,20 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data)
|
|
|
|
arrangelayers(l->mon);
|
|
|
|
arrangelayers(l->mon);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
|
|
commitlocksurface(struct wl_listener *listener, void *data)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Monitor *m = wl_container_of(listener, m, commit_lock_surface);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!m->lock_surface->surface->mapped)
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wl_list_remove(&m->commit_lock_surface.link);
|
|
|
|
|
|
|
|
wl_list_init(&m->commit_lock_surface.link);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
commitnotify(struct wl_listener *listener, void *data)
|
|
|
|
commitnotify(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
{
|
|
|
@@ -980,6 +1031,8 @@ commitnotify(struct wl_listener *listener, void *data)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
transactioncommit(c, c->resize_serial && c->surface.xdg->current.configure_serial
|
|
|
|
|
|
|
|
>= c->resize_serial);
|
|
|
|
resize(c, c->geom, (c->isfloating && !c->isfullscreen));
|
|
|
|
resize(c, c->geom, (c->isfloating && !c->isfullscreen));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -1006,8 +1059,8 @@ commitpopup(struct wl_listener *listener, void *data)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
box = type == LayerShell ? l->mon->m : c->mon->w;
|
|
|
|
box = type == LayerShell ? l->mon->m : c->mon->w;
|
|
|
|
box.x -= (type == LayerShell ? l->scene->node.x : c->geom.x);
|
|
|
|
box.x -= (type == LayerShell ? l->scene->node.x : c->geom.x - c->surface.xdg->geometry.x);
|
|
|
|
box.y -= (type == LayerShell ? l->scene->node.y : c->geom.y);
|
|
|
|
box.y -= (type == LayerShell ? l->scene->node.y : c->geom.y - c->surface.xdg->geometry.y);
|
|
|
|
wlr_xdg_popup_unconstrain_from_box(popup, &box);
|
|
|
|
wlr_xdg_popup_unconstrain_from_box(popup, &box);
|
|
|
|
wl_list_remove(&listener->link);
|
|
|
|
wl_list_remove(&listener->link);
|
|
|
|
free(listener);
|
|
|
|
free(listener);
|
|
|
@@ -1128,6 +1181,7 @@ createlocksurface(struct wl_listener *listener, void *data)
|
|
|
|
wlr_session_lock_surface_v1_configure(lock_surface, m->m.width, m->m.height);
|
|
|
|
wlr_session_lock_surface_v1_configure(lock_surface, m->m.width, m->m.height);
|
|
|
|
|
|
|
|
|
|
|
|
LISTEN(&lock_surface->events.destroy, &m->destroy_lock_surface, destroylocksurface);
|
|
|
|
LISTEN(&lock_surface->events.destroy, &m->destroy_lock_surface, destroylocksurface);
|
|
|
|
|
|
|
|
LISTEN(&lock_surface->surface->events.commit, &m->commit_lock_surface, commitlocksurface);
|
|
|
|
|
|
|
|
|
|
|
|
if (m == selmon)
|
|
|
|
if (m == selmon)
|
|
|
|
client_notify_enter(lock_surface->surface, wlr_seat_get_keyboard(seat));
|
|
|
|
client_notify_enter(lock_surface->surface, wlr_seat_get_keyboard(seat));
|
|
|
@@ -1349,7 +1403,7 @@ void
|
|
|
|
destroydragicon(struct wl_listener *listener, void *data)
|
|
|
|
destroydragicon(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* Focus enter isn't sent during drag, so refocus the focused node. */
|
|
|
|
/* Focus enter isn't sent during drag, so refocus the focused node. */
|
|
|
|
focusclient(focustop(selmon), 1);
|
|
|
|
focusclient(focustop(selmon), NULL, 1);
|
|
|
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
|
|
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
|
|
|
wl_list_remove(&listener->link);
|
|
|
|
wl_list_remove(&listener->link);
|
|
|
|
free(listener);
|
|
|
|
free(listener);
|
|
|
@@ -1388,7 +1442,7 @@ destroylock(SessionLock *lock, int unlock)
|
|
|
|
|
|
|
|
|
|
|
|
wlr_scene_node_set_enabled(&locked_bg->node, 0);
|
|
|
|
wlr_scene_node_set_enabled(&locked_bg->node, 0);
|
|
|
|
|
|
|
|
|
|
|
|
focusclient(focustop(selmon), 0);
|
|
|
|
focusclient(focustop(selmon), NULL, 0);
|
|
|
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
|
|
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
|
|
destroy:
|
|
|
|
destroy:
|
|
|
@@ -1409,6 +1463,7 @@ destroylocksurface(struct wl_listener *listener, void *data)
|
|
|
|
|
|
|
|
|
|
|
|
m->lock_surface = NULL;
|
|
|
|
m->lock_surface = NULL;
|
|
|
|
wl_list_remove(&m->destroy_lock_surface.link);
|
|
|
|
wl_list_remove(&m->destroy_lock_surface.link);
|
|
|
|
|
|
|
|
wl_list_remove(&m->commit_lock_surface.link);
|
|
|
|
|
|
|
|
|
|
|
|
if (lock_surface->surface != seat->keyboard_state.focused_surface)
|
|
|
|
if (lock_surface->surface != seat->keyboard_state.focused_surface)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
@@ -1417,7 +1472,7 @@ destroylocksurface(struct wl_listener *listener, void *data)
|
|
|
|
surface = wl_container_of(cur_lock->surfaces.next, surface, link);
|
|
|
|
surface = wl_container_of(cur_lock->surfaces.next, surface, link);
|
|
|
|
client_notify_enter(surface->surface, wlr_seat_get_keyboard(seat));
|
|
|
|
client_notify_enter(surface->surface, wlr_seat_get_keyboard(seat));
|
|
|
|
} else if (!locked) {
|
|
|
|
} else if (!locked) {
|
|
|
|
focusclient(focustop(selmon), 1);
|
|
|
|
focusclient(focustop(selmon), NULL, 1);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
wlr_seat_keyboard_clear_focus(seat);
|
|
|
|
wlr_seat_keyboard_clear_focus(seat);
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -1505,9 +1560,9 @@ dirtomon(enum wlr_direction dir)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
focusclient(Client *c, int lift)
|
|
|
|
focusclient(Client *c, LayerSurface *l, int lift)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
struct wlr_surface *old = seat->keyboard_state.focused_surface;
|
|
|
|
struct wlr_surface *surface, *old = seat->keyboard_state.focused_surface;
|
|
|
|
int unused_lx, unused_ly, old_client_type;
|
|
|
|
int unused_lx, unused_ly, old_client_type;
|
|
|
|
Client *old_c = NULL;
|
|
|
|
Client *old_c = NULL;
|
|
|
|
LayerSurface *old_l = NULL;
|
|
|
|
LayerSurface *old_l = NULL;
|
|
|
@@ -1528,9 +1583,6 @@ focusclient(Client *c, int lift)
|
|
|
|
wlr_xdg_popup_destroy(popup);
|
|
|
|
wlr_xdg_popup_destroy(popup);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (old_c && old_c == exclusive_focus && client_wants_focus(old_c))
|
|
|
|
|
|
|
|
exclusive_focus = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Put the new client atop the focus stack and select its monitor */
|
|
|
|
/* Put the new client atop the focus stack and select its monitor */
|
|
|
|
if (c && !client_is_unmanaged(c)) {
|
|
|
|
if (c && !client_is_unmanaged(c)) {
|
|
|
|
wl_list_remove(&c->flink);
|
|
|
|
wl_list_remove(&c->flink);
|
|
|
@@ -1540,14 +1592,16 @@ focusclient(Client *c, int lift)
|
|
|
|
|
|
|
|
|
|
|
|
/* Don't change border color if there is an exclusive focus or we are
|
|
|
|
/* Don't change border color if there is an exclusive focus or we are
|
|
|
|
* handling a drag operation */
|
|
|
|
* handling a drag operation */
|
|
|
|
if (!exclusive_focus && !seat->drag)
|
|
|
|
if (!(old_l && old_l->layer_surface->current.keyboard_interactive == ZWLR_LAYER_SURFACE_V1_KEYBOARD_INTERACTIVITY_EXCLUSIVE)
|
|
|
|
|
|
|
|
&& !(old_c && client_wants_focus(old_c))
|
|
|
|
|
|
|
|
&& !seat->drag)
|
|
|
|
client_set_border_color(c, focuscolor);
|
|
|
|
client_set_border_color(c, focuscolor);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* If an overlay is focused, don't focus or activate the client,
|
|
|
|
/* If an overlay is focused, don't focus or activate the client,
|
|
|
|
* but only update its position in fstack to render its border with focuscolor
|
|
|
|
* but only update its position in fstack to render its border with focuscolor
|
|
|
|
* and focus it after the overlay is closed. */
|
|
|
|
* and focus it after the overlay is closed. */
|
|
|
|
if (old && (!c || client_surface(c) != old)
|
|
|
|
if (!l && old && (!c || client_surface(c) != old)
|
|
|
|
&& old_client_type == LayerShell && wlr_scene_node_coords(
|
|
|
|
&& old_client_type == LayerShell && wlr_scene_node_coords(
|
|
|
|
&old_l->scene->node, &unused_lx, &unused_ly)
|
|
|
|
&old_l->scene->node, &unused_lx, &unused_ly)
|
|
|
|
&& old_l->layer_surface->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP
|
|
|
|
&& old_l->layer_surface->current.layer >= ZWLR_LAYER_SHELL_V1_LAYER_TOP
|
|
|
@@ -1564,24 +1618,23 @@ focusclient(Client *c, int lift)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
printstatus();
|
|
|
|
printstatus();
|
|
|
|
|
|
|
|
|
|
|
|
if (!c) {
|
|
|
|
if (!c && !l) {
|
|
|
|
/* With no client, all we have left is to clear focus */
|
|
|
|
/* With no client, all we have left is to clear focus */
|
|
|
|
input_method_relay_set_focus(input_method_relay, NULL);
|
|
|
|
input_method_relay_set_focus(input_method_relay, NULL);
|
|
|
|
wlr_seat_keyboard_notify_clear_focus(seat);
|
|
|
|
wlr_seat_keyboard_notify_clear_focus(seat);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Change cursor surface */
|
|
|
|
surface = c ? client_surface(c) : l->layer_surface->surface;
|
|
|
|
|
|
|
|
input_method_relay_set_focus(input_method_relay, surface);
|
|
|
|
|
|
|
|
client_notify_enter(surface, wlr_seat_get_keyboard(seat));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (l)
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
client_activate_surface(surface, 1);
|
|
|
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
|
|
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
|
|
input_method_relay_set_focus(input_method_relay, client_surface(c));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Have a client, so focus its top-level wlr_surface */
|
|
|
|
|
|
|
|
client_notify_enter(client_surface(c), wlr_seat_get_keyboard(seat));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Activate the new client */
|
|
|
|
|
|
|
|
client_activate_surface(client_surface(c), 1);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!client_is_unmanaged(c))
|
|
|
|
if (!client_is_unmanaged(c))
|
|
|
|
focused_client = c;
|
|
|
|
focused_client = c;
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -1595,7 +1648,7 @@ focusmon(const Arg *arg)
|
|
|
|
selmon = dirtomon(arg->i);
|
|
|
|
selmon = dirtomon(arg->i);
|
|
|
|
while (!selmon->wlr_output->enabled && i++ < nmons);
|
|
|
|
while (!selmon->wlr_output->enabled && i++ < nmons);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
focusclient(focustop(selmon), 1);
|
|
|
|
focusclient(focustop(selmon), NULL, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
@@ -1621,7 +1674,7 @@ focusstack(const Arg *arg)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* If only one client is visible on selmon, then c == sel */
|
|
|
|
/* If only one client is visible on selmon, then c == sel */
|
|
|
|
focusclient(c, 1);
|
|
|
|
focusclient(c, NULL, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* We probably should change the name of this: it sounds like it
|
|
|
|
/* We probably should change the name of this: it sounds like it
|
|
|
@@ -1810,7 +1863,7 @@ int
|
|
|
|
keyrepeat(void *data)
|
|
|
|
keyrepeat(void *data)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
KeyboardGroup *group = data;
|
|
|
|
KeyboardGroup *group = data;
|
|
|
|
if (group->wlr_group->keyboard.repeat_info.rate <= 0)
|
|
|
|
if (locked || group->wlr_group->keyboard.repeat_info.rate <= 0)
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
|
|
wl_event_source_timer_update(group->key_repeat_source,
|
|
|
|
wl_event_source_timer_update(group->key_repeat_source,
|
|
|
@@ -1846,12 +1899,18 @@ locksession(struct wl_listener *listener, void *data)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
lock = session_lock->data = ecalloc(1, sizeof(*lock));
|
|
|
|
lock = session_lock->data = ecalloc(1, sizeof(*lock));
|
|
|
|
focusclient(NULL, 0);
|
|
|
|
focusclient(NULL, NULL, 0);
|
|
|
|
|
|
|
|
|
|
|
|
lock->scene = wlr_scene_tree_create(layers[LyrBlock]);
|
|
|
|
lock->scene = wlr_scene_tree_create(layers[LyrBlock]);
|
|
|
|
cur_lock = lock->lock = session_lock;
|
|
|
|
cur_lock = lock->lock = session_lock;
|
|
|
|
locked = 1;
|
|
|
|
locked = 1;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Cancel any interactive move/resize and take the pointer focus away
|
|
|
|
|
|
|
|
* from the clients below the lock screen */
|
|
|
|
|
|
|
|
cursor_mode = CurNormal;
|
|
|
|
|
|
|
|
grabc = NULL;
|
|
|
|
|
|
|
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
|
|
|
|
|
|
|
|
|
|
|
LISTEN(&session_lock->events.new_surface, &lock->new_surface, createlocksurface);
|
|
|
|
LISTEN(&session_lock->events.new_surface, &lock->new_surface, createlocksurface);
|
|
|
|
LISTEN(&session_lock->events.destroy, &lock->destroy, destroysessionlock);
|
|
|
|
LISTEN(&session_lock->events.destroy, &lock->destroy, destroysessionlock);
|
|
|
|
LISTEN(&session_lock->events.unlock, &lock->unlock, unlocksession);
|
|
|
|
LISTEN(&session_lock->events.unlock, &lock->unlock, unlocksession);
|
|
|
@@ -1889,10 +1948,8 @@ mapnotify(struct wl_listener *listener, void *data)
|
|
|
|
/* Unmanaged clients always are floating */
|
|
|
|
/* Unmanaged clients always are floating */
|
|
|
|
wlr_scene_node_reparent(&c->scene->node, layers[LyrUnmanaged]);
|
|
|
|
wlr_scene_node_reparent(&c->scene->node, layers[LyrUnmanaged]);
|
|
|
|
wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y);
|
|
|
|
wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y);
|
|
|
|
if (client_wants_focus(c)) {
|
|
|
|
if (client_wants_focus(c))
|
|
|
|
focusclient(c, 1);
|
|
|
|
focusclient(c, NULL, 1);
|
|
|
|
exclusive_focus = c;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
goto unset_fullscreen;
|
|
|
|
goto unset_fullscreen;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -1903,8 +1960,15 @@ mapnotify(struct wl_listener *listener, void *data)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Initialize client geometry with room for border */
|
|
|
|
/* Initialize client geometry with room for border */
|
|
|
|
|
|
|
|
client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT |
|
|
|
|
|
|
|
|
WLR_EDGE_RIGHT);
|
|
|
|
c->geom.width += 2 * c->bw;
|
|
|
|
c->geom.width += 2 * c->bw;
|
|
|
|
c->geom.height += 2 * c->bw;
|
|
|
|
c->geom.height += 2 * c->bw;
|
|
|
|
|
|
|
|
if (client_is_x11(c)) {
|
|
|
|
|
|
|
|
int x = c->geom.x - (int)c->bw, y = c->geom.y - (int)c->bw;
|
|
|
|
|
|
|
|
c->geom.x = c->geom.x < sgeom.x ? x : MAX(x, sgeom.x);
|
|
|
|
|
|
|
|
c->geom.y = c->geom.y < sgeom.y ? y : MAX(y, sgeom.y);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Insert this client into client lists. */
|
|
|
|
/* Insert this client into client lists. */
|
|
|
|
wl_list_insert(&clients, &c->link);
|
|
|
|
wl_list_insert(&clients, &c->link);
|
|
|
@@ -2228,10 +2292,9 @@ pointerfocus(Client *c, LayerSurface *l, struct wlr_surface *surface, double sx,
|
|
|
|
|
|
|
|
|
|
|
|
if (surface != seat->pointer_state.focused_surface && sloppyfocus && time) {
|
|
|
|
if (surface != seat->pointer_state.focused_surface && sloppyfocus && time) {
|
|
|
|
if (c && (!client_is_unmanaged(c) || client_wants_focus(c))) {
|
|
|
|
if (c && (!client_is_unmanaged(c) || client_wants_focus(c))) {
|
|
|
|
focusclient(c, 0);
|
|
|
|
focusclient(c, NULL, 0);
|
|
|
|
} else if (l && l->layer_surface->current.keyboard_interactive) {
|
|
|
|
} else if (l && l->layer_surface->current.keyboard_interactive) {
|
|
|
|
focusclient(NULL, 0);
|
|
|
|
focusclient(NULL, l, 0);
|
|
|
|
client_notify_enter(l->layer_surface->surface, wlr_seat_get_keyboard(seat));
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -2365,7 +2428,7 @@ void
|
|
|
|
resize(Client *c, struct wlr_box geo, int interact)
|
|
|
|
resize(Client *c, struct wlr_box geo, int interact)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
struct wlr_box *bbox;
|
|
|
|
struct wlr_box *bbox;
|
|
|
|
struct wlr_box clip;
|
|
|
|
uint32_t serial;
|
|
|
|
|
|
|
|
|
|
|
|
if (!c->mon || !client_surface(c)->mapped)
|
|
|
|
if (!c->mon || !client_surface(c)->mapped)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
@@ -2376,20 +2439,27 @@ resize(Client *c, struct wlr_box geo, int interact)
|
|
|
|
c->geom = geo;
|
|
|
|
c->geom = geo;
|
|
|
|
applybounds(c, bbox);
|
|
|
|
applybounds(c, bbox);
|
|
|
|
|
|
|
|
|
|
|
|
/* Update scene-graph, including borders */
|
|
|
|
if ((serial = client_set_size(c, c->geom.width - 2 * c->bw,
|
|
|
|
wlr_scene_node_set_position(&c->scene->node, c->geom.x, c->geom.y);
|
|
|
|
c->geom.height - 2 * c->bw)))
|
|
|
|
wlr_scene_node_set_position(&c->scene_surface->node, c->bw, c->bw);
|
|
|
|
c->resize_serial = serial;
|
|
|
|
wlr_scene_rect_set_size(c->border[0], c->geom.width, c->bw);
|
|
|
|
|
|
|
|
wlr_scene_rect_set_size(c->border[1], c->geom.width, c->bw);
|
|
|
|
|
|
|
|
wlr_scene_rect_set_size(c->border[2], c->bw, c->geom.height - 2 * c->bw);
|
|
|
|
|
|
|
|
wlr_scene_rect_set_size(c->border[3], c->bw, c->geom.height - 2 * c->bw);
|
|
|
|
|
|
|
|
wlr_scene_node_set_position(&c->border[1]->node, 0, c->geom.height - c->bw);
|
|
|
|
|
|
|
|
wlr_scene_node_set_position(&c->border[2]->node, 0, c->bw);
|
|
|
|
|
|
|
|
wlr_scene_node_set_position(&c->border[3]->node, c->geom.width - c->bw, c->bw);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
client_set_size(c, c->geom.width - 2 * c->bw, c->geom.height - 2 * c->bw);
|
|
|
|
if (interact || (!c->resize_serial && wlr_box_equal(&c->geom, &c->current))) {
|
|
|
|
client_get_clip(c, &clip);
|
|
|
|
c->resize_serial = 0;
|
|
|
|
wlr_scene_subsurface_tree_set_clip(&c->scene_surface->node, &clip);
|
|
|
|
applygeom(c);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Until the transaction is applied, keep showing the current content
|
|
|
|
|
|
|
|
* instead of buffers with the new size at the old position. */
|
|
|
|
|
|
|
|
if (c->resize_serial) {
|
|
|
|
|
|
|
|
if (!c->snapshot && c->scene->node.enabled
|
|
|
|
|
|
|
|
&& (c->snapshot = snapshot(&c->scene_surface->node, c->scene, c)))
|
|
|
|
|
|
|
|
wlr_scene_node_set_enabled(&c->scene_surface->node, 0);
|
|
|
|
|
|
|
|
/* The scene graph doesn't send frame done events to hidden
|
|
|
|
|
|
|
|
* surfaces, but the client may be waiting for one to redraw */
|
|
|
|
|
|
|
|
client_send_frame_done(c);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
transactionschedule();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
@@ -2490,14 +2560,10 @@ setcursorshape(struct wl_listener *listener, void *data)
|
|
|
|
void
|
|
|
|
void
|
|
|
|
setfloating(Client *c, int floating)
|
|
|
|
setfloating(Client *c, int floating)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Client *p = client_get_parent(c);
|
|
|
|
|
|
|
|
c->isfloating = floating;
|
|
|
|
c->isfloating = floating;
|
|
|
|
/* If in floating layout do not change the client's layer */
|
|
|
|
/* If in floating layout do not change the client's layer */
|
|
|
|
if (!c->mon || !client_surface(c)->mapped || !c->mon->lt[c->mon->sellt]->arrange)
|
|
|
|
if (!c->mon || !client_surface(c)->mapped || !c->mon->lt[c->mon->sellt]->arrange)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen ||
|
|
|
|
|
|
|
|
(p && p->isfullscreen) ? LyrFS
|
|
|
|
|
|
|
|
: c->isfloating ? LyrFloat : LyrTile]);
|
|
|
|
|
|
|
|
arrange(c->mon);
|
|
|
|
arrange(c->mon);
|
|
|
|
printstatus();
|
|
|
|
printstatus();
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -2510,8 +2576,6 @@ setfullscreen(Client *c, int fullscreen)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
c->bw = fullscreen ? 0 : borderpx;
|
|
|
|
c->bw = fullscreen ? 0 : borderpx;
|
|
|
|
client_set_fullscreen(c, fullscreen);
|
|
|
|
client_set_fullscreen(c, fullscreen);
|
|
|
|
wlr_scene_node_reparent(&c->scene->node, layers[c->isfullscreen
|
|
|
|
|
|
|
|
? LyrFS : c->isfloating ? LyrFloat : LyrTile]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (fullscreen) {
|
|
|
|
if (fullscreen) {
|
|
|
|
c->prev = c->geom;
|
|
|
|
c->prev = c->geom;
|
|
|
@@ -2574,7 +2638,7 @@ setmon(Client *c, Monitor *m, uint32_t newtags)
|
|
|
|
setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */
|
|
|
|
setfullscreen(c, c->isfullscreen); /* This will call arrange(c->mon) */
|
|
|
|
setfloating(c, c->isfloating);
|
|
|
|
setfloating(c, c->isfloating);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
focusclient(focustop(selmon), 1);
|
|
|
|
focusclient(focustop(selmon), NULL, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
@@ -2715,6 +2779,9 @@ setup(void)
|
|
|
|
wl_list_init(&clients);
|
|
|
|
wl_list_init(&clients);
|
|
|
|
wl_list_init(&fstack);
|
|
|
|
wl_list_init(&fstack);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
transaction_timer = wl_event_loop_add_timer(event_loop, transactiontimeout, NULL);
|
|
|
|
|
|
|
|
wl_array_init(&ghosts);
|
|
|
|
|
|
|
|
|
|
|
|
xdg_shell = wlr_xdg_shell_create(dpy, 6);
|
|
|
|
xdg_shell = wlr_xdg_shell_create(dpy, 6);
|
|
|
|
wl_signal_add(&xdg_shell->events.new_toplevel, &new_xdg_toplevel);
|
|
|
|
wl_signal_add(&xdg_shell->events.new_toplevel, &new_xdg_toplevel);
|
|
|
|
wl_signal_add(&xdg_shell->events.new_popup, &new_xdg_popup);
|
|
|
|
wl_signal_add(&xdg_shell->events.new_popup, &new_xdg_popup);
|
|
|
@@ -2836,6 +2903,57 @@ setup(void)
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct wlr_scene_node *
|
|
|
|
|
|
|
|
snapshot(struct wlr_scene_node *node, struct wlr_scene_tree *parent, void *data)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
/* Copy the visible part of a scene graph subtree, keeping references to
|
|
|
|
|
|
|
|
* the buffers so that they can be shown after the client changes them */
|
|
|
|
|
|
|
|
struct wlr_scene_node *child, *copy;
|
|
|
|
|
|
|
|
struct wlr_scene_tree *tree;
|
|
|
|
|
|
|
|
struct wlr_scene_rect *rect;
|
|
|
|
|
|
|
|
struct wlr_scene_buffer *src, *buffer;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!node->enabled)
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (node->type) {
|
|
|
|
|
|
|
|
case WLR_SCENE_NODE_TREE:
|
|
|
|
|
|
|
|
tree = wlr_scene_tree_create(parent);
|
|
|
|
|
|
|
|
wl_list_for_each(child, &wlr_scene_tree_from_node(node)->children, link)
|
|
|
|
|
|
|
|
snapshot(child, tree, data);
|
|
|
|
|
|
|
|
copy = &tree->node;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WLR_SCENE_NODE_RECT:
|
|
|
|
|
|
|
|
rect = wlr_scene_rect_from_node(node);
|
|
|
|
|
|
|
|
copy = &wlr_scene_rect_create(parent, rect->width, rect->height, rect->color)->node;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WLR_SCENE_NODE_BUFFER:
|
|
|
|
|
|
|
|
src = wlr_scene_buffer_from_node(node);
|
|
|
|
|
|
|
|
buffer = wlr_scene_buffer_create(parent, NULL);
|
|
|
|
|
|
|
|
wlr_scene_buffer_set_dest_size(buffer, src->dst_width, src->dst_height);
|
|
|
|
|
|
|
|
wlr_scene_buffer_set_opaque_region(buffer, &src->opaque_region);
|
|
|
|
|
|
|
|
wlr_scene_buffer_set_opacity(buffer, src->opacity);
|
|
|
|
|
|
|
|
wlr_scene_buffer_set_filter_mode(buffer, src->filter_mode);
|
|
|
|
|
|
|
|
wlr_scene_buffer_set_transfer_function(buffer, src->transfer_function);
|
|
|
|
|
|
|
|
wlr_scene_buffer_set_primaries(buffer, src->primaries);
|
|
|
|
|
|
|
|
wlr_scene_buffer_set_color_encoding(buffer, src->color_encoding);
|
|
|
|
|
|
|
|
wlr_scene_buffer_set_color_range(buffer, src->color_range);
|
|
|
|
|
|
|
|
wlr_scene_buffer_set_source_box(buffer, &src->src_box);
|
|
|
|
|
|
|
|
wlr_scene_buffer_set_transform(buffer, src->transform);
|
|
|
|
|
|
|
|
wlr_scene_buffer_set_buffer(buffer, src->buffer);
|
|
|
|
|
|
|
|
copy = &buffer->node;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
copy->data = data;
|
|
|
|
|
|
|
|
wlr_scene_node_set_position(copy, node->x, node->y);
|
|
|
|
|
|
|
|
if (node->parent == parent)
|
|
|
|
|
|
|
|
wlr_scene_node_place_above(copy, node);
|
|
|
|
|
|
|
|
return copy;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
spawn(const Arg *arg)
|
|
|
|
spawn(const Arg *arg)
|
|
|
|
{
|
|
|
|
{
|
|
|
@@ -2866,7 +2984,7 @@ tag(const Arg *arg)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
sel->tags = arg->ui & TAGMASK;
|
|
|
|
sel->tags = arg->ui & TAGMASK;
|
|
|
|
focusclient(focustop(selmon), 1);
|
|
|
|
focusclient(focustop(selmon), NULL, 1);
|
|
|
|
arrange(selmon);
|
|
|
|
arrange(selmon);
|
|
|
|
printstatus();
|
|
|
|
printstatus();
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -2939,7 +3057,7 @@ toggletag(const Arg *arg)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
sel->tags = newtags;
|
|
|
|
sel->tags = newtags;
|
|
|
|
focusclient(focustop(selmon), 1);
|
|
|
|
focusclient(focustop(selmon), NULL, 1);
|
|
|
|
arrange(selmon);
|
|
|
|
arrange(selmon);
|
|
|
|
printstatus();
|
|
|
|
printstatus();
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -2952,11 +3070,93 @@ toggleview(const Arg *arg)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
selmon->tagset[selmon->seltags] = newtagset;
|
|
|
|
selmon->tagset[selmon->seltags] = newtagset;
|
|
|
|
focusclient(focustop(selmon), 1);
|
|
|
|
focusclient(focustop(selmon), NULL, 1);
|
|
|
|
arrange(selmon);
|
|
|
|
arrange(selmon);
|
|
|
|
printstatus();
|
|
|
|
printstatus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
|
|
transactionapply(void)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
struct wlr_scene_node **ghost;
|
|
|
|
|
|
|
|
Client *c;
|
|
|
|
|
|
|
|
Monitor *m;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wl_event_source_timer_update(transaction_timer, 0);
|
|
|
|
|
|
|
|
transaction_waiting = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wl_array_for_each(ghost, &ghosts)
|
|
|
|
|
|
|
|
wlr_scene_node_destroy(*ghost);
|
|
|
|
|
|
|
|
ghosts.size = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wl_list_for_each(c, &clients, link) {
|
|
|
|
|
|
|
|
c->resize_serial = 0;
|
|
|
|
|
|
|
|
if (!c->mon)
|
|
|
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (c->mon->wlr_output->enabled)
|
|
|
|
|
|
|
|
wlr_scene_node_set_enabled(&c->scene->node, VISIBLEON(c, c->mon));
|
|
|
|
|
|
|
|
applygeom(c);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
wl_list_for_each(m, &mons, link) {
|
|
|
|
|
|
|
|
if (m->wlr_output->enabled)
|
|
|
|
|
|
|
|
wlr_scene_node_set_enabled(&m->fullscreen_bg->node,
|
|
|
|
|
|
|
|
(c = focustop(m)) && c->isfullscreen);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
|
|
|
|
|
|
|
checkidleinhibitor(NULL);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
|
|
transactioncheck(void *data)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Client *c;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
transaction_idle = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Hidden clients don't have to redraw before the layout is shown */
|
|
|
|
|
|
|
|
wl_list_for_each(c, &clients, link) {
|
|
|
|
|
|
|
|
if (c->resize_serial && VISIBLEON(c, c->mon) && c->mon->wlr_output->enabled) {
|
|
|
|
|
|
|
|
if (!transaction_waiting) {
|
|
|
|
|
|
|
|
/* Don't restart the timer on updates of the pending
|
|
|
|
|
|
|
|
* layout, so the delay is bounded */
|
|
|
|
|
|
|
|
wl_event_source_timer_update(transaction_timer, TRANSACTION_TIMEOUT);
|
|
|
|
|
|
|
|
transaction_waiting = 1;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
transactionapply();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
|
|
transactioncommit(Client *c, int ready)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (c->resize_serial && ready) {
|
|
|
|
|
|
|
|
c->resize_serial = 0;
|
|
|
|
|
|
|
|
transactionschedule();
|
|
|
|
|
|
|
|
} else if (c->snapshot) {
|
|
|
|
|
|
|
|
/* This buffer is not shown, let the client draw again */
|
|
|
|
|
|
|
|
client_send_frame_done(c);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
|
|
transactionschedule(void)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!transaction_idle)
|
|
|
|
|
|
|
|
transaction_idle = wl_event_loop_add_idle(event_loop, transactioncheck, NULL);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
|
|
|
transactiontimeout(void *data)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
transactionapply();
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
unlocksession(struct wl_listener *listener, void *data)
|
|
|
|
unlocksession(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
{
|
|
|
@@ -2971,12 +3171,10 @@ unmaplayersurfacenotify(struct wl_listener *listener, void *data)
|
|
|
|
|
|
|
|
|
|
|
|
l->mapped = 0;
|
|
|
|
l->mapped = 0;
|
|
|
|
wlr_scene_node_set_enabled(&l->scene->node, 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))
|
|
|
|
if (l->layer_surface->output && (l->mon = l->layer_surface->output->data))
|
|
|
|
arrangelayers(l->mon);
|
|
|
|
arrangelayers(l->mon);
|
|
|
|
if (l->layer_surface->surface == seat->keyboard_state.focused_surface)
|
|
|
|
if (l->layer_surface->surface == seat->keyboard_state.focused_surface)
|
|
|
|
focusclient(focustop(selmon), 1);
|
|
|
|
focusclient(focustop(selmon), NULL, 1);
|
|
|
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
|
|
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -2985,6 +3183,7 @@ unmapnotify(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* Called when the surface is unmapped, and should no longer be shown. */
|
|
|
|
/* Called when the surface is unmapped, and should no longer be shown. */
|
|
|
|
Client *c = wl_container_of(listener, c, unmap);
|
|
|
|
Client *c = wl_container_of(listener, c, unmap);
|
|
|
|
|
|
|
|
struct wlr_scene_node *ghost, **slot;
|
|
|
|
if (c == grabc) {
|
|
|
|
if (c == grabc) {
|
|
|
|
cursor_mode = CurNormal;
|
|
|
|
cursor_mode = CurNormal;
|
|
|
|
grabc = NULL;
|
|
|
|
grabc = NULL;
|
|
|
@@ -2992,15 +3191,21 @@ unmapnotify(struct wl_listener *listener, void *data)
|
|
|
|
if (c == focused_client)
|
|
|
|
if (c == focused_client)
|
|
|
|
focused_client = NULL;
|
|
|
|
focused_client = NULL;
|
|
|
|
|
|
|
|
|
|
|
|
if (client_is_unmanaged(c)) {
|
|
|
|
if (!client_is_unmanaged(c)) {
|
|
|
|
if (c == exclusive_focus) {
|
|
|
|
/* Keep showing the client until the transaction rearranging the
|
|
|
|
exclusive_focus = NULL;
|
|
|
|
* remaining ones is applied, to not show a gap */
|
|
|
|
focusclient(focustop(selmon), 1);
|
|
|
|
if ((ghost = snapshot(&c->scene->node, c->scene->node.parent, NULL))) {
|
|
|
|
|
|
|
|
if ((slot = wl_array_add(&ghosts, sizeof(ghost))))
|
|
|
|
|
|
|
|
*slot = ghost;
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
wlr_scene_node_destroy(ghost);
|
|
|
|
|
|
|
|
transactionschedule();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
|
|
|
|
wl_list_remove(&c->link);
|
|
|
|
wl_list_remove(&c->link);
|
|
|
|
setmon(c, NULL, 0);
|
|
|
|
setmon(c, NULL, 0);
|
|
|
|
wl_list_remove(&c->flink);
|
|
|
|
wl_list_remove(&c->flink);
|
|
|
|
|
|
|
|
} else if (client_wants_focus(c)) {
|
|
|
|
|
|
|
|
focusclient(focustop(selmon), NULL, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (c->foreign_toplevel_handle) {
|
|
|
|
if (c->foreign_toplevel_handle) {
|
|
|
@@ -3019,6 +3224,9 @@ unmapnotify(struct wl_listener *listener, void *data)
|
|
|
|
c->image_capture_source = NULL;
|
|
|
|
c->image_capture_source = NULL;
|
|
|
|
wlr_scene_node_destroy(&c->scene->node);
|
|
|
|
wlr_scene_node_destroy(&c->scene->node);
|
|
|
|
client_surface(c)->data = NULL;
|
|
|
|
client_surface(c)->data = NULL;
|
|
|
|
|
|
|
|
c->snapshot = NULL;
|
|
|
|
|
|
|
|
c->resize_serial = 0;
|
|
|
|
|
|
|
|
c->current = (struct wlr_box){0};
|
|
|
|
printstatus();
|
|
|
|
printstatus();
|
|
|
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
|
|
|
motionnotify(0, NULL, 0, 0, 0, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -3114,7 +3322,7 @@ updatemons(struct wl_listener *listener, void *data)
|
|
|
|
if (!c->mon && client_surface(c)->mapped)
|
|
|
|
if (!c->mon && client_surface(c)->mapped)
|
|
|
|
setmon(c, selmon, c->tags);
|
|
|
|
setmon(c, selmon, c->tags);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
focusclient(focustop(selmon), 1);
|
|
|
|
focusclient(focustop(selmon), NULL, 1);
|
|
|
|
if (selmon->lock_surface) {
|
|
|
|
if (selmon->lock_surface) {
|
|
|
|
client_notify_enter(selmon->lock_surface->surface,
|
|
|
|
client_notify_enter(selmon->lock_surface->surface,
|
|
|
|
wlr_seat_get_keyboard(seat));
|
|
|
|
wlr_seat_get_keyboard(seat));
|
|
|
@@ -3173,7 +3381,7 @@ view(const Arg *arg)
|
|
|
|
selmon->seltags ^= 1; /* toggle sel tagset */
|
|
|
|
selmon->seltags ^= 1; /* toggle sel tagset */
|
|
|
|
if (arg->ui & TAGMASK)
|
|
|
|
if (arg->ui & TAGMASK)
|
|
|
|
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
|
|
|
|
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
|
|
|
|
focusclient(focustop(selmon), 1);
|
|
|
|
focusclient(focustop(selmon), NULL, 1);
|
|
|
|
arrange(selmon);
|
|
|
|
arrange(selmon);
|
|
|
|
printstatus();
|
|
|
|
printstatus();
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -3218,20 +3426,26 @@ xytonode(double x, double y, struct wlr_surface **psurface,
|
|
|
|
Client **pc, LayerSurface **pl, double *nx, double *ny)
|
|
|
|
Client **pc, LayerSurface **pl, double *nx, double *ny)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
struct wlr_scene_node *node;
|
|
|
|
struct wlr_scene_node *node;
|
|
|
|
|
|
|
|
struct wlr_scene_surface *scene_surface;
|
|
|
|
struct wlr_surface *surface = NULL;
|
|
|
|
struct wlr_surface *surface = NULL;
|
|
|
|
|
|
|
|
Client *c = NULL;
|
|
|
|
int layer;
|
|
|
|
int layer;
|
|
|
|
|
|
|
|
|
|
|
|
for (layer = NUM_LAYERS - 1; !surface && layer >= 0; layer--) {
|
|
|
|
for (layer = NUM_LAYERS - 1; !surface && !c && layer >= (locked ? LyrBlock : 0); layer--) {
|
|
|
|
if (layer == LyrIMPopup ||
|
|
|
|
if (layer == LyrIMPopup ||
|
|
|
|
!(node = wlr_scene_node_at(&layers[layer]->node, x, y, nx, ny)))
|
|
|
|
!(node = wlr_scene_node_at(&layers[layer]->node, x, y, nx, ny))
|
|
|
|
|
|
|
|
|| node->type != WLR_SCENE_NODE_BUFFER)
|
|
|
|
continue;
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
|
|
if (node->type == WLR_SCENE_NODE_BUFFER)
|
|
|
|
if ((scene_surface = wlr_scene_surface_try_from_buffer(
|
|
|
|
surface = wlr_scene_surface_try_from_buffer(
|
|
|
|
wlr_scene_buffer_from_node(node))))
|
|
|
|
wlr_scene_buffer_from_node(node))->surface;
|
|
|
|
surface = scene_surface->surface;
|
|
|
|
|
|
|
|
else /* snapshot of a client during a transaction */
|
|
|
|
|
|
|
|
c = node->data;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (psurface) *psurface = surface;
|
|
|
|
if (psurface) *psurface = surface;
|
|
|
|
|
|
|
|
if (pc) *pc = c;
|
|
|
|
toplevel_from_wlr_surface(surface, pc, pl);
|
|
|
|
toplevel_from_wlr_surface(surface, pc, pl);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -3264,7 +3478,7 @@ zoom(const Arg *arg)
|
|
|
|
wl_list_remove(&sel->link);
|
|
|
|
wl_list_remove(&sel->link);
|
|
|
|
wl_list_insert(&clients, &sel->link);
|
|
|
|
wl_list_insert(&clients, &sel->link);
|
|
|
|
|
|
|
|
|
|
|
|
focusclient(sel, 1);
|
|
|
|
focusclient(sel, NULL, 1);
|
|
|
|
arrange(selmon);
|
|
|
|
arrange(selmon);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@@ -3284,10 +3498,21 @@ associatex11(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Client *c = wl_container_of(listener, c, associate);
|
|
|
|
Client *c = wl_container_of(listener, c, associate);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
LISTEN(&client_surface(c)->events.commit, &c->commit, commitx11);
|
|
|
|
LISTEN(&client_surface(c)->events.map, &c->map, mapnotify);
|
|
|
|
LISTEN(&client_surface(c)->events.map, &c->map, mapnotify);
|
|
|
|
LISTEN(&client_surface(c)->events.unmap, &c->unmap, unmapnotify);
|
|
|
|
LISTEN(&client_surface(c)->events.unmap, &c->unmap, unmapnotify);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
|
|
|
commitx11(struct wl_listener *listener, void *data)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
Client *c = wl_container_of(listener, c, commit);
|
|
|
|
|
|
|
|
struct wlr_surface *surface = client_surface(c);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
transactioncommit(c, surface->current.width == c->geom.width - 2 * (int)c->bw
|
|
|
|
|
|
|
|
&& surface->current.height == c->geom.height - 2 * (int)c->bw);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
void
|
|
|
|
configurex11(struct wl_listener *listener, void *data)
|
|
|
|
configurex11(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
{
|
|
|
@@ -3336,6 +3561,7 @@ void
|
|
|
|
dissociatex11(struct wl_listener *listener, void *data)
|
|
|
|
dissociatex11(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
Client *c = wl_container_of(listener, c, dissociate);
|
|
|
|
Client *c = wl_container_of(listener, c, dissociate);
|
|
|
|
|
|
|
|
wl_list_remove(&c->commit.link);
|
|
|
|
wl_list_remove(&c->map.link);
|
|
|
|
wl_list_remove(&c->map.link);
|
|
|
|
wl_list_remove(&c->unmap.link);
|
|
|
|
wl_list_remove(&c->unmap.link);
|
|
|
|
}
|
|
|
|
}
|
|
|
|