forked from mirror/dwl
Merge remote-tracking branch 'djpohly/main' into HEAD
This commit is contained in:
commit
29a2b647b2
6 changed files with 230 additions and 165 deletions
12
Makefile
12
Makefile
|
@ -1,6 +1,6 @@
|
||||||
include config.mk
|
include config.mk
|
||||||
|
|
||||||
CFLAGS += -I. -DWLR_USE_UNSTABLE -std=c99
|
CFLAGS += -I. -DWLR_USE_UNSTABLE -std=c99 -pedantic
|
||||||
|
|
||||||
WAYLAND_PROTOCOLS=$(shell pkg-config --variable=pkgdatadir wayland-protocols)
|
WAYLAND_PROTOCOLS=$(shell pkg-config --variable=pkgdatadir wayland-protocols)
|
||||||
WAYLAND_SCANNER=$(shell pkg-config --variable=wayland_scanner wayland-scanner)
|
WAYLAND_SCANNER=$(shell pkg-config --variable=wayland_scanner wayland-scanner)
|
||||||
|
@ -15,11 +15,11 @@ clean:
|
||||||
rm -f dwl *.o *-protocol.h *-protocol.c
|
rm -f dwl *.o *-protocol.h *-protocol.c
|
||||||
|
|
||||||
install: dwl
|
install: dwl
|
||||||
install -Dm755 dwl $(PREFIX)/bin/dwl
|
install -Dm755 dwl $(DESTDIR)$(PREFIX)/bin/dwl
|
||||||
install -Dm644 dwl.1 $(MANDIR)/man1/dwl.1
|
install -Dm644 dwl.1 $(DESTDIR)$(MANDIR)/man1/dwl.1
|
||||||
|
|
||||||
uninstall:
|
uninstall:
|
||||||
rm -f $(PREFIX)/bin/dwl $(MANDIR)/man1/dwl.1
|
rm -f $(DESTDIR)$(PREFIX)/bin/dwl $(DESTDIR)$(MANDIR)/man1/dwl.1
|
||||||
|
|
||||||
.PHONY: all clean install uninstall
|
.PHONY: all clean install uninstall
|
||||||
|
|
||||||
|
@ -59,6 +59,6 @@ idle-protocol.o: idle-protocol.h
|
||||||
config.h: | config.def.h
|
config.h: | config.def.h
|
||||||
cp config.def.h $@
|
cp config.def.h $@
|
||||||
|
|
||||||
dwl.o: config.mk 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 util.h
|
||||||
|
|
||||||
dwl: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o idle-protocol.o
|
dwl: xdg-shell-protocol.o wlr-layer-shell-unstable-v1-protocol.o idle-protocol.o util.o
|
||||||
|
|
|
@ -14,8 +14,10 @@ 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.
|
- 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 multi-monitor layout support, including position and rotation
|
||||||
- Configurable HiDPI/multi-DPI support
|
- Configurable HiDPI/multi-DPI support
|
||||||
|
- Idle-inhibit protocol which lets applications such as mpv disable idle monitoring
|
||||||
- Provide information to external status bars via stdout/stdin
|
- Provide information to external status bars via stdout/stdin
|
||||||
- Urgency hints via xdg-activate protocol
|
- Urgency hints via xdg-activate protocol
|
||||||
|
- Support screen lockers via input-inhibitor protocol
|
||||||
- Various Wayland protocols
|
- Various Wayland protocols
|
||||||
- XWayland support as provided by wlroots (can be enabled in `config.mk`)
|
- XWayland support as provided by wlroots (can be enabled in `config.mk`)
|
||||||
- Zero flickering - Wayland users naturally expect that "every frame is perfect"
|
- Zero flickering - Wayland users naturally expect that "every frame is perfect"
|
||||||
|
@ -25,8 +27,6 @@ dwl is not meant to provide every feature under the sun. Instead, like dwm, it s
|
||||||
Features under consideration (possibly as patches) are:
|
Features under consideration (possibly as patches) are:
|
||||||
|
|
||||||
- Protocols made trivial by wlroots
|
- Protocols made trivial by wlroots
|
||||||
- Implement the input-inhibitor protocol to support screen lockers (see https://github.com/djpohly/dwl/pull/132)
|
|
||||||
- Implement the idle-inhibit protocol which lets applications such as mpv disable idle monitoring (see https://github.com/djpohly/dwl/pull/133)
|
|
||||||
- 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 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)
|
||||||
|
|
||||||
Feature *non-goals* for the main codebase include:
|
Feature *non-goals* for the main codebase include:
|
||||||
|
|
13
config.def.h
13
config.def.h
|
@ -13,8 +13,8 @@ static const Rule rules[] = {
|
||||||
/* app_id title tags mask isfloating monitor */
|
/* app_id title tags mask isfloating monitor */
|
||||||
/* examples:
|
/* examples:
|
||||||
{ "Gimp", NULL, 0, 1, -1 },
|
{ "Gimp", NULL, 0, 1, -1 },
|
||||||
{ "firefox", NULL, 1 << 8, 0, -1 },
|
|
||||||
*/
|
*/
|
||||||
|
{ "firefox", NULL, 1 << 8, 0, -1 },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* layout(s) */
|
/* layout(s) */
|
||||||
|
@ -25,16 +25,14 @@ static const Layout layouts[] = {
|
||||||
{ "[M]", monocle },
|
{ "[M]", monocle },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* monitors
|
/* monitors */
|
||||||
* The order in which monitors are defined determines their position.
|
|
||||||
* Non-configured monitors are always added to the left. */
|
|
||||||
static const MonitorRule monrules[] = {
|
static const MonitorRule monrules[] = {
|
||||||
/* name mfact nmaster scale layout rotate/reflect x y */
|
/* name mfact nmaster scale layout rotate/reflect */
|
||||||
/* example of a HiDPI laptop monitor:
|
/* example of a HiDPI laptop monitor:
|
||||||
{ "eDP-1", 0.5, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, 0, 0 },
|
{ "eDP-1", 0.5, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL },
|
||||||
*/
|
*/
|
||||||
/* defaults */
|
/* defaults */
|
||||||
{ NULL, 0.55, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, 0, 0 },
|
{ NULL, 0.55, 1, 1, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* keyboard */
|
/* keyboard */
|
||||||
|
@ -43,6 +41,7 @@ static const struct xkb_rule_names xkb_rules = {
|
||||||
/* example:
|
/* example:
|
||||||
.options = "ctrl:nocaps",
|
.options = "ctrl:nocaps",
|
||||||
*/
|
*/
|
||||||
|
.options = "",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int repeat_rate = 25;
|
static const int repeat_rate = 25;
|
||||||
|
|
327
dwl.c
327
dwl.c
|
@ -3,6 +3,7 @@
|
||||||
*/
|
*/
|
||||||
#define _POSIX_C_SOURCE 200809L
|
#define _POSIX_C_SOURCE 200809L
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
|
#include <libinput.h>
|
||||||
#include <linux/input-event-codes.h>
|
#include <linux/input-event-codes.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -10,9 +11,9 @@
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <libinput.h>
|
|
||||||
#include <wayland-server-core.h>
|
#include <wayland-server-core.h>
|
||||||
#include <wlr/backend.h>
|
#include <wlr/backend.h>
|
||||||
|
#include <wlr/backend/libinput.h>
|
||||||
#include <wlr/render/allocator.h>
|
#include <wlr/render/allocator.h>
|
||||||
#include <wlr/render/wlr_renderer.h>
|
#include <wlr/render/wlr_renderer.h>
|
||||||
#include <wlr/types/wlr_compositor.h>
|
#include <wlr/types/wlr_compositor.h>
|
||||||
|
@ -21,11 +22,12 @@
|
||||||
#include <wlr/types/wlr_data_device.h>
|
#include <wlr/types/wlr_data_device.h>
|
||||||
#include <wlr/types/wlr_export_dmabuf_v1.h>
|
#include <wlr/types/wlr_export_dmabuf_v1.h>
|
||||||
#include <wlr/types/wlr_gamma_control_v1.h>
|
#include <wlr/types/wlr_gamma_control_v1.h>
|
||||||
#include <wlr/types/wlr_input_device.h>
|
|
||||||
#include <wlr/types/wlr_idle.h>
|
#include <wlr/types/wlr_idle.h>
|
||||||
#include <wlr/types/wlr_layer_shell_v1.h>
|
#include <wlr/types/wlr_idle_inhibit_v1.h>
|
||||||
|
#include <wlr/types/wlr_input_device.h>
|
||||||
|
#include <wlr/types/wlr_input_inhibitor.h>
|
||||||
#include <wlr/types/wlr_keyboard.h>
|
#include <wlr/types/wlr_keyboard.h>
|
||||||
#include <wlr/types/wlr_matrix.h>
|
#include <wlr/types/wlr_layer_shell_v1.h>
|
||||||
#include <wlr/types/wlr_output.h>
|
#include <wlr/types/wlr_output.h>
|
||||||
#include <wlr/types/wlr_output_layout.h>
|
#include <wlr/types/wlr_output_layout.h>
|
||||||
#include <wlr/types/wlr_output_management_v1.h>
|
#include <wlr/types/wlr_output_management_v1.h>
|
||||||
|
@ -33,10 +35,10 @@
|
||||||
#include <wlr/types/wlr_presentation_time.h>
|
#include <wlr/types/wlr_presentation_time.h>
|
||||||
#include <wlr/types/wlr_primary_selection.h>
|
#include <wlr/types/wlr_primary_selection.h>
|
||||||
#include <wlr/types/wlr_primary_selection_v1.h>
|
#include <wlr/types/wlr_primary_selection_v1.h>
|
||||||
#include <wlr/types/wlr_screencopy_v1.h>
|
|
||||||
#include <wlr/types/wlr_scene.h>
|
#include <wlr/types/wlr_scene.h>
|
||||||
#include <wlr/types/wlr_server_decoration.h>
|
#include <wlr/types/wlr_screencopy_v1.h>
|
||||||
#include <wlr/types/wlr_seat.h>
|
#include <wlr/types/wlr_seat.h>
|
||||||
|
#include <wlr/types/wlr_server_decoration.h>
|
||||||
#include <wlr/types/wlr_subcompositor.h>
|
#include <wlr/types/wlr_subcompositor.h>
|
||||||
#include <wlr/types/wlr_viewporter.h>
|
#include <wlr/types/wlr_viewporter.h>
|
||||||
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
#include <wlr/types/wlr_virtual_keyboard_v1.h>
|
||||||
|
@ -45,7 +47,6 @@
|
||||||
#include <wlr/types/wlr_xdg_decoration_v1.h>
|
#include <wlr/types/wlr_xdg_decoration_v1.h>
|
||||||
#include <wlr/types/wlr_xdg_output_v1.h>
|
#include <wlr/types/wlr_xdg_output_v1.h>
|
||||||
#include <wlr/types/wlr_xdg_shell.h>
|
#include <wlr/types/wlr_xdg_shell.h>
|
||||||
#include <wlr/backend/libinput.h>
|
|
||||||
#include <wlr/util/log.h>
|
#include <wlr/util/log.h>
|
||||||
#include <xkbcommon/xkbcommon.h>
|
#include <xkbcommon/xkbcommon.h>
|
||||||
#ifdef XWAYLAND
|
#ifdef XWAYLAND
|
||||||
|
@ -53,9 +54,9 @@
|
||||||
#include <wlr/xwayland.h>
|
#include <wlr/xwayland.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
/* macros */
|
/* macros */
|
||||||
#define BARF(fmt, ...) do { fprintf(stderr, fmt "\n", ##__VA_ARGS__); exit(EXIT_FAILURE); } while (0)
|
|
||||||
#define EBARF(fmt, ...) BARF(fmt ": %s", ##__VA_ARGS__, strerror(errno))
|
|
||||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||||
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||||
#define CLEANMASK(mask) (mask & ~WLR_MODIFIER_CAPS)
|
#define CLEANMASK(mask) (mask & ~WLR_MODIFIER_CAPS)
|
||||||
|
@ -139,6 +140,7 @@ typedef struct {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* Must be first */
|
/* Must be first */
|
||||||
unsigned int type; /* LayerShell */
|
unsigned int type; /* LayerShell */
|
||||||
|
int mapped;
|
||||||
struct wlr_scene_node *scene;
|
struct wlr_scene_node *scene;
|
||||||
struct wlr_scene_layer_surface_v1 *scene_layer;
|
struct wlr_scene_layer_surface_v1 *scene_layer;
|
||||||
struct wl_list link;
|
struct wl_list link;
|
||||||
|
@ -180,8 +182,6 @@ typedef struct {
|
||||||
float scale;
|
float scale;
|
||||||
const Layout *lt;
|
const Layout *lt;
|
||||||
enum wl_output_transform rr;
|
enum wl_output_transform rr;
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
} MonitorRule;
|
} MonitorRule;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -208,12 +208,14 @@ static void cleanupmon(struct wl_listener *listener, void *data);
|
||||||
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 commitnotify(struct wl_listener *listener, void *data);
|
static void commitnotify(struct wl_listener *listener, void *data);
|
||||||
|
static void createidleinhibitor(struct wl_listener *listener, void *data);
|
||||||
static void createkeyboard(struct wlr_keyboard *keyboard);
|
static void createkeyboard(struct wlr_keyboard *keyboard);
|
||||||
|
static void createlayersurface(struct wl_listener *listener, void *data);
|
||||||
static void createmon(struct wl_listener *listener, void *data);
|
static void createmon(struct wl_listener *listener, void *data);
|
||||||
static void createnotify(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_pointer *pointer);
|
static void createpointer(struct wlr_pointer *pointer);
|
||||||
static void cursorframe(struct wl_listener *listener, void *data);
|
static void cursorframe(struct wl_listener *listener, void *data);
|
||||||
|
static void destroyidleinhibitor(struct wl_listener *listener, void *data);
|
||||||
static void destroylayersurfacenotify(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(struct wl_listener *listener, void *data);
|
||||||
static Monitor *dirtomon(enum wlr_direction dir);
|
static Monitor *dirtomon(enum wlr_direction dir);
|
||||||
|
@ -221,8 +223,8 @@ static void dragicondestroy(struct wl_listener *listener, void *data);
|
||||||
static void focusclient(Client *c, int lift);
|
static void focusclient(Client *c, 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 void fullscreennotify(struct wl_listener *listener, void *data);
|
|
||||||
static Client *focustop(Monitor *m);
|
static Client *focustop(Monitor *m);
|
||||||
|
static void fullscreennotify(struct wl_listener *listener, void *data);
|
||||||
static void incnmaster(const Arg *arg);
|
static void incnmaster(const Arg *arg);
|
||||||
static void inputdevice(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 int keybinding(uint32_t mods, xkb_keysym_t sym);
|
||||||
|
@ -250,13 +252,13 @@ static void resize(Client *c, int x, int y, int w, int h, int interact);
|
||||||
static void run(char *startup_cmd);
|
static void run(char *startup_cmd);
|
||||||
static Client *selclient(void);
|
static Client *selclient(void);
|
||||||
static void setcursor(struct wl_listener *listener, void *data);
|
static void setcursor(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 setfloating(Client *c, int floating);
|
static void setfloating(Client *c, int floating);
|
||||||
static void setfullscreen(Client *c, int fullscreen);
|
static void setfullscreen(Client *c, int fullscreen);
|
||||||
static void setlayout(const Arg *arg);
|
static void setlayout(const Arg *arg);
|
||||||
static void setmfact(const Arg *arg);
|
static void setmfact(const Arg *arg);
|
||||||
static void setmon(Client *c, Monitor *m, unsigned int newtags);
|
static void setmon(Client *c, Monitor *m, unsigned int newtags);
|
||||||
|
static void setpsel(struct wl_listener *listener, void *data);
|
||||||
|
static void setsel(struct wl_listener *listener, void *data);
|
||||||
static void setup(void);
|
static void setup(void);
|
||||||
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);
|
||||||
|
@ -275,9 +277,9 @@ static void updatetitle(struct wl_listener *listener, void *data);
|
||||||
static void urgent(struct wl_listener *listener, void *data);
|
static void urgent(struct wl_listener *listener, void *data);
|
||||||
static void view(const Arg *arg);
|
static void view(const Arg *arg);
|
||||||
static void virtualkeyboard(struct wl_listener *listener, void *data);
|
static void virtualkeyboard(struct wl_listener *listener, void *data);
|
||||||
|
static Monitor *xytomon(double x, double y);
|
||||||
static struct wlr_scene_node *xytonode(double x, double y, struct wlr_surface **psurface,
|
static struct wlr_scene_node *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);
|
||||||
static Monitor *xytomon(double x, double y);
|
|
||||||
static void zoom(const Arg *arg);
|
static void zoom(const Arg *arg);
|
||||||
|
|
||||||
/* variables */
|
/* variables */
|
||||||
|
@ -295,6 +297,8 @@ static struct wlr_xdg_activation_v1 *activation;
|
||||||
static struct wl_list clients; /* tiling order */
|
static struct wl_list clients; /* tiling order */
|
||||||
static struct wl_list fstack; /* focus order */
|
static struct wl_list fstack; /* focus order */
|
||||||
static struct wlr_idle *idle;
|
static struct wlr_idle *idle;
|
||||||
|
static struct wlr_idle_inhibit_manager_v1 *idle_inhibit_mgr;
|
||||||
|
static struct wlr_input_inhibit_manager *input_inhibit_mgr;
|
||||||
static struct wlr_layer_shell_v1 *layer_shell;
|
static struct wlr_layer_shell_v1 *layer_shell;
|
||||||
static struct wlr_output_manager_v1 *output_mgr;
|
static struct wlr_output_manager_v1 *output_mgr;
|
||||||
static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr;
|
static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr;
|
||||||
|
@ -319,6 +323,8 @@ static struct wl_listener cursor_button = {.notify = buttonpress};
|
||||||
static struct wl_listener cursor_frame = {.notify = cursorframe};
|
static struct wl_listener cursor_frame = {.notify = cursorframe};
|
||||||
static struct wl_listener cursor_motion = {.notify = motionrelative};
|
static struct wl_listener cursor_motion = {.notify = motionrelative};
|
||||||
static struct wl_listener cursor_motion_absolute = {.notify = motionabsolute};
|
static struct wl_listener cursor_motion_absolute = {.notify = motionabsolute};
|
||||||
|
static struct wl_listener idle_inhibitor_create = {.notify = createidleinhibitor};
|
||||||
|
static struct wl_listener idle_inhibitor_destroy = {.notify = destroyidleinhibitor};
|
||||||
static struct wl_listener layout_change = {.notify = updatemons};
|
static struct wl_listener layout_change = {.notify = updatemons};
|
||||||
static struct wl_listener new_input = {.notify = inputdevice};
|
static struct wl_listener new_input = {.notify = inputdevice};
|
||||||
static struct wl_listener new_virtual_keyboard = {.notify = virtualkeyboard};
|
static struct wl_listener new_virtual_keyboard = {.notify = virtualkeyboard};
|
||||||
|
@ -620,9 +626,14 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data)
|
||||||
wlr_scene_node_reparent(layersurface->scene,
|
wlr_scene_node_reparent(layersurface->scene,
|
||||||
layers[wlr_layer_surface->current.layer]);
|
layers[wlr_layer_surface->current.layer]);
|
||||||
|
|
||||||
if (!wlr_output)
|
if (!wlr_output || !(m = wlr_output->data))
|
||||||
return;
|
return;
|
||||||
m = wlr_output->data;
|
|
||||||
|
if (wlr_layer_surface->current.committed == 0
|
||||||
|
&& layersurface->mapped == wlr_layer_surface->mapped)
|
||||||
|
return;
|
||||||
|
|
||||||
|
layersurface->mapped = wlr_layer_surface->mapped;
|
||||||
|
|
||||||
if (layers[wlr_layer_surface->current.layer] != layersurface->scene) {
|
if (layers[wlr_layer_surface->current.layer] != layersurface->scene) {
|
||||||
wl_list_remove(&layersurface->link);
|
wl_list_remove(&layersurface->link);
|
||||||
|
@ -642,14 +653,21 @@ commitnotify(struct wl_listener *listener, void *data)
|
||||||
c->resize = 0;
|
c->resize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
createidleinhibitor(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct wlr_idle_inhibitor_v1 *idle_inhibitor = data;
|
||||||
|
wl_signal_add(&idle_inhibitor->events.destroy, &idle_inhibitor_destroy);
|
||||||
|
|
||||||
|
wlr_idle_set_enabled(idle, seat, 0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
createkeyboard(struct wlr_keyboard *keyboard)
|
createkeyboard(struct wlr_keyboard *keyboard)
|
||||||
{
|
{
|
||||||
struct xkb_context *context;
|
struct xkb_context *context;
|
||||||
struct xkb_keymap *keymap;
|
struct xkb_keymap *keymap;
|
||||||
Keyboard *kb = keyboard->data = calloc(1, sizeof(*kb));
|
Keyboard *kb = keyboard->data = ecalloc(1, sizeof(*kb));
|
||||||
if (!kb)
|
|
||||||
EBARF("createkeyboard: calloc");
|
|
||||||
kb->wlr_keyboard = keyboard;
|
kb->wlr_keyboard = keyboard;
|
||||||
|
|
||||||
/* Prepare an XKB keymap and assign it to the keyboard. */
|
/* Prepare an XKB keymap and assign it to the keyboard. */
|
||||||
|
@ -673,6 +691,52 @@ createkeyboard(struct wlr_keyboard *keyboard)
|
||||||
wl_list_insert(&keyboards, &kb->link);
|
wl_list_insert(&keyboards, &kb->link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
createlayersurface(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct wlr_layer_surface_v1 *wlr_layer_surface = data;
|
||||||
|
LayerSurface *layersurface;
|
||||||
|
Monitor *m;
|
||||||
|
struct wlr_layer_surface_v1_state old_state;
|
||||||
|
|
||||||
|
if (!wlr_layer_surface->output) {
|
||||||
|
wlr_layer_surface->output = selmon->wlr_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
layersurface = ecalloc(1, sizeof(LayerSurface));
|
||||||
|
layersurface->type = LayerShell;
|
||||||
|
LISTEN(&wlr_layer_surface->surface->events.commit,
|
||||||
|
&layersurface->surface_commit, commitlayersurfacenotify);
|
||||||
|
LISTEN(&wlr_layer_surface->events.destroy, &layersurface->destroy,
|
||||||
|
destroylayersurfacenotify);
|
||||||
|
LISTEN(&wlr_layer_surface->events.map, &layersurface->map,
|
||||||
|
maplayersurfacenotify);
|
||||||
|
LISTEN(&wlr_layer_surface->events.unmap, &layersurface->unmap,
|
||||||
|
unmaplayersurfacenotify);
|
||||||
|
|
||||||
|
layersurface->layer_surface = wlr_layer_surface;
|
||||||
|
wlr_layer_surface->data = layersurface;
|
||||||
|
m = wlr_layer_surface->output->data;
|
||||||
|
|
||||||
|
layersurface->scene_layer = wlr_scene_layer_surface_v1_create(
|
||||||
|
layers[wlr_layer_surface->pending.layer], wlr_layer_surface);
|
||||||
|
layersurface->scene = wlr_layer_surface->surface->data =
|
||||||
|
layersurface->scene_layer->node;
|
||||||
|
|
||||||
|
layersurface->scene->data = layersurface;
|
||||||
|
|
||||||
|
wl_list_insert(&m->layers[wlr_layer_surface->pending.layer],
|
||||||
|
&layersurface->link);
|
||||||
|
|
||||||
|
/* Temporarily set the layer's current state to pending
|
||||||
|
* so that we can easily arrange it
|
||||||
|
*/
|
||||||
|
old_state = wlr_layer_surface->current;
|
||||||
|
wlr_layer_surface->current = wlr_layer_surface->pending;
|
||||||
|
arrangelayers(m);
|
||||||
|
wlr_layer_surface->current = old_state;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
createmon(struct wl_listener *listener, void *data)
|
createmon(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
|
@ -680,9 +744,7 @@ createmon(struct wl_listener *listener, void *data)
|
||||||
* monitor) becomes available. */
|
* monitor) becomes available. */
|
||||||
struct wlr_output *wlr_output = data;
|
struct wlr_output *wlr_output = data;
|
||||||
const MonitorRule *r;
|
const MonitorRule *r;
|
||||||
Monitor *m = wlr_output->data = calloc(1, sizeof(*m));
|
Monitor *m = wlr_output->data = ecalloc(1, sizeof(*m));
|
||||||
if (!m)
|
|
||||||
EBARF("createmon: calloc");
|
|
||||||
m->wlr_output = wlr_output;
|
m->wlr_output = wlr_output;
|
||||||
|
|
||||||
wlr_output_init_render(wlr_output, alloc, drw);
|
wlr_output_init_render(wlr_output, alloc, drw);
|
||||||
|
@ -767,9 +829,7 @@ createnotify(struct wl_listener *listener, void *data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Allocate a Client for this surface */
|
/* Allocate a Client for this surface */
|
||||||
c = xdg_surface->data = calloc(1, sizeof(*c));
|
c = xdg_surface->data = ecalloc(1, sizeof(*c));
|
||||||
if (!c)
|
|
||||||
EBARF("createnotify: calloc");
|
|
||||||
c->surface.xdg = xdg_surface;
|
c->surface.xdg = xdg_surface;
|
||||||
c->bw = borderpx;
|
c->bw = borderpx;
|
||||||
|
|
||||||
|
@ -783,53 +843,6 @@ createnotify(struct wl_listener *listener, void *data)
|
||||||
c->isfullscreen = 0;
|
c->isfullscreen = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
createlayersurface(struct wl_listener *listener, void *data)
|
|
||||||
{
|
|
||||||
struct wlr_layer_surface_v1 *wlr_layer_surface = data;
|
|
||||||
LayerSurface *layersurface;
|
|
||||||
Monitor *m;
|
|
||||||
struct wlr_layer_surface_v1_state old_state;
|
|
||||||
|
|
||||||
if (!wlr_layer_surface->output) {
|
|
||||||
wlr_layer_surface->output = selmon->wlr_output;
|
|
||||||
}
|
|
||||||
|
|
||||||
layersurface = calloc(1, sizeof(LayerSurface));
|
|
||||||
if (!layersurface)
|
|
||||||
EBARF("layersurface: calloc");
|
|
||||||
layersurface->type = LayerShell;
|
|
||||||
LISTEN(&wlr_layer_surface->surface->events.commit,
|
|
||||||
&layersurface->surface_commit, commitlayersurfacenotify);
|
|
||||||
LISTEN(&wlr_layer_surface->events.destroy, &layersurface->destroy,
|
|
||||||
destroylayersurfacenotify);
|
|
||||||
LISTEN(&wlr_layer_surface->events.map, &layersurface->map,
|
|
||||||
maplayersurfacenotify);
|
|
||||||
LISTEN(&wlr_layer_surface->events.unmap, &layersurface->unmap,
|
|
||||||
unmaplayersurfacenotify);
|
|
||||||
|
|
||||||
layersurface->layer_surface = wlr_layer_surface;
|
|
||||||
wlr_layer_surface->data = layersurface;
|
|
||||||
m = wlr_layer_surface->output->data;
|
|
||||||
|
|
||||||
layersurface->scene_layer = wlr_scene_layer_surface_v1_create(
|
|
||||||
layers[wlr_layer_surface->pending.layer], wlr_layer_surface);
|
|
||||||
layersurface->scene = wlr_layer_surface->surface->data =
|
|
||||||
layersurface->scene_layer->node;
|
|
||||||
layersurface->scene->data = layersurface;
|
|
||||||
|
|
||||||
wl_list_insert(&m->layers[wlr_layer_surface->pending.layer],
|
|
||||||
&layersurface->link);
|
|
||||||
|
|
||||||
/* Temporarily set the layer's current state to pending
|
|
||||||
* so that we can easily arrange it
|
|
||||||
*/
|
|
||||||
old_state = wlr_layer_surface->current;
|
|
||||||
wlr_layer_surface->current = wlr_layer_surface->pending;
|
|
||||||
arrangelayers(m);
|
|
||||||
wlr_layer_surface->current = old_state;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
createpointer(struct wlr_pointer *pointer)
|
createpointer(struct wlr_pointer *pointer)
|
||||||
{
|
{
|
||||||
|
@ -862,6 +875,14 @@ cursorframe(struct wl_listener *listener, void *data)
|
||||||
wlr_seat_pointer_notify_frame(seat);
|
wlr_seat_pointer_notify_frame(seat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
destroyidleinhibitor(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
/* I've been testing and at this point the inhibitor has not yet been
|
||||||
|
* removed from the list, checking if it has at least one item. */
|
||||||
|
wlr_idle_set_enabled(idle, seat, wl_list_length(&idle_inhibit_mgr->inhibitors) <= 1);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
destroylayersurfacenotify(struct wl_listener *listener, void *data)
|
destroylayersurfacenotify(struct wl_listener *listener, void *data)
|
||||||
{
|
{
|
||||||
|
@ -903,57 +924,6 @@ destroynotify(struct wl_listener *listener, void *data)
|
||||||
free(c);
|
free(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
dragicondestroy(struct wl_listener *listener, void *data)
|
|
||||||
{
|
|
||||||
struct wlr_drag_icon *icon = data;
|
|
||||||
wlr_scene_node_destroy(icon->data);
|
|
||||||
// Focus enter isn't sent during drag, so refocus the focused node.
|
|
||||||
focusclient(selclient(), 1);
|
|
||||||
motionnotify(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
togglefullscreen(const Arg *arg)
|
|
||||||
{
|
|
||||||
Client *sel = selclient();
|
|
||||||
if (sel)
|
|
||||||
setfullscreen(sel, !sel->isfullscreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
setfullscreen(Client *c, int fullscreen)
|
|
||||||
{
|
|
||||||
c->isfullscreen = fullscreen;
|
|
||||||
c->bw = fullscreen ? 0 : borderpx;
|
|
||||||
client_set_fullscreen(c, fullscreen);
|
|
||||||
|
|
||||||
if (fullscreen) {
|
|
||||||
c->prev = c->geom;
|
|
||||||
resize(c, c->mon->m.x, c->mon->m.y, c->mon->m.width, c->mon->m.height, 0);
|
|
||||||
} else {
|
|
||||||
/* restore previous size instead of arrange for floating windows since
|
|
||||||
* client positions are set by the user and cannot be recalculated */
|
|
||||||
resize(c, c->prev.x, c->prev.y, c->prev.width, c->prev.height, 0);
|
|
||||||
}
|
|
||||||
arrange(c->mon);
|
|
||||||
printstatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
fullscreennotify(struct wl_listener *listener, void *data)
|
|
||||||
{
|
|
||||||
Client *c = wl_container_of(listener, c, fullscreen);
|
|
||||||
int fullscreen = client_wants_fullscreen(c);
|
|
||||||
|
|
||||||
if (!c->mon) {
|
|
||||||
/* if the client is not mapped yet, let mapnotify() call setfullscreen() */
|
|
||||||
c->isfullscreen = fullscreen;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
setfullscreen(c, fullscreen);
|
|
||||||
}
|
|
||||||
|
|
||||||
Monitor *
|
Monitor *
|
||||||
dirtomon(enum wlr_direction dir)
|
dirtomon(enum wlr_direction dir)
|
||||||
{
|
{
|
||||||
|
@ -968,6 +938,16 @@ dirtomon(enum wlr_direction dir)
|
||||||
return selmon;
|
return selmon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dragicondestroy(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
struct wlr_drag_icon *icon = data;
|
||||||
|
wlr_scene_node_destroy(icon->data);
|
||||||
|
// Focus enter isn't sent during drag, so refocus the focused node.
|
||||||
|
focusclient(selclient(), 1);
|
||||||
|
motionnotify(0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
focusclient(Client *c, int lift)
|
focusclient(Client *c, int lift)
|
||||||
{
|
{
|
||||||
|
@ -1021,6 +1001,7 @@ focusclient(Client *c, int lift)
|
||||||
}
|
}
|
||||||
|
|
||||||
printstatus();
|
printstatus();
|
||||||
|
wlr_idle_set_enabled(idle, seat, wl_list_empty(&idle_inhibit_mgr->inhibitors));
|
||||||
|
|
||||||
if (!c) {
|
if (!c) {
|
||||||
/* With no client, all we have left is to clear focus */
|
/* With no client, all we have left is to clear focus */
|
||||||
|
@ -1082,6 +1063,20 @@ focustop(Monitor *m)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
fullscreennotify(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
Client *c = wl_container_of(listener, c, fullscreen);
|
||||||
|
int fullscreen = client_wants_fullscreen(c);
|
||||||
|
|
||||||
|
if (!c->mon) {
|
||||||
|
/* if the client is not mapped yet, let mapnotify() call setfullscreen() */
|
||||||
|
c->isfullscreen = fullscreen;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setfullscreen(c, fullscreen);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
incnmaster(const Arg *arg)
|
incnmaster(const Arg *arg)
|
||||||
{
|
{
|
||||||
|
@ -1159,8 +1154,10 @@ keypress(struct wl_listener *listener, void *data)
|
||||||
|
|
||||||
wlr_idle_notify_activity(idle, seat);
|
wlr_idle_notify_activity(idle, seat);
|
||||||
|
|
||||||
/* On _press_, attempt to process a compositor keybinding. */
|
/* On _press_ if there is no active screen locker,
|
||||||
if (event->state == WL_KEYBOARD_KEY_STATE_PRESSED)
|
* attempt to process a compositor keybinding. */
|
||||||
|
if (!input_inhibit_mgr->active_inhibitor
|
||||||
|
&& event->state == WL_KEYBOARD_KEY_STATE_PRESSED)
|
||||||
for (i = 0; i < nsyms; i++)
|
for (i = 0; i < nsyms; i++)
|
||||||
handled = keybinding(mods, syms[i]) || handled;
|
handled = keybinding(mods, syms[i]) || handled;
|
||||||
|
|
||||||
|
@ -1591,22 +1588,22 @@ run(char *startup_cmd)
|
||||||
/* Add a Unix socket to the Wayland display. */
|
/* Add a Unix socket to the Wayland display. */
|
||||||
const char *socket = wl_display_add_socket_auto(dpy);
|
const char *socket = wl_display_add_socket_auto(dpy);
|
||||||
if (!socket)
|
if (!socket)
|
||||||
BARF("startup: display_add_socket_auto");
|
die("startup: display_add_socket_auto");
|
||||||
setenv("WAYLAND_DISPLAY", socket, 1);
|
setenv("WAYLAND_DISPLAY", socket, 1);
|
||||||
|
|
||||||
/* Now that the socket exists, run the startup command */
|
/* Now that the socket exists, run the startup command */
|
||||||
if (startup_cmd) {
|
if (startup_cmd) {
|
||||||
int piperw[2];
|
int piperw[2];
|
||||||
pipe(piperw);
|
if (pipe(piperw) < 0)
|
||||||
startup_pid = fork();
|
die("startup: pipe:");
|
||||||
if (startup_pid < 0)
|
if ((startup_pid = fork()) < 0)
|
||||||
EBARF("startup: fork");
|
die("startup: fork:");
|
||||||
if (startup_pid == 0) {
|
if (startup_pid == 0) {
|
||||||
dup2(piperw[0], STDIN_FILENO);
|
dup2(piperw[0], STDIN_FILENO);
|
||||||
close(piperw[0]);
|
close(piperw[0]);
|
||||||
close(piperw[1]);
|
close(piperw[1]);
|
||||||
execl("/bin/sh", "/bin/sh", "-c", startup_cmd, NULL);
|
execl("/bin/sh", "/bin/sh", "-c", startup_cmd, NULL);
|
||||||
EBARF("startup: execl");
|
die("startup: execl:");
|
||||||
}
|
}
|
||||||
dup2(piperw[1], STDOUT_FILENO);
|
dup2(piperw[1], STDOUT_FILENO);
|
||||||
close(piperw[1]);
|
close(piperw[1]);
|
||||||
|
@ -1619,7 +1616,7 @@ run(char *startup_cmd)
|
||||||
/* Start the backend. This will enumerate outputs and inputs, become the DRM
|
/* Start the backend. This will enumerate outputs and inputs, become the DRM
|
||||||
* master, etc */
|
* master, etc */
|
||||||
if (!wlr_backend_start(backend))
|
if (!wlr_backend_start(backend))
|
||||||
BARF("startup: backend_start");
|
die("startup: backend_start");
|
||||||
|
|
||||||
/* Now that outputs are initialized, choose initial selmon based on
|
/* Now that outputs are initialized, choose initial selmon based on
|
||||||
* cursor position, and set default cursor image */
|
* cursor position, and set default cursor image */
|
||||||
|
@ -1681,6 +1678,25 @@ setfloating(Client *c, int floating)
|
||||||
printstatus();
|
printstatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
setfullscreen(Client *c, int fullscreen)
|
||||||
|
{
|
||||||
|
c->isfullscreen = fullscreen;
|
||||||
|
c->bw = fullscreen ? 0 : borderpx;
|
||||||
|
client_set_fullscreen(c, fullscreen);
|
||||||
|
|
||||||
|
if (fullscreen) {
|
||||||
|
c->prev = c->geom;
|
||||||
|
resize(c, c->mon->m.x, c->mon->m.y, c->mon->m.width, c->mon->m.height, 0);
|
||||||
|
} else {
|
||||||
|
/* restore previous size instead of arrange for floating windows since
|
||||||
|
* client positions are set by the user and cannot be recalculated */
|
||||||
|
resize(c, c->prev.x, c->prev.y, c->prev.width, c->prev.height, 0);
|
||||||
|
}
|
||||||
|
arrange(c->mon);
|
||||||
|
printstatus();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
setlayout(const Arg *arg)
|
setlayout(const Arg *arg)
|
||||||
{
|
{
|
||||||
|
@ -1779,7 +1795,7 @@ setup(void)
|
||||||
* if the backend does not support hardware cursors (some older GPUs
|
* if the backend does not support hardware cursors (some older GPUs
|
||||||
* don't). */
|
* don't). */
|
||||||
if (!(backend = wlr_backend_autocreate(dpy)))
|
if (!(backend = wlr_backend_autocreate(dpy)))
|
||||||
BARF("couldn't create backend");
|
die("couldn't create backend");
|
||||||
|
|
||||||
/* Initialize the scene graph used to lay out windows */
|
/* Initialize the scene graph used to lay out windows */
|
||||||
scene = wlr_scene_create();
|
scene = wlr_scene_create();
|
||||||
|
@ -1793,12 +1809,12 @@ setup(void)
|
||||||
|
|
||||||
/* Create a renderer with the default implementation */
|
/* Create a renderer with the default implementation */
|
||||||
if (!(drw = wlr_renderer_autocreate(backend)))
|
if (!(drw = wlr_renderer_autocreate(backend)))
|
||||||
BARF("couldn't create renderer");
|
die("couldn't create renderer");
|
||||||
wlr_renderer_init_wl_display(drw, dpy);
|
wlr_renderer_init_wl_display(drw, dpy);
|
||||||
|
|
||||||
/* Create a default allocator */
|
/* Create a default allocator */
|
||||||
if (!(alloc = wlr_allocator_autocreate(backend, drw)))
|
if (!(alloc = wlr_allocator_autocreate(backend, drw)))
|
||||||
BARF("couldn't create allocator");
|
die("couldn't create allocator");
|
||||||
|
|
||||||
/* This creates some hands-off wlroots interfaces. The compositor is
|
/* This creates some hands-off wlroots interfaces. The compositor is
|
||||||
* necessary for clients to allocate surfaces and the data device manager
|
* necessary for clients to allocate surfaces and the data device manager
|
||||||
|
@ -1842,12 +1858,17 @@ setup(void)
|
||||||
|
|
||||||
idle = wlr_idle_create(dpy);
|
idle = wlr_idle_create(dpy);
|
||||||
|
|
||||||
|
idle_inhibit_mgr = wlr_idle_inhibit_v1_create(dpy);
|
||||||
|
wl_signal_add(&idle_inhibit_mgr->events.new_inhibitor, &idle_inhibitor_create);
|
||||||
|
|
||||||
layer_shell = wlr_layer_shell_v1_create(dpy);
|
layer_shell = wlr_layer_shell_v1_create(dpy);
|
||||||
wl_signal_add(&layer_shell->events.new_surface, &new_layer_shell_surface);
|
wl_signal_add(&layer_shell->events.new_surface, &new_layer_shell_surface);
|
||||||
|
|
||||||
xdg_shell = wlr_xdg_shell_create(dpy);
|
xdg_shell = wlr_xdg_shell_create(dpy);
|
||||||
wl_signal_add(&xdg_shell->events.new_surface, &new_xdg_surface);
|
wl_signal_add(&xdg_shell->events.new_surface, &new_xdg_surface);
|
||||||
|
|
||||||
|
input_inhibit_mgr = wlr_input_inhibit_manager_create(dpy);
|
||||||
|
|
||||||
/* Use decoration protocols to negotiate server-side decorations */
|
/* Use decoration protocols to negotiate server-side decorations */
|
||||||
wlr_server_decoration_manager_set_default_mode(
|
wlr_server_decoration_manager_set_default_mode(
|
||||||
wlr_server_decoration_manager_create(dpy),
|
wlr_server_decoration_manager_create(dpy),
|
||||||
|
@ -1933,7 +1954,7 @@ spawn(const Arg *arg)
|
||||||
dup2(STDERR_FILENO, STDOUT_FILENO);
|
dup2(STDERR_FILENO, STDOUT_FILENO);
|
||||||
setsid();
|
setsid();
|
||||||
execvp(((char **)arg->v)[0], (char **)arg->v);
|
execvp(((char **)arg->v)[0], (char **)arg->v);
|
||||||
EBARF("dwl: execvp %s failed", ((char **)arg->v)[0]);
|
die("dwl: execvp %s failed:", ((char **)arg->v)[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2013,6 +2034,14 @@ togglefloating(const Arg *arg)
|
||||||
setfloating(sel, !sel->isfloating);
|
setfloating(sel, !sel->isfloating);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
togglefullscreen(const Arg *arg)
|
||||||
|
{
|
||||||
|
Client *sel = selclient();
|
||||||
|
if (sel)
|
||||||
|
setfullscreen(sel, !sel->isfullscreen);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
toggletag(const Arg *arg)
|
toggletag(const Arg *arg)
|
||||||
{
|
{
|
||||||
|
@ -2167,6 +2196,13 @@ virtualkeyboard(struct wl_listener *listener, void *data)
|
||||||
createkeyboard(device->keyboard);
|
createkeyboard(device->keyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Monitor *
|
||||||
|
xytomon(double x, double y)
|
||||||
|
{
|
||||||
|
struct wlr_output *o = wlr_output_layout_output_at(output_layout, x, y);
|
||||||
|
return o ? o->data : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
struct wlr_scene_node *
|
struct wlr_scene_node *
|
||||||
xytonode(double x, double y, struct wlr_surface **psurface,
|
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)
|
||||||
|
@ -2200,13 +2236,6 @@ xytonode(double x, double y, struct wlr_surface **psurface,
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
Monitor *
|
|
||||||
xytomon(double x, double y)
|
|
||||||
{
|
|
||||||
struct wlr_output *o = wlr_output_layout_output_at(output_layout, x, y);
|
|
||||||
return o ? o->data : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
zoom(const Arg *arg)
|
zoom(const Arg *arg)
|
||||||
{
|
{
|
||||||
|
@ -2269,9 +2298,7 @@ createnotifyx11(struct wl_listener *listener, void *data)
|
||||||
setfullscreen(c, 0);
|
setfullscreen(c, 0);
|
||||||
|
|
||||||
/* Allocate a Client for this surface */
|
/* Allocate a Client for this surface */
|
||||||
c = xwayland_surface->data = calloc(1, sizeof(*c));
|
c = xwayland_surface->data = ecalloc(1, sizeof(*c));
|
||||||
if (!c)
|
|
||||||
EBARF("createnotifyx11: calloc");
|
|
||||||
c->surface.xwayland = xwayland_surface;
|
c->surface.xwayland = xwayland_surface;
|
||||||
c->type = xwayland_surface->override_redirect ? X11Unmanaged : X11Managed;
|
c->type = xwayland_surface->override_redirect ? X11Unmanaged : X11Managed;
|
||||||
c->bw = borderpx;
|
c->bw = borderpx;
|
||||||
|
@ -2370,12 +2397,12 @@ main(int argc, char *argv[])
|
||||||
|
|
||||||
/* Wayland requires XDG_RUNTIME_DIR for creating its communications socket */
|
/* Wayland requires XDG_RUNTIME_DIR for creating its communications socket */
|
||||||
if (!getenv("XDG_RUNTIME_DIR"))
|
if (!getenv("XDG_RUNTIME_DIR"))
|
||||||
BARF("XDG_RUNTIME_DIR must be set");
|
die("XDG_RUNTIME_DIR must be set");
|
||||||
setup();
|
setup();
|
||||||
run(startup_cmd);
|
run(startup_cmd);
|
||||||
cleanup();
|
cleanup();
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
|
||||||
usage:
|
usage:
|
||||||
BARF("Usage: %s [-s startup command]", argv[0]);
|
die("Usage: %s [-s startup command]", argv[0]);
|
||||||
}
|
}
|
||||||
|
|
35
util.c
Normal file
35
util.c
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/* See LICENSE.dwm file for copyright and license details. */
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
void *
|
||||||
|
ecalloc(size_t nmemb, size_t size)
|
||||||
|
{
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
if (!(p = calloc(nmemb, size)))
|
||||||
|
die("calloc:");
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
die(const char *fmt, ...) {
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vfprintf(stderr, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if (fmt[0] && fmt[strlen(fmt)-1] == ':') {
|
||||||
|
fputc(' ', stderr);
|
||||||
|
perror(NULL);
|
||||||
|
} else {
|
||||||
|
fputc('\n', stderr);
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(1);
|
||||||
|
}
|
4
util.h
Normal file
4
util.h
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
/* See LICENSE.dwm file for copyright and license details. */
|
||||||
|
|
||||||
|
void die(const char *fmt, ...);
|
||||||
|
void *ecalloc(size_t nmemb, size_t size);
|
Loading…
Reference in a new issue