mirror of
https://codeberg.org/dwl/dwl.git
synced 2025-10-27 10:14:14 +00:00
Merge pull request #4 from Sevz17/basic_damage_tracking
fix crash when foot closes + fix merge conflicts
This commit is contained in:
commit
de0c391141
22
Makefile
22
Makefile
@ -11,6 +11,17 @@ LDLIBS += $(foreach p,$(PKGS),$(shell pkg-config --libs $(p)))
|
||||
|
||||
all: dwl
|
||||
|
||||
clean:
|
||||
rm -f dwl *.o *-protocol.h *-protocol.c
|
||||
|
||||
install: dwl
|
||||
install -D dwl $(PREFIX)/bin/dwl
|
||||
|
||||
uninstall:
|
||||
rm -f $(PREFIX)/bin/dwl
|
||||
|
||||
.PHONY: all clean install uninstall
|
||||
|
||||
# wayland-scanner is a tool which generates C headers and rigging for Wayland
|
||||
# protocols, which are specified in XML. wlroots requires you to rig these up
|
||||
# to your build system yourself and provide them in the include path.
|
||||
@ -47,15 +58,6 @@ idle-protocol.o: idle-protocol.h
|
||||
config.h: | config.def.h
|
||||
cp config.def.h $@
|
||||
|
||||
dwl.o: config.h client.h xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h idle-protocol.h
|
||||
dwl.o: config.mk config.h client.h xdg-shell-protocol.h wlr-layer-shell-unstable-v1-protocol.h idle-protocol.h
|
||||
|
||||
dwl: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o idle-protocol.o
|
||||
|
||||
clean:
|
||||
rm -f dwl *.o *-protocol.h *-protocol.c
|
||||
|
||||
install: dwl
|
||||
install -D dwl $(PREFIX)/bin/dwl
|
||||
|
||||
.DEFAULT_GOAL=dwl
|
||||
.PHONY: clean
|
||||
|
||||
20
README.md
20
README.md
@ -14,30 +14,31 @@ dwl is not meant to provide every feature under the sun. Instead, like dwm, it s
|
||||
- Any features provided by dwm/Xlib: simple window borders, tags, keybindings, client rules, mouse move/resize. Providing a built-in status bar is an exception to this goal, to avoid dependencies on font rendering and/or drawing libraries when an external bar could work well.
|
||||
- Configurable multi-monitor layout support, including position and rotation
|
||||
- Configurable HiDPI/multi-DPI support
|
||||
- Provide information to external status bars via stdout/stdin
|
||||
- Urgency hints via xdg-activate protocol
|
||||
- Various Wayland protocols
|
||||
- XWayland support as provided by wlroots
|
||||
- XWayland support as provided by wlroots (can be enabled in `config.mk`)
|
||||
- Zero flickering - Wayland users naturally expect that "every frame is perfect"
|
||||
|
||||
Features under consideration (possibly as patches) are:
|
||||
|
||||
- Protocols made trivial by wlroots
|
||||
- Provide information to external status bars via stdout or another file descriptor
|
||||
- Implement the input-inhibitor protocol to support screen lockers
|
||||
- Implement the idle-inhibit protocol which lets applications such as mpv disable idle monitoring
|
||||
- Layer shell popups (used by Waybar)
|
||||
- Basic yes/no damage tracking to avoid needless redraws
|
||||
- More in-depth damage region tracking ([which may improve power usage](https://mozillagfx.wordpress.com/2019/10/22/dramatically-reduced-power-usage-in-firefox-70-on-macos-with-core-animation/))
|
||||
- Implement the text-input and input-method protocols to support IME once ibus implements input-method v2 (see https://github.com/ibus/ibus/pull/2256 and https://github.com/djpohly/dwl/pull/12)
|
||||
- Implement urgent/attention/focus-request once it's part of the xdg-shell protocol (https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/9)
|
||||
|
||||
Feature *non-goals* include:
|
||||
Feature *non-goals* for the main codebase include:
|
||||
|
||||
- Client-side decoration (any more than is necessary to tell the clients not to)
|
||||
- Client-initiated window management, such as move, resize, and close, which can be done through the compositor
|
||||
- Animations and visual effects
|
||||
|
||||
## Building dwl
|
||||
|
||||
dwl has only two dependencies: wlroots-git and wayland-protocols. Simply install these and run `make`.
|
||||
dwl has only two dependencies: wlroots and wayland-protocols. Simply install these (and their `-devel` versions if your distro has separate development packages) and run `make`. If you wish to build against a Git version of wlroots, check out the [wlroots-next branch](https://github.com/djpohly/dwl/tree/wlroots-next).
|
||||
|
||||
To enable XWayland, you should also install xorg-xwayland and uncomment its flag in `config.mk`.
|
||||
|
||||
@ -49,14 +50,19 @@ As in the dwm community, we encourage users to share patches they have created.
|
||||
|
||||
## Running dwl
|
||||
|
||||
dwl can be run as-is, with no arguments. In an existing Wayland or X11 session, this will open a window to act as a virtual display. When run from a TTY, the Wayland server will take over the entire virtual terminal. Clients started by dwl will have `WAYLAND_DISPLAY` set in their environment, and other clients can be started from outside the session by setting this variable accordingly.
|
||||
dwl can be run on any of the backends supported by wlroots. This means you can run it as a separate window inside either an X11 or Wayland session, as well as directly from a VT console. Depending on your distro's setup, you may need to add your user to the `video` and `input` groups before you can run dwl on a VT.
|
||||
|
||||
You can also specify a startup program using the `-s` option. The argument to this option will be run at startup as a shell command (using `sh -c`) and can serve a similar function to `.xinitrc`: starting a service manager or other startup applications. Unlike `.xinitrc`, the display server will not shut down when this process terminates. Instead, as dwl is shutting down, it will send this process a SIGTERM and wait for it to terminate (if it hasn't already). This makes it ideal not only for initialization but also for execing into a user-level service manager like s6 or `systemd --user`.
|
||||
When dwl is run with no arguments, it will launch the server and begin handling any shortcuts configured in `config.h`. There is no status bar or other decoration initially; these are instead clients that can be run within the Wayland session.
|
||||
|
||||
If you would like to run a script or command automatically at startup, you can specify the command using the `-s` option. The argument to this option will be parsed as a shell command (using `sh -c`) and can serve a similar function to `.xinitrc`. Unlike `.xinitrc`, the display server will not shut down when this process terminates. Instead, as dwl is shutting down, it will send this process a SIGTERM and wait for it to terminate (if it hasn't already). This makes it ideal for execing into a user service manager like [s6](https://skarnet.org/software/s6/), [anopa](https://jjacky.com/anopa/), [runit](http://smarden.org/runit/faq.html#userservices), or [`systemd --user`](https://wiki.archlinux.org/title/Systemd/User).
|
||||
|
||||
Note: The `-s` command is run as a *child process* of dwl, which means that it does not have the ability to affect the environment of dwl or of any processes that it spawns. If you need to set environment variables that affect the entire dwl session (such as `XDG_RUNTIME_DIR` in the note below), these must be set prior to running dwl.
|
||||
|
||||
Note: Wayland requires a valid `XDG_RUNTIME_DIR`, which is usually set up by a session manager such as `elogind` or `systemd-logind`. If your system doesn't do this automatically, you will need to configure it prior to launching `dwl`, e.g.:
|
||||
|
||||
export XDG_RUNTIME_DIR=/tmp/xdg-runtime-$(id -u)
|
||||
mkdir -p $XDG_RUNTIME_DIR
|
||||
dwl
|
||||
|
||||
## Replacements for X applications
|
||||
|
||||
|
||||
11
client.h
11
client.h
@ -141,6 +141,17 @@ client_set_size(Client *c, uint32_t width, uint32_t height)
|
||||
return wlr_xdg_toplevel_set_size(c->surface.xdg, width, height);
|
||||
}
|
||||
|
||||
static inline void
|
||||
client_set_tiled(Client *c, uint32_t edges)
|
||||
{
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return;
|
||||
#endif
|
||||
wlr_xdg_toplevel_set_tiled(c->surface.xdg, WLR_EDGE_TOP |
|
||||
WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT);
|
||||
}
|
||||
|
||||
static inline struct wlr_surface *
|
||||
client_surface(Client *c)
|
||||
{
|
||||
|
||||
175
dwl.c
175
dwl.c
@ -30,13 +30,16 @@
|
||||
#include <wlr/types/wlr_output_layout.h>
|
||||
#include <wlr/types/wlr_output_management_v1.h>
|
||||
#include <wlr/types/wlr_pointer.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_screencopy_v1.h>
|
||||
#include <wlr/types/wlr_server_decoration.h>
|
||||
#include <wlr/types/wlr_seat.h>
|
||||
#include <wlr/types/wlr_viewporter.h>
|
||||
#include <wlr/types/wlr_virtual_keyboard_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>
|
||||
@ -97,6 +100,7 @@ typedef struct {
|
||||
struct wl_listener map;
|
||||
struct wl_listener unmap;
|
||||
struct wl_listener destroy;
|
||||
struct wl_listener set_title;
|
||||
struct wl_listener fullscreen;
|
||||
struct wlr_box geom; /* layout-relative, includes border */
|
||||
Monitor *mon;
|
||||
@ -107,7 +111,7 @@ typedef struct {
|
||||
#endif
|
||||
int bw;
|
||||
unsigned int tags;
|
||||
int isfloating;
|
||||
int isfloating, isurgent;
|
||||
uint32_t resize; /* configure serial of a pending resize */
|
||||
int prevx;
|
||||
int prevy;
|
||||
@ -243,19 +247,16 @@ static void createmon(struct wl_listener *listener, void *data);
|
||||
static void createnotify(struct wl_listener *listener, void *data);
|
||||
static void createlayersurface(struct wl_listener *listener, void *data);
|
||||
static void createpointer(struct wlr_input_device *device);
|
||||
static void createxdeco(struct wl_listener *listener, void *data);
|
||||
static void cursorframe(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 destroynotify_sub(struct wl_listener *listener, void *data);
|
||||
static void destroyxdeco(struct wl_listener *listener, void *data);
|
||||
static Monitor *dirtomon(enum wlr_direction dir);
|
||||
static void focusclient(Client *c, int lift);
|
||||
static void focusmon(const Arg *arg);
|
||||
static void focusstack(const Arg *arg);
|
||||
static void fullscreennotify(struct wl_listener *listener, void *data);
|
||||
static Client *focustop(Monitor *m);
|
||||
static void getxdecomode(struct wl_listener *listener, void *data);
|
||||
static void incnmaster(const Arg *arg);
|
||||
static void inputdevice(struct wl_listener *listener, void *data);
|
||||
static int keybinding(uint32_t mods, xkb_keysym_t sym);
|
||||
@ -278,6 +279,7 @@ static void pointerfocus(Client *c, struct wlr_surface *surface,
|
||||
double sx, double sy, uint32_t time);
|
||||
static void printstatus(void);
|
||||
static void quit(const Arg *arg);
|
||||
static void quitsignal(int signo);
|
||||
static void render(struct wlr_surface *surface, int sx, int sy, void *data);
|
||||
static void renderclients(Monitor *m, struct timespec *now);
|
||||
static void renderlayer(struct wl_list *layer_surfaces, struct timespec *now);
|
||||
@ -309,6 +311,8 @@ static void unmaplayersurfacenotify(struct wl_listener *listener, void *data);
|
||||
static void unmapnotify(struct wl_listener *listener, void *data);
|
||||
static void unmapnotify_sub(struct wl_listener *listener, void *data);
|
||||
static void updatemons(struct wl_listener *listener, void *data);
|
||||
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 virtualkeyboard(struct wl_listener *listener, void *data);
|
||||
static Client *xytoclient(double x, double y);
|
||||
@ -325,6 +329,7 @@ static struct wlr_renderer *drw;
|
||||
static struct wlr_compositor *compositor;
|
||||
|
||||
static struct wlr_xdg_shell *xdg_shell;
|
||||
static struct wlr_xdg_activation_v1 *activation;
|
||||
static struct wl_list clients; /* tiling order */
|
||||
static struct wl_list fstack; /* focus order */
|
||||
static struct wl_list stack; /* stacking z-order */
|
||||
@ -332,8 +337,8 @@ static struct wl_list independents;
|
||||
static struct wl_list subsurfaces;
|
||||
static struct wlr_idle *idle;
|
||||
static struct wlr_layer_shell_v1 *layer_shell;
|
||||
static struct wlr_xdg_decoration_manager_v1 *xdeco_mgr;
|
||||
static struct wlr_output_manager_v1 *output_mgr;
|
||||
static struct wlr_presentation *presentation;
|
||||
static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr;
|
||||
|
||||
static struct wlr_cursor *cursor;
|
||||
@ -364,11 +369,11 @@ static struct wl_listener layout_change = {.notify = updatemons};
|
||||
static struct wl_listener new_input = {.notify = inputdevice};
|
||||
static struct wl_listener new_virtual_keyboard = {.notify = virtualkeyboard};
|
||||
static struct wl_listener new_output = {.notify = createmon};
|
||||
static struct wl_listener new_xdeco = {.notify = createxdeco};
|
||||
static struct wl_listener new_xdg_surface = {.notify = createnotify};
|
||||
static struct wl_listener new_layer_shell_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 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};
|
||||
@ -803,6 +808,7 @@ commitnotify(struct wl_listener *listener, void *data)
|
||||
c->resize = 0;
|
||||
|
||||
// Damage the whole screen
|
||||
if (c->mon)
|
||||
wlr_output_damage_add_whole(c->mon->damage);
|
||||
}
|
||||
|
||||
@ -880,11 +886,13 @@ createmon(struct wl_listener *listener, void *data)
|
||||
LISTEN(&wlr_output->events.frame, &m->frame, rendermon);
|
||||
LISTEN(&wlr_output->events.destroy, &m->destroy, cleanupmon);
|
||||
|
||||
wl_list_insert(&mons, &m->link);
|
||||
wlr_output_enable(wlr_output, 1);
|
||||
if (!wlr_output_commit(wlr_output))
|
||||
return;
|
||||
|
||||
wl_list_insert(&mons, &m->link);
|
||||
printstatus();
|
||||
|
||||
/* Adds this to the output layout in the order it was configured in.
|
||||
*
|
||||
* The output layout utility automatically adds a wl_output global to the
|
||||
@ -923,14 +931,11 @@ createnotify(struct wl_listener *listener, void *data)
|
||||
c->surface.xdg = xdg_surface;
|
||||
c->bw = borderpx;
|
||||
|
||||
/* Tell the client not to try anything fancy */
|
||||
wlr_xdg_toplevel_set_tiled(c->surface.xdg, WLR_EDGE_TOP |
|
||||
WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT);
|
||||
|
||||
LISTEN(&xdg_surface->surface->events.new_subsurface, &c->new_sub, new_subnotify);
|
||||
LISTEN(&xdg_surface->events.map, &c->map, mapnotify);
|
||||
LISTEN(&xdg_surface->events.unmap, &c->unmap, unmapnotify);
|
||||
LISTEN(&xdg_surface->events.destroy, &c->destroy, destroynotify);
|
||||
LISTEN(&xdg_surface->toplevel->events.set_title, &c->set_title, updatetitle);
|
||||
LISTEN(&xdg_surface->toplevel->events.request_fullscreen, &c->fullscreen,
|
||||
fullscreennotify);
|
||||
c->isfullscreen = 0;
|
||||
@ -994,18 +999,6 @@ createpointer(struct wlr_input_device *device)
|
||||
wlr_cursor_attach_input_device(cursor, device);
|
||||
}
|
||||
|
||||
void
|
||||
createxdeco(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct wlr_xdg_toplevel_decoration_v1 *wlr_deco = data;
|
||||
Decoration *d = wlr_deco->data = calloc(1, sizeof(*d));
|
||||
|
||||
LISTEN(&wlr_deco->events.request_mode, &d->request_mode, getxdecomode);
|
||||
LISTEN(&wlr_deco->events.destroy, &d->destroy, destroyxdeco);
|
||||
|
||||
getxdecomode(&d->request_mode, wlr_deco);
|
||||
}
|
||||
|
||||
void
|
||||
cursorframe(struct wl_listener *listener, void *data)
|
||||
{
|
||||
@ -1051,6 +1044,7 @@ destroynotify(struct wl_listener *listener, void *data)
|
||||
wl_list_remove(&c->map.link);
|
||||
wl_list_remove(&c->unmap.link);
|
||||
wl_list_remove(&c->destroy.link);
|
||||
wl_list_remove(&c->set_title.link);
|
||||
wl_list_remove(&c->fullscreen.link);
|
||||
#ifdef XWAYLAND
|
||||
if (c->type == X11Managed)
|
||||
@ -1072,17 +1066,6 @@ destroynotify_sub(struct wl_listener *listener, void *data)
|
||||
free(s);
|
||||
}
|
||||
|
||||
void
|
||||
destroyxdeco(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct wlr_xdg_toplevel_decoration_v1 *wlr_deco = data;
|
||||
Decoration *d = wlr_deco->data;
|
||||
|
||||
wl_list_remove(&d->destroy.link);
|
||||
wl_list_remove(&d->request_mode.link);
|
||||
free(d);
|
||||
}
|
||||
|
||||
void
|
||||
togglefullscreen(const Arg *arg)
|
||||
{
|
||||
@ -1153,8 +1136,8 @@ focusclient(Client *c, int lift)
|
||||
wl_list_remove(&c->flink);
|
||||
wl_list_insert(&fstack, &c->flink);
|
||||
selmon = c->mon;
|
||||
c->isurgent = 0;
|
||||
}
|
||||
printstatus();
|
||||
|
||||
/* Deactivate old client if focus is changing */
|
||||
if (old && (!c || client_surface(c) != old)) {
|
||||
@ -1177,6 +1160,8 @@ focusclient(Client *c, int lift)
|
||||
}
|
||||
}
|
||||
|
||||
printstatus();
|
||||
|
||||
if (!c) {
|
||||
/* With no client, all we have left is to clear focus */
|
||||
wlr_seat_keyboard_notify_clear_focus(seat);
|
||||
@ -1237,14 +1222,6 @@ focustop(Monitor *m)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
getxdecomode(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct wlr_xdg_toplevel_decoration_v1 *wlr_deco = data;
|
||||
wlr_xdg_toplevel_decoration_v1_set_mode(wlr_deco,
|
||||
WLR_XDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE);
|
||||
}
|
||||
|
||||
void
|
||||
incnmaster(const Arg *arg)
|
||||
{
|
||||
@ -1391,6 +1368,9 @@ mapnotify(struct wl_listener *listener, void *data)
|
||||
c->geom.width += 2 * c->bw;
|
||||
c->geom.height += 2 * c->bw;
|
||||
|
||||
/* Tell the client not to try anything fancy */
|
||||
client_set_tiled(c, WLR_EDGE_TOP | WLR_EDGE_BOTTOM | WLR_EDGE_LEFT | WLR_EDGE_RIGHT);
|
||||
|
||||
/* Set initial monitor, tags, floating status, and focus */
|
||||
applyrules(c);
|
||||
|
||||
@ -1666,22 +1646,29 @@ void
|
||||
printstatus(void)
|
||||
{
|
||||
Monitor *m = NULL;
|
||||
Client *c = NULL;
|
||||
unsigned int activetags;
|
||||
Client *c;
|
||||
unsigned int occ, urg, sel;
|
||||
|
||||
wl_list_for_each(m, &mons, link) {
|
||||
activetags=0;
|
||||
occ = urg = 0;
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
if (c->mon == m)
|
||||
activetags |= c->tags;
|
||||
if (c->mon != m)
|
||||
continue;
|
||||
occ |= c->tags;
|
||||
if (c->isurgent)
|
||||
urg |= c->tags;
|
||||
}
|
||||
if (focustop(m))
|
||||
if ((c = focustop(m))) {
|
||||
printf("%s title %s\n", m->wlr_output->name, client_get_title(focustop(m)));
|
||||
else
|
||||
sel = c->tags;
|
||||
} else {
|
||||
printf("%s title \n", m->wlr_output->name);
|
||||
sel = 0;
|
||||
}
|
||||
|
||||
printf("%s selmon %u\n", m->wlr_output->name, m == selmon);
|
||||
printf("%s tags %u %u\n", m->wlr_output->name, activetags, m->tagset[m->seltags]);
|
||||
printf("%s tags %u %u %u %u\n", m->wlr_output->name, occ, m->tagset[m->seltags],
|
||||
sel, urg);
|
||||
printf("%s layout %s\n", m->wlr_output->name, m->lt[m->sellt]->symbol);
|
||||
}
|
||||
fflush(stdout);
|
||||
@ -1693,6 +1680,12 @@ quit(const Arg *arg)
|
||||
wl_display_terminate(dpy);
|
||||
}
|
||||
|
||||
void
|
||||
quitsignal(int signo)
|
||||
{
|
||||
quit(NULL);
|
||||
}
|
||||
|
||||
void
|
||||
render(struct wlr_surface *surface, int sx, int sy, void *data)
|
||||
{
|
||||
@ -1749,6 +1742,8 @@ render(struct wlr_surface *surface, int sx, int sy, void *data)
|
||||
/* This lets the client know that we've displayed that frame and it can
|
||||
* prepare another one now if it likes. */
|
||||
wlr_surface_send_frame_done(surface, rdata->when);
|
||||
|
||||
wlr_presentation_surface_sampled_on_output(presentation, surface, output);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1911,6 +1906,27 @@ run(char *startup_cmd)
|
||||
const char *socket = wl_display_add_socket_auto(dpy);
|
||||
if (!socket)
|
||||
BARF("startup: display_add_socket_auto");
|
||||
setenv("WAYLAND_DISPLAY", socket, 1);
|
||||
|
||||
/* Now that the socket exists, run the startup command */
|
||||
if (startup_cmd) {
|
||||
int piperw[2];
|
||||
pipe(piperw);
|
||||
startup_pid = fork();
|
||||
if (startup_pid < 0)
|
||||
EBARF("startup: fork");
|
||||
if (startup_pid == 0) {
|
||||
dup2(piperw[0], STDIN_FILENO);
|
||||
close(piperw[1]);
|
||||
execl("/bin/sh", "/bin/sh", "-c", startup_cmd, NULL);
|
||||
EBARF("startup: execl");
|
||||
}
|
||||
dup2(piperw[1], STDOUT_FILENO);
|
||||
close(piperw[0]);
|
||||
}
|
||||
/* If nobody is reading the status output, don't terminate */
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
printstatus();
|
||||
|
||||
/* Start the backend. This will enumerate outputs and inputs, become the DRM
|
||||
* master, etc */
|
||||
@ -1928,21 +1944,6 @@ run(char *startup_cmd)
|
||||
wlr_cursor_warp_closest(cursor, NULL, cursor->x, cursor->y);
|
||||
wlr_xcursor_manager_set_cursor_image(cursor_mgr, "left_ptr", cursor);
|
||||
|
||||
/* Set the WAYLAND_DISPLAY environment variable to our socket and run the
|
||||
* startup command if requested. */
|
||||
setenv("WAYLAND_DISPLAY", socket, 1);
|
||||
|
||||
if (startup_cmd) {
|
||||
startup_pid = fork();
|
||||
if (startup_pid < 0)
|
||||
EBARF("startup: fork");
|
||||
if (startup_pid == 0) {
|
||||
dup2(STDERR_FILENO, STDOUT_FILENO);
|
||||
execl("/bin/sh", "/bin/sh", "-c", startup_cmd, NULL);
|
||||
EBARF("startup: execl");
|
||||
}
|
||||
}
|
||||
|
||||
/* Run the Wayland event loop. This does not return until you exit the
|
||||
* compositor. Starting the backend rigged up all of the necessary event
|
||||
* loop configuration to listen to libinput events, DRM events, generate
|
||||
@ -2079,8 +2080,10 @@ setup(void)
|
||||
* clients from the Unix socket, manging Wayland globals, and so on. */
|
||||
dpy = wl_display_create();
|
||||
|
||||
/* clean up child processes immediately */
|
||||
/* Set up signal handlers */
|
||||
sigchld(0);
|
||||
signal(SIGINT, quitsignal);
|
||||
signal(SIGTERM, quitsignal);
|
||||
|
||||
/* The backend is a wlroots feature which abstracts the underlying input and
|
||||
* output hardware. The autocreate option will choose the most suitable
|
||||
@ -2114,6 +2117,10 @@ setup(void)
|
||||
wlr_primary_selection_v1_device_manager_create(dpy);
|
||||
wlr_viewporter_create(dpy);
|
||||
|
||||
/* Initializes the interface used to implement urgency hints */
|
||||
activation = wlr_xdg_activation_v1_create(dpy);
|
||||
wl_signal_add(&activation->events.request_activate, &request_activate);
|
||||
|
||||
/* Creates an output layout, which a wlroots utility for working with an
|
||||
* arrangement of screens in a physical layout. */
|
||||
output_layout = wlr_output_layout_create();
|
||||
@ -2145,9 +2152,11 @@ setup(void)
|
||||
xdg_shell = wlr_xdg_shell_create(dpy);
|
||||
wl_signal_add(&xdg_shell->events.new_surface, &new_xdg_surface);
|
||||
|
||||
/* Use xdg_decoration protocol to negotiate server-side decorations */
|
||||
xdeco_mgr = wlr_xdg_decoration_manager_v1_create(dpy);
|
||||
wl_signal_add(&xdeco_mgr->events.new_toplevel_decoration, &new_xdeco);
|
||||
/* Use decoration protocols to negotiate server-side decorations */
|
||||
wlr_server_decoration_manager_set_default_mode(
|
||||
wlr_server_decoration_manager_create(dpy),
|
||||
WLR_SERVER_DECORATION_MANAGER_MODE_SERVER);
|
||||
wlr_xdg_decoration_manager_v1_create(dpy);
|
||||
|
||||
/*
|
||||
* Creates a cursor, which is a wlroots utility for tracking the cursor
|
||||
@ -2203,6 +2212,8 @@ setup(void)
|
||||
wl_signal_add(&output_mgr->events.apply, &output_mgr_apply);
|
||||
wl_signal_add(&output_mgr->events.test, &output_mgr_test);
|
||||
|
||||
presentation = wlr_presentation_create(dpy, backend);
|
||||
|
||||
#ifdef XWAYLAND
|
||||
/*
|
||||
* Initialise the XWayland X server.
|
||||
@ -2430,6 +2441,29 @@ updatemons(struct wl_listener *listener, void *data)
|
||||
wlr_output_manager_v1_set_configuration(output_mgr, config);
|
||||
}
|
||||
|
||||
void
|
||||
updatetitle(struct wl_listener *listener, void *data)
|
||||
{
|
||||
Client *c = wl_container_of(listener, c, set_title);
|
||||
if (c == focustop(c->mon))
|
||||
printstatus();
|
||||
}
|
||||
|
||||
void
|
||||
urgent(struct wl_listener *listener, void *data)
|
||||
{
|
||||
struct wlr_xdg_activation_v1_request_activate_event *event = data;
|
||||
Client *c;
|
||||
|
||||
if (!wlr_surface_is_xdg_surface(event->surface))
|
||||
return;
|
||||
c = wlr_xdg_surface_from_wlr_surface(event->surface)->data;
|
||||
if (c != selclient()) {
|
||||
c->isurgent = 1;
|
||||
printstatus();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
view(const Arg *arg)
|
||||
{
|
||||
@ -2566,6 +2600,7 @@ createnotifyx11(struct wl_listener *listener, void *data)
|
||||
activatex11);
|
||||
LISTEN(&xwayland_surface->events.request_configure, &c->configure,
|
||||
configurex11);
|
||||
LISTEN(&xwayland_surface->events.set_title, &c->set_title, updatetitle);
|
||||
LISTEN(&xwayland_surface->events.destroy, &c->destroy, destroynotify);
|
||||
LISTEN(&xwayland_surface->events.request_fullscreen, &c->fullscreen,
|
||||
fullscreennotify);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user