Compare commits

...

46 commits
bwaaa ... main

Author SHA1 Message Date
Leonardo Hernández Hernández 002c7d2204
tell xwayland clients they're maximized
like we do to xdg clients when tiled state is not supported.
2024-09-21 21:00:47 -06:00
Guido Cella 8206cc8889 fix a use after free
This line makes dwl crash after closing mpv with the switchtotag patch.
2024-09-12 04:33:19 +00:00
Guido Cella 54f207839f reorder config.mk variables
By placing the default WLR_INCS and WLR_LIBS before the ones for an
alternative wlroots, they don't need to be commented to enable the
alternative ones.
2024-09-08 20:51:41 +02:00
Leonardo Hernández Hernández 9c05b9622c
fix style for client_set_scale() 2024-08-30 22:29:08 -06:00
choc d34be5d545
remove unused link member from KeyboardGroup
unnecessary since grouping Keyboard wl_list to use wlr_keyboard_group in 023efce

ΔSLOC: -1
2024-08-27 23:12:00 -06:00
Leonardo Hernández Hernández c49312f084
disable scene node unless it is unmanaged 2024-08-27 23:09:46 -06:00
Leonardo Hernández Hernández f899060965
send a configure to unmanaged clients when mapping 2024-08-27 23:09:46 -06:00
Leonardo Hernández Hernández cc72df11d6
configure xdg_toplevels after configuring it's decoration 2024-08-27 23:09:46 -06:00
Leonardo Hernández Hernández 0312720ae8
remove a space before parenthesis in function calls 2024-08-27 23:09:46 -06:00
Leonardo Hernández Hernández 6de87121e2
destroy popups when we can't get it's parent or they don't have monitor 2024-08-27 23:09:46 -06:00
Leonardo Hernández Hernández bbc00d88a4
remove a redundant check
resize() now does the same check
2024-08-27 23:09:46 -06:00
Leonardo Hernández Hernández 54b546121b
avoid using a else block 2024-08-27 23:09:46 -06:00
Leonardo Hernández Hernández 43016bdad8
introduce client_set_scale() 2024-08-27 23:09:41 -06:00
Leonardo Hernández Hernández b616476c85
remove unnecessary LayerShell.geom
We only used geom.x and geom.y. We can access those variables directly from the
scene node.
2024-08-27 23:09:08 -06:00
Leonardo Hernández Hernández d4ad37354e
update comment about first fields of Client and LayerSurface order 2024-08-27 23:09:08 -06:00
Leonardo Hernández Hernández 5db05e82bd
fix style in configurex11() 2024-08-27 23:09:08 -06:00
Leonardo Hernández Hernández 8ec5e52e06
fix crash when a client is created while all outputs are disabled 2024-08-26 21:56:10 -06:00
Leonardo Hernández Hernández c5275ca571
state that the Discord server is community-maintained
Previously I regularly checked the server but it has been quite a long time
since I was able to do it.
2024-08-18 19:24:04 -06:00
A Frederick Christensen 2c0b889f86
Update CHANGELOG.md 2024-08-18 19:23:56 -06:00
Leonardo Hernández Hernández 554754c9a2
chase xdg_surface geometry changes (wlroots!4788)
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4788
2024-08-14 13:37:14 -06:00
Leonardo Hernández Hernández 0caa658276
use wlr_scene_set_gamma_control_manager_v1() (wlroots!4192)
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4192
2024-08-14 12:21:27 -06:00
Leonardo Hernández Hernández 07aeef1f7e
guarantee client_get_{title,appid} never return NULL
ΔSLOC: -6
2024-08-14 12:19:37 -06:00
Leonardo Hernández Hernández e454f7ae81
allow the use of non-system wlroots library
References: https://codeberg.org/dwl/dwl/issues/646#issuecomment-2032644
2024-08-14 12:00:52 -06:00
Leonardo Hernández Hernández 334bbe6f0f
fix potential crash in configurex11()
We can't call resize() on unmanaged clients because they don't have borders and
resize() requires them.

Fixes: 94f4ead7da
2024-08-10 10:47:48 -06:00
Leonardo Hernández Hernández 1b805ddd38
account border width in configurex11()
Fixes: 13925eb1da
2024-08-08 14:46:25 -06:00
Leonardo Hernández Hernández 94f4ead7da
actually move unmanaged clients in configurex11()
only calling wlr_xwayland_surface_configure() may be not enough because we also
need to move the scene node in order to make effective the configure
2024-08-08 14:46:08 -06:00
Leonardo Hernández Hernández bb21ecda30
improve checking in configurex11()
this avoids a client resizing itself when the user is interactively resizing
the client
2024-08-08 14:33:03 -06:00
Leonardo Hernández Hernández b25717c939
drop a useless check in configurex11() 2024-08-08 14:19:39 -06:00
Leonardo Hernández Hernández a4fa954616
do not restack xwayland surfaces (wlroots!4756)
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4756
2024-08-07 16:58:16 -06:00
Leonardo Hernández Hernández 35951a8d7e
add support for linux-drm-syncobj-v1 (wlroots!4715)
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4262
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4715
2024-08-06 12:20:25 -06:00
Leonardo Hernández Hernández a634e3f527
fix crash when a virtual pointer is destroyed
Fixes: https://codeberg.org/dwl/dwl/issues/680
2024-08-06 12:01:22 -06:00
Leonardo Hernández Hernández d136dadf45
-pedantic -> -Wpedantic
Bug: https://codeberg.org/dwl/dwl/issues/584
2024-08-01 22:41:00 -06:00
Sivecano 672b4c405d
fix maximize callback not getting deregisterd 2024-07-27 22:05:53 -06:00
Leonardo Hernández Hernández b5abbc37d8
fix crash when re-mapping a client
Fixes: ab5c554d09
2024-07-27 21:59:27 -06:00
Leonardo Hernández Hernández 986beef5be
replace spaces with tabs
Fixes: 71f11e6cf6
2024-07-27 00:41:39 -06:00
Leonardo Hernández Hernández 487abc28ba
add myself to .mailmap 2024-07-24 15:51:49 -06:00
Leonardo Hernández Hernández cd216908a7
send scale on initial commit to layer surfaces
Signed-off-by: Leonardo Hernández Hernández <leohdz172@proton.me>
2024-07-24 06:25:54 -05:00
Lennart Jablonka f2c5023a3a dwl(1): use correct special characters for - and '
The hyphen-minus <-> and apostrophe-quote <'> are interpreted by troff
as hyphen and right single quotation mark.  See groff_char(7).

Fixes: 0db6f3c5b5 ("add dwl(1)")
2024-07-23 23:32:15 +00:00
Lennart Jablonka 4bbbb4907e add myself to .mailmap 2024-07-23 23:32:15 +00:00
A Frederick Christensen ea6a450121
README.md Fix links formatting issue after re-flow text to 80 columns 2024-07-21 14:34:45 -05:00
A Frederick Christensen ad30ca910b
Documentation restructuring
Modified documentation to make clear the change in development (main) branch versus releases.
2024-07-21 14:21:43 -05:00
Leonardo Hernández Hernández 452a314faa
update README.md to mention the main branch now requires wlroots-git
Closes: https://codeberg.org/dwl/dwl/issues/646
2024-07-14 21:55:58 -06:00
Leonardo Hernández Hernández da6de7c4d7
update wlr_xwayland_surface names (wlroots!2434)
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/2434
2024-07-14 21:37:03 -06:00
Leonardo Hernández Hernández 2553111aa3
bump wlroots version 2024-07-14 21:34:44 -06:00
Leonardo Hernández Hernández 51881da27b
bump version to 0.8-dev 2024-07-14 21:34:28 -06:00
Leonardo Hernández Hernández 7328e5691c
changelog: add new 'unreleased' section 2024-07-14 21:33:37 -06:00
9 changed files with 267 additions and 239 deletions

3
.mailmap Normal file
View file

@ -0,0 +1,3 @@
Lennart Jablonka <humm@ljabl.com> <hummsmith42@gmail.com>
Leonardo Hernández Hernández <leohdz172@proton.me> <leohdz172@outlook.com>
Leonardo Hernández Hernández <leohdz172@proton.me> <leohdz172@protonmail.com>

View file

@ -1,10 +1,33 @@
# Changelog # Changelog
* [Unreleased](#unreleased)
* [0.7](#0.7) * [0.7](#0.7)
* [0.6](#0.6) * [0.6](#0.6)
* [0.5](#0.5) * [0.5](#0.5)
## Unreleased
### Added
* Support for the linux-drm-syncobj-v1 protocol ([wlroots!4715][wlroots!4715], [#685][685])
* Allow the use of non-system wlroots library ([#646][646])
[wlroots!4715]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4715
[685]: https://codeberg.org/dwl/dwl/pulls/685
[646]: https://codeberg.org/dwl/dwl/pulls/646
### Changed
### Deprecated
### Removed
### Fixed
* Crash when a client is created while all outputs are disabled.
### Security
### Contributors
## 0.7 ## 0.7
This version is just 0.6 with wlroots 0.18 compatibility. This version is just 0.6 with wlroots 0.18 compatibility.

View file

@ -6,15 +6,15 @@ include config.mk
# flags for compiling # flags for compiling
DWLCPPFLAGS = -I. -DWLR_USE_UNSTABLE -D_POSIX_C_SOURCE=200809L \ DWLCPPFLAGS = -I. -DWLR_USE_UNSTABLE -D_POSIX_C_SOURCE=200809L \
-DVERSION=\"$(VERSION)\" $(XWAYLAND) -DVERSION=\"$(VERSION)\" $(XWAYLAND)
DWLDEVCFLAGS = -g -pedantic -Wall -Wextra -Wdeclaration-after-statement \ DWLDEVCFLAGS = -g -Wpedantic -Wall -Wextra -Wdeclaration-after-statement \
-Wno-unused-parameter -Wshadow -Wunused-macros -Werror=strict-prototypes \ -Wno-unused-parameter -Wshadow -Wunused-macros -Werror=strict-prototypes \
-Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types \ -Werror=implicit -Werror=return-type -Werror=incompatible-pointer-types \
-Wfloat-conversion -Wfloat-conversion
# CFLAGS / LDFLAGS # CFLAGS / LDFLAGS
PKGS = wlroots-0.18 wayland-server xkbcommon libinput $(XLIBS) PKGS = wayland-server xkbcommon libinput $(XLIBS)
DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS) DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(WLR_INCS) $(DWLCPPFLAGS) $(DWLDEVCFLAGS) $(CFLAGS)
LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` -lm $(LIBS) LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(WLR_LIBS) -lm $(LIBS)
all: dwl all: dwl
dwl: dwl.o util.o dwl: dwl.o util.o

241
README.md
View file

@ -1,25 +1,136 @@
# dwl - dwm for Wayland # dwl - dwm for Wayland
Join us on our IRC channel: [#dwl on Libera Chat] Join us on our IRC channel: [#dwl on Libera Chat]
Or on our [Discord server]. Or on the community-maintained [Discord server].
dwl is a compact, hackable compositor for [Wayland] based on [wlroots]. It is dwl is a compact, hackable compositor for [Wayland] based on [wlroots]. It is
intended to fill the same space in the Wayland world that dwm does in X11, intended to fill the same space in the Wayland world that dwm does in X11,
primarily in terms of functionality, and secondarily in terms of philosophy. primarily in terms of functionality, and secondarily in terms of
Like dwm, dwl is: philosophy. Like dwm, dwl is:
- Easy to understand, hack on, and extend with patches - Easy to understand, hack on, and extend with patches
- One C source file (or a very small number) configurable via `config.h` - One C source file (or a very small number) configurable via `config.h`
- Tied to as few external dependencies as possible - Tied to as few external dependencies as possible
## Getting Started:
### Latest semi-stable [release]
This is probably where you want to start. This builds against the dependent
packages' versions currently shipping in major distributions. If your
distribution's wlroots version is older, use an earlier dwl [release] or [0.x
branch].
### Development branch [main]
Active development progresses on the `main` branch. The `main` branch is built
against a late (and often changing) git commit of wlroots. While the adventurous
are welcome to use `main`, it is a rocky road. Using `main` requires that the
user be willing to chase git commits of wlroots. Testing development pull
requests may involve merging unmerged pull requests in [wlroots]' git repository
and/or git commits of wayland.
### Building dwl
dwl has the following dependencies:
- libinput
- wayland
- wlroots (compiled with the libinput backend)
- xkbcommon
- wayland-protocols (compile-time only)
- pkg-config (compile-time only)
dwl has the following additional dependencies if XWayland support is enabled:
- libxcb
- libxcb-wm
- wlroots (compiled with X11 support)
- Xwayland (runtime only)
Install these (and their `-devel` versions if your distro has separate
development packages) and run `make`. If you wish to build against a released
version of wlroots (*you probably do*), use a [release] or a [0.x branch]. If
you want to use the unstable development `main` branch, you need to use the git
version of [wlroots].
To enable XWayland, you should uncomment its flags in `config.mk`.
## Configuration
All configuration is done by editing `config.h` and recompiling, in the same
manner as dwm. There is no way to separately restart the window manager in
Wayland without restarting the entire display server, so any changes will take
effect the next time dwl is executed.
As in the dwm community, we encourage users to share patches they have
created. Check out the [dwl-patches] repository!
## Running dwl
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. If you are using `elogind` or `systemd-logind` you need to install polkit;
otherwise you need to add yourself in the `seat` group and enable/start the
seatd daemon.
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. Do note that the default background color is black. This can be
modified in `config.h`.
If you would like to run a script or command automatically at startup, you can
specify the command using the `-s` option. This command will be executed as a
shell command using `/bin/sh -c`. It serves a similar function to `.xinitrc`,
but differs in that the display server will not shut down when this process
terminates. Instead, dwl will send this process a SIGTERM at shutdown and wait
for it to terminate (if it hasn't already). This makes it ideal for execing into
a user service manager like [s6], [anopa], [runit], [dinit], or [`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, these must be set prior to running dwl. For example, 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
### Status information
Information about selected layouts, current window title, app-id, and
selected/occupied/urgent tags is written to the stdin of the `-s` command (see
the `printstatus()` function for details). This information can be used to
populate an external status bar with a script that parses the
information. Failing to read this information will cause dwl to block, so if you
do want to run a startup command that does not consume the status information,
you can close standard input with the `<&-` shell redirection, for example:
dwl -s 'foot --server <&-'
If your startup command is a shell script, you can achieve the same inside the
script with the line
exec <&-
To get a list of status bars that work with dwl consult our [wiki].
## Replacements for X applications
You can find a [list of useful resources on our wiki].
## Background
dwl is not meant to provide every feature under the sun. Instead, like dwm, it dwl is not meant to provide every feature under the sun. Instead, like dwm, it
sticks to features which are necessary, simple, and straightforward to implement sticks to features which are necessary, simple, and straightforward to implement
given the base on which it is built. Implemented default features are: given the base on which it is built. Implemented default features are:
- Any features provided by dwm/Xlib: simple window borders, tags, keybindings, - Any features provided by dwm/Xlib: simple window borders, tags, keybindings,
client rules, mouse move/resize. Providing a built-in status bar is an 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 exception to this goal, to avoid dependencies on font rendering and/or drawing
drawing libraries when an external bar could work well. 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 - Idle-inhibit protocol which lets applications such as mpv disable idle
@ -53,100 +164,6 @@ Feature *non-goals* for the main codebase include:
be done through the compositor be done through the compositor
- Animations and visual effects - Animations and visual effects
## Building dwl
dwl has the following dependencies:
```
libinput
wayland
wlroots (compiled with the libinput backend)
xkbcommon
wayland-protocols (compile-time only)
pkg-config (compile-time only)
```
If you enable X11 support:
```
libxcb
libxcb-wm
wlroots (compiled with X11 support)
Xwayland (runtime only)
```
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].
To enable XWayland, you should uncomment its flags in `config.mk`.
## Configuration
All configuration is done by editing `config.h` and recompiling, in the same
manner as dwm. There is no way to separately restart the window manager in
Wayland without restarting the entire display server, so any changes will take
effect the next time dwl is executed.
As in the dwm community, we encourage users to share patches they have created.
Check out the dwl [patches repository]!
## Running dwl
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. If you are using `elogind` or `systemd-logind` you need to install
polkit; otherwise you need to add yourself in the `seat` group and
enable/start the seatd daemon.
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.
Do note that the background color is black.
If you would like to run a script or command automatically at startup, you can
specify the command using the `-s` option. This command will be executed as a
shell command using `/bin/sh -c`. It serves a similar function to `.xinitrc`,
but differs in that the display server will not shut down when this process
terminates. Instead, dwl will send this process a SIGTERM at shutdown and wait
for it to terminate (if it hasn't already). This makes it ideal for execing into
a user service manager like [s6], [anopa], [runit], [dinit], or [`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, these must be set prior to running dwl. For example, 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
### Status information
Information about selected layouts, current window title, app-id, and
selected/occupied/urgent tags is written to the stdin of the `-s` command (see
the `printstatus()` function for details). This information can be used to
populate an external status bar with a script that parses the information.
Failing to read this information will cause dwl to block, so if you do want to
run a startup command that does not consume the status information, you can
close standard input with the `<&-` shell redirection, for example:
dwl -s 'foot --server <&-'
If your startup command is a shell script, you can achieve the same inside the
script with the line
exec <&-
To get a list of status bars that work with dwl consult our [wiki].
## Replacements for X applications
You can find a [list of useful resources on our wiki].
## Acknowledgements ## Acknowledgements
dwl began by extending the TinyWL example provided (CC0) by the sway/wlroots dwl began by extending the TinyWL example provided (CC0) by the sway/wlroots
@ -164,17 +181,19 @@ inspiration, and to the various contributors to the project, including:
- Stivvo for output management and fullscreen support, and patch maintenance - Stivvo for output management and fullscreen support, and patch maintenance
[Discord server]: https://discord.gg/jJxZnrGPWN
[#dwl on Libera Chat]: https://web.libera.chat/?channels=#dwl
[Wayland]: https://wayland.freedesktop.org/
[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots/
[wlroots-next branch]: https://codeberg.org/dwl/dwl/src/branch/wlroots-next
[patches repository]: https://codeberg.org/dwl/dwl-patches
[s6]: https://skarnet.org/software/s6/
[anopa]: https://jjacky.com/anopa/
[runit]: http://smarden.org/runit/faq.html#userservices
[dinit]: https://davmac.org/projects/dinit/
[`systemd --user`]: https://wiki.archlinux.org/title/Systemd/User [`systemd --user`]: https://wiki.archlinux.org/title/Systemd/User
[#dwl on Libera Chat]: https://web.libera.chat/?channels=#dwl
[0.7-rc1]: https://codeberg.org/dwl/dwl/releases/tag/v0.7-rc1
[0.x branch]: https://codeberg.org/dwl/dwl/branches
[anopa]: https://jjacky.com/anopa/
[dinit]: https://davmac.org/projects/dinit/
[dwl-patches]: https://codeberg.org/dwl/dwl-patches
[list of useful resources on our wiki]: https://codeberg.org/dwl/dwl/wiki/Home#migrating-from-x
[main]: https://codeberg.org/dwl/dwl/src/branch/main
[release]: https://codeberg.org/dwl/dwl/releases
[runit]: http://smarden.org/runit/faq.html#userservices
[s6]: https://skarnet.org/software/s6/
[wlroots]: https://gitlab.freedesktop.org/wlroots/wlroots/
[wiki]: https://codeberg.org/dwl/dwl/wiki/Home#compatible-status-bars [wiki]: https://codeberg.org/dwl/dwl/wiki/Home#compatible-status-bars
[list of useful resources on our wiki]: [Discord server]: https://discord.gg/jJxZnrGPWN
https://codeberg.org/dwl/dwl/wiki/Home#migrating-from-x [Wayland]: https://wayland.freedesktop.org/

View file

@ -126,15 +126,14 @@ client_get_appid(Client *c)
{ {
#ifdef XWAYLAND #ifdef XWAYLAND
if (client_is_x11(c)) if (client_is_x11(c))
return c->surface.xwayland->class; return c->surface.xwayland->class ? c->surface.xwayland->class : "broken";
#endif #endif
return c->surface.xdg->toplevel->app_id; return c->surface.xdg->toplevel->app_id ? c->surface.xdg->toplevel->app_id : "broken";
} }
static inline void static inline void
client_get_clip(Client *c, struct wlr_box *clip) client_get_clip(Client *c, struct wlr_box *clip)
{ {
struct wlr_box xdg_geom = {0};
*clip = (struct wlr_box){ *clip = (struct wlr_box){
.x = 0, .x = 0,
.y = 0, .y = 0,
@ -147,9 +146,8 @@ client_get_clip(Client *c, struct wlr_box *clip)
return; return;
#endif #endif
wlr_xdg_surface_get_geometry(c->surface.xdg, &xdg_geom); clip->x = c->surface.xdg->geometry.x;
clip->x = xdg_geom.x; clip->y = c->surface.xdg->geometry.y;
clip->y = xdg_geom.y;
} }
static inline void static inline void
@ -164,7 +162,7 @@ client_get_geometry(Client *c, struct wlr_box *geom)
return; return;
} }
#endif #endif
wlr_xdg_surface_get_geometry(c->surface.xdg, geom); *geom = c->surface.xdg->geometry;
} }
static inline Client * static inline Client *
@ -200,9 +198,9 @@ client_get_title(Client *c)
{ {
#ifdef XWAYLAND #ifdef XWAYLAND
if (client_is_x11(c)) if (client_is_x11(c))
return c->surface.xwayland->title; return c->surface.xwayland->title ? c->surface.xwayland->title : "broken";
#endif #endif
return c->surface.xdg->toplevel->title; return c->surface.xdg->toplevel->title ? c->surface.xdg->toplevel->title : "broken";
} }
static inline int static inline int
@ -301,17 +299,6 @@ client_notify_enter(struct wlr_surface *s, struct wlr_keyboard *kb)
wlr_seat_keyboard_notify_enter(seat, s, NULL, 0, NULL); wlr_seat_keyboard_notify_enter(seat, s, NULL, 0, NULL);
} }
static inline void
client_restack_surface(Client *c)
{
#ifdef XWAYLAND
if (client_is_x11(c))
wlr_xwayland_surface_restack(c->surface.xwayland, NULL,
XCB_STACK_MODE_ABOVE);
#endif
return;
}
static inline void static inline void
client_send_close(Client *c) client_send_close(Client *c)
{ {
@ -344,6 +331,13 @@ client_set_fullscreen(Client *c, int fullscreen)
wlr_xdg_toplevel_set_fullscreen(c->surface.xdg->toplevel, fullscreen); wlr_xdg_toplevel_set_fullscreen(c->surface.xdg->toplevel, fullscreen);
} }
static inline void
client_set_scale(struct wlr_surface *s, float scale)
{
wlr_fractional_scale_v1_notify_scale(s, scale);
wlr_surface_set_preferred_buffer_scale(s, (int32_t)ceilf(scale));
}
static inline uint32_t static inline uint32_t
client_set_size(Client *c, uint32_t width, uint32_t height) client_set_size(Client *c, uint32_t width, uint32_t height)
{ {
@ -364,8 +358,11 @@ static inline void
client_set_tiled(Client *c, uint32_t edges) client_set_tiled(Client *c, uint32_t edges)
{ {
#ifdef XWAYLAND #ifdef XWAYLAND
if (client_is_x11(c)) if (client_is_x11(c)) {
wlr_xwayland_surface_set_maximized(c->surface.xwayland,
edges != WLR_EDGE_NONE, edges != WLR_EDGE_NONE);
return; return;
}
#endif #endif
if (wl_resource_get_version(c->surface.xdg->toplevel->resource) if (wl_resource_get_version(c->surface.xdg->toplevel->resource)
>= XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) { >= XDG_TOPLEVEL_STATE_TILED_RIGHT_SINCE_VERSION) {
@ -391,8 +388,8 @@ client_wants_focus(Client *c)
{ {
#ifdef XWAYLAND #ifdef XWAYLAND
return client_is_unmanaged(c) return client_is_unmanaged(c)
&& wlr_xwayland_or_surface_wants_focus(c->surface.xwayland) && wlr_xwayland_surface_override_redirect_wants_focus(c->surface.xwayland)
&& wlr_xwayland_icccm_input_model(c->surface.xwayland) != WLR_ICCCM_INPUT_MODEL_NONE; && wlr_xwayland_surface_icccm_input_model(c->surface.xwayland) != WLR_ICCCM_INPUT_MODEL_NONE;
#endif #endif
return 0; return 0;
} }

View file

@ -1,4 +1,4 @@
_VERSION = 0.7-rc1 _VERSION = 0.8-dev
VERSION = `git describe --tags --dirty 2>/dev/null || echo $(_VERSION)` VERSION = `git describe --tags --dirty 2>/dev/null || echo $(_VERSION)`
PKG_CONFIG = pkg-config PKG_CONFIG = pkg-config
@ -8,10 +8,29 @@ PREFIX = /usr/local
MANDIR = $(PREFIX)/share/man MANDIR = $(PREFIX)/share/man
DATADIR = $(PREFIX)/share DATADIR = $(PREFIX)/share
WLR_INCS = `$(PKG_CONFIG) --cflags wlroots-0.19`
WLR_LIBS = `$(PKG_CONFIG) --libs wlroots-0.19`
# Allow using an alternative wlroots installations
# This has to have all the includes required by wlroots, e.g:
# Assuming wlroots git repo is "${PWD}/wlroots" and you only ran "meson setup build && ninja -C build"
#WLR_INCS = -I/usr/include/pixman-1 -I/usr/include/elogind -I/usr/include/libdrm \
# -I$(PWD)/wlroots/include
# Set -rpath to avoid using the wrong library.
#WLR_LIBS = -Wl,-rpath,$(PWD)/wlroots/build -L$(PWD)/wlroots/build -lwlroots-0.19
# Assuming you ran "meson setup --prefix ${PWD}/0.19 build && ninja -C build install"
#WLR_INCS = -I/usr/include/pixman-1 -I/usr/include/elogind -I/usr/include/libdrm \
# -I$(PWD)/wlroots/0.19/include/wlroots-0.19
#WLR_LIBS = -Wl,-rpath,$(PWD)/wlroots/0.19/lib64 -L$(PWD)/wlroots/0.19/lib64 -lwlroots-0.19
XWAYLAND = XWAYLAND =
XLIBS = XLIBS =
# Uncomment to build XWayland support # Uncomment to build XWayland support
#XWAYLAND = -DXWAYLAND #XWAYLAND = -DXWAYLAND
#XLIBS = xcb xcb-icccm #XLIBS = xcb xcb-icccm
CC = gcc # dwl itself only uses C99 features, but wlroots' headers use anonymous unions (C11).
# To avoid warnings about them, we do not use -std=c99 and instead of using the
# gmake default 'CC=c99', we use cc.
CC = cc

2
dwl.1
View file

@ -140,7 +140,7 @@ server.
Start Start
.Nm .Nm
with s6 in the background: with s6 in the background:
.Dl dwl -s 's6-svscan <&-' .Dl dwl \-s \(aqs6\-svscan <&\-\(aq
.Sh SEE ALSO .Sh SEE ALSO
.Xr foot 1 , .Xr foot 1 ,
.Xr wmenu 1 , .Xr wmenu 1 ,

145
dwl.c
View file

@ -33,6 +33,7 @@
#include <wlr/types/wlr_keyboard_group.h> #include <wlr/types/wlr_keyboard_group.h>
#include <wlr/types/wlr_layer_shell_v1.h> #include <wlr/types/wlr_layer_shell_v1.h>
#include <wlr/types/wlr_linux_dmabuf_v1.h> #include <wlr/types/wlr_linux_dmabuf_v1.h>
#include <wlr/types/wlr_linux_drm_syncobj_v1.h>
#include <wlr/types/wlr_output.h> #include <wlr/types/wlr_output.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>
@ -105,15 +106,18 @@ typedef struct {
typedef struct Monitor Monitor; typedef struct Monitor Monitor;
typedef struct { typedef struct {
/* Must keep these three elements in this order */ /* Must keep this field first */
unsigned int type; /* XDGShell or X11* */ unsigned int type; /* XDGShell or X11* */
struct wlr_box geom; /* layout-relative, includes border */
Monitor *mon; Monitor *mon;
struct wlr_scene_tree *scene; struct wlr_scene_tree *scene;
struct wlr_scene_rect *border[4]; /* top, bottom, left, right */ struct wlr_scene_rect *border[4]; /* top, bottom, left, right */
struct wlr_scene_tree *scene_surface; struct wlr_scene_tree *scene_surface;
struct wl_list link; struct wl_list link;
struct wl_list flink; struct wl_list flink;
struct wlr_box geom; /* layout-relative, includes border */
struct wlr_box prev; /* layout-relative, includes border */
struct wlr_box bounds; /* only width and height are used */
union { union {
struct wlr_xdg_surface *xdg; struct wlr_xdg_surface *xdg;
struct wlr_xwayland_surface *xwayland; struct wlr_xwayland_surface *xwayland;
@ -128,8 +132,6 @@ typedef struct {
struct wl_listener fullscreen; struct wl_listener fullscreen;
struct wl_listener set_decoration_mode; struct wl_listener set_decoration_mode;
struct wl_listener destroy_decoration; struct wl_listener destroy_decoration;
struct wlr_box prev; /* layout-relative, includes border */
struct wlr_box bounds;
#ifdef XWAYLAND #ifdef XWAYLAND
struct wl_listener activate; struct wl_listener activate;
struct wl_listener associate; struct wl_listener associate;
@ -151,7 +153,6 @@ typedef struct {
} Key; } Key;
typedef struct { typedef struct {
struct wl_list link;
struct wlr_keyboard_group *wlr_group; struct wlr_keyboard_group *wlr_group;
int nsyms; int nsyms;
@ -165,9 +166,9 @@ typedef struct {
} KeyboardGroup; } KeyboardGroup;
typedef struct { typedef struct {
/* Must keep these three elements in this order */ /* Must keep this field first */
unsigned int type; /* LayerShell */ unsigned int type; /* LayerShell */
struct wlr_box geom;
Monitor *mon; Monitor *mon;
struct wlr_scene_tree *scene; struct wlr_scene_tree *scene;
struct wlr_scene_tree *popups; struct wlr_scene_tree *popups;
@ -326,7 +327,6 @@ static void setcursor(struct wl_listener *listener, void *data);
static void setcursorshape(struct wl_listener *listener, void *data); static void setcursorshape(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 setgamma(struct wl_listener *listener, void *data);
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, uint32_t newtags); static void setmon(Client *c, Monitor *m, uint32_t newtags);
@ -357,7 +357,6 @@ static void xytonode(double x, double y, struct wlr_surface **psurface,
static void zoom(const Arg *arg); static void zoom(const Arg *arg);
/* variables */ /* variables */
static const char broken[] = "broken";
static pid_t child_pid = -1; static pid_t child_pid = -1;
static int locked; static int locked;
static void *exclusive_focus; static void *exclusive_focus;
@ -383,7 +382,6 @@ static struct wlr_idle_notifier_v1 *idle_notifier;
static struct wlr_idle_inhibit_manager_v1 *idle_inhibit_mgr; static struct wlr_idle_inhibit_manager_v1 *idle_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_gamma_control_manager_v1 *gamma_control_mgr;
static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr; static struct wlr_virtual_keyboard_manager_v1 *virtual_keyboard_mgr;
static struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr; static struct wlr_virtual_pointer_manager_v1 *virtual_pointer_mgr;
static struct wlr_cursor_shape_manager_v1 *cursor_shape_mgr; static struct wlr_cursor_shape_manager_v1 *cursor_shape_mgr;
@ -461,10 +459,8 @@ applyrules(Client *c)
Monitor *mon = selmon, *m; Monitor *mon = selmon, *m;
c->isfloating = client_is_float_type(c); c->isfloating = client_is_float_type(c);
if (!(appid = client_get_appid(c))) appid = client_get_appid(c);
appid = broken; title = client_get_title(c);
if (!(title = client_get_title(c)))
title = broken;
for (r = rules; r < END(rules); r++) { for (r = rules; r < END(rules); r++) {
if ((!r->title || strstr(title, r->title)) if ((!r->title || strstr(title, r->title))
@ -535,8 +531,6 @@ arrangelayer(Monitor *m, struct wl_list *list, struct wlr_box *usable_area, int
wlr_scene_layer_surface_v1_configure(l->scene_layer, &full_area, usable_area); wlr_scene_layer_surface_v1_configure(l->scene_layer, &full_area, usable_area);
wlr_scene_node_set_position(&l->popups->node, l->scene->node.x, l->scene->node.y); wlr_scene_node_set_position(&l->popups->node, l->scene->node.x, l->scene->node.y);
l->geom.x = l->scene->node.x;
l->geom.y = l->scene->node.y;
} }
} }
@ -630,17 +624,17 @@ buttonpress(struct wl_listener *listener, void *data)
break; break;
case WL_POINTER_BUTTON_STATE_RELEASED: case WL_POINTER_BUTTON_STATE_RELEASED:
/* If you released any buttons, we exit interactive move/resize mode. */ /* If you released any buttons, we exit interactive move/resize mode. */
/* TODO should reset to the pointer focus's current setcursor */ /* TODO: should reset to the pointer focus's current setcursor */
if (!locked && cursor_mode != CurNormal && cursor_mode != CurPressed) { if (!locked && cursor_mode != CurNormal && cursor_mode != CurPressed) {
wlr_cursor_set_xcursor(cursor, cursor_mgr, "default"); wlr_cursor_set_xcursor(cursor, cursor_mgr, "default");
cursor_mode = CurNormal; cursor_mode = CurNormal;
/* Drop the window off on its new monitor */ /* Drop the window off on its new monitor */
selmon = xytomon(cursor->x, cursor->y); selmon = xytomon(cursor->x, cursor->y);
setmon(grabc, selmon, 0); setmon(grabc, selmon, 0);
grabc = NULL;
return; return;
} else {
cursor_mode = CurNormal;
} }
cursor_mode = CurNormal;
break; break;
} }
/* If the event wasn't handled by the compositor, notify the client with /* If the event wasn't handled by the compositor, notify the client with
@ -763,6 +757,8 @@ commitlayersurfacenotify(struct wl_listener *listener, void *data)
struct wlr_layer_surface_v1_state old_state; struct wlr_layer_surface_v1_state old_state;
if (l->layer_surface->initial_commit) { if (l->layer_surface->initial_commit) {
client_set_scale(layer_surface->surface, l->mon->wlr_output->scale);
/* Temporarily set the layer's current state to pending /* Temporarily set the layer's current state to pending
* so that we can easily arrange it */ * so that we can easily arrange it */
old_state = l->layer_surface->current; old_state = l->layer_surface->current;
@ -800,18 +796,19 @@ commitnotify(struct wl_listener *listener, void *data)
* a wrong monitor. * a wrong monitor.
*/ */
applyrules(c); applyrules(c);
wlr_surface_set_preferred_buffer_scale(client_surface(c), (int)ceilf(c->mon->wlr_output->scale)); if (c->mon) {
wlr_fractional_scale_v1_notify_scale(client_surface(c), c->mon->wlr_output->scale); client_set_scale(client_surface(c), c->mon->wlr_output->scale);
}
setmon(c, NULL, 0); /* Make sure to reapply rules in mapnotify() */ setmon(c, NULL, 0); /* Make sure to reapply rules in mapnotify() */
wlr_xdg_toplevel_set_wm_capabilities(c->surface.xdg->toplevel, WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN); wlr_xdg_toplevel_set_wm_capabilities(c->surface.xdg->toplevel,
wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, 0, 0); WLR_XDG_TOPLEVEL_WM_CAPABILITIES_FULLSCREEN);
if (c->decoration) if (c->decoration)
requestdecorationmode(&c->set_decoration_mode, c->decoration); requestdecorationmode(&c->set_decoration_mode, c->decoration);
wlr_xdg_toplevel_set_size(c->surface.xdg->toplevel, 0, 0);
return; return;
} }
if (client_surface(c)->mapped && c->mon)
resize(c, c->geom, (c->isfloating && !c->isfullscreen)); resize(c, c->geom, (c->isfloating && !c->isfullscreen));
/* mark a pending resize as completed */ /* mark a pending resize as completed */
@ -837,11 +834,13 @@ commitpopup(struct wl_listener *listener, void *data)
return; return;
popup->base->surface->data = wlr_scene_xdg_surface_create( popup->base->surface->data = wlr_scene_xdg_surface_create(
popup->parent->data, popup->base); popup->parent->data, popup->base);
if ((l && !l->mon) || (c && !c->mon)) if ((l && !l->mon) || (c && !c->mon)) {
wlr_xdg_popup_destroy(popup);
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->geom.x : c->geom.x); box.x -= (type == LayerShell ? l->scene->node.x : c->geom.x);
box.y -= (type == LayerShell ? l->geom.y : c->geom.y); box.y -= (type == LayerShell ? l->scene->node.y : c->geom.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);
} }
@ -945,8 +944,6 @@ createlayersurface(struct wl_listener *listener, void *data)
wl_list_insert(&l->mon->layers[layer_surface->pending.layer],&l->link); wl_list_insert(&l->mon->layers[layer_surface->pending.layer],&l->link);
wlr_surface_send_enter(surface, layer_surface->output); wlr_surface_send_enter(surface, layer_surface->output);
wlr_fractional_scale_v1_notify_scale(surface, l->mon->wlr_output->scale);
wlr_surface_set_preferred_buffer_scale(surface, (int32_t)ceilf(l->mon->wlr_output->scale));
} }
void void
@ -1174,7 +1171,6 @@ void
destroydecoration(struct wl_listener *listener, void *data) destroydecoration(struct wl_listener *listener, void *data)
{ {
Client *c = wl_container_of(listener, c, destroy_decoration); Client *c = wl_container_of(listener, c, destroy_decoration);
c->decoration = NULL;
wl_list_remove(&c->destroy_decoration.link); wl_list_remove(&c->destroy_decoration.link);
wl_list_remove(&c->set_decoration_mode.link); wl_list_remove(&c->set_decoration_mode.link);
@ -1275,6 +1271,7 @@ destroynotify(struct wl_listener *listener, void *data)
wl_list_remove(&c->commit.link); 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);
wl_list_remove(&c->maximize.link);
} }
free(c); free(c);
} }
@ -1365,7 +1362,6 @@ focusclient(Client *c, int lift)
wl_list_insert(&fstack, &c->flink); wl_list_insert(&fstack, &c->flink);
selmon = c->mon; selmon = c->mon;
c->isurgent = 0; c->isurgent = 0;
client_restack_surface(c);
/* 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 */
@ -1692,7 +1688,8 @@ mapnotify(struct wl_listener *listener, void *data)
/* Create scene tree for this client and its border */ /* Create scene tree for this client and its border */
c->scene = client_surface(c)->data = wlr_scene_tree_create(layers[LyrTile]); c->scene = client_surface(c)->data = wlr_scene_tree_create(layers[LyrTile]);
wlr_scene_node_set_enabled(&c->scene->node, c->type != XDGShell); /* Enabled later by a call to arrange() */
wlr_scene_node_set_enabled(&c->scene->node, client_is_unmanaged(c));
c->scene_surface = c->type == XDGShell c->scene_surface = c->type == XDGShell
? wlr_scene_xdg_surface_create(c->scene, c->surface.xdg) ? wlr_scene_xdg_surface_create(c->scene, c->surface.xdg)
: wlr_scene_subsurface_tree_create(c->scene, client_surface(c)); : wlr_scene_subsurface_tree_create(c->scene, client_surface(c));
@ -1705,6 +1702,7 @@ 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[LyrFloat]); wlr_scene_node_reparent(&c->scene->node, layers[LyrFloat]);
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);
client_set_size(c, c->geom.width, c->geom.height);
if (client_wants_focus(c)) { if (client_wants_focus(c)) {
focusclient(c, 1); focusclient(c, 1);
exclusive_focus = c; exclusive_focus = c;
@ -1822,8 +1820,8 @@ motionnotify(uint32_t time, struct wlr_input_device *device, double dx, double d
&& toplevel_from_wlr_surface(seat->pointer_state.focused_surface, &w, &l) >= 0) { && toplevel_from_wlr_surface(seat->pointer_state.focused_surface, &w, &l) >= 0) {
c = w; c = w;
surface = seat->pointer_state.focused_surface; surface = seat->pointer_state.focused_surface;
sx = cursor->x - (l ? l->geom.x : w->geom.x); sx = cursor->x - (l ? l->scene->node.x : w->geom.x);
sy = cursor->y - (l ? l->geom.y : w->geom.y); sy = cursor->y - (l ? l->scene->node.y : w->geom.y);
} }
/* time is 0 in internal calls meant to restore pointer focus. */ /* time is 0 in internal calls meant to restore pointer focus. */
@ -2037,7 +2035,6 @@ printstatus(void)
Monitor *m = NULL; Monitor *m = NULL;
Client *c; Client *c;
uint32_t occ, urg, sel; uint32_t occ, urg, sel;
const char *appid, *title;
wl_list_for_each(m, &mons, link) { wl_list_for_each(m, &mons, link) {
occ = urg = 0; occ = urg = 0;
@ -2049,10 +2046,8 @@ printstatus(void)
urg |= c->tags; urg |= c->tags;
} }
if ((c = focustop(m))) { if ((c = focustop(m))) {
title = client_get_title(c); printf("%s title %s\n", m->wlr_output->name, client_get_title(c));
appid = client_get_appid(c); printf("%s appid %s\n", m->wlr_output->name, client_get_appid(c));
printf("%s title %s\n", m->wlr_output->name, title ? title : broken);
printf("%s appid %s\n", m->wlr_output->name, appid ? appid : broken);
printf("%s fullscreen %d\n", m->wlr_output->name, c->isfullscreen); printf("%s fullscreen %d\n", m->wlr_output->name, c->isfullscreen);
printf("%s floating %d\n", m->wlr_output->name, c->isfloating); printf("%s floating %d\n", m->wlr_output->name, c->isfloating);
sel = c->tags; sel = c->tags;
@ -2103,7 +2098,6 @@ rendermon(struct wl_listener *listener, void *data)
Monitor *m = wl_container_of(listener, m, frame); Monitor *m = wl_container_of(listener, m, frame);
Client *c; Client *c;
struct wlr_output_state pending = {0}; struct wlr_output_state pending = {0};
struct wlr_gamma_control_v1 *gamma_control;
struct timespec now; struct timespec now;
/* Render if no XDG clients have an outstanding resize and are visible on /* Render if no XDG clients have an outstanding resize and are visible on
@ -2113,32 +2107,7 @@ rendermon(struct wl_listener *listener, void *data)
goto skip; goto skip;
} }
/*
* HACK: The "correct" way to set the gamma is to commit it together with
* the rest of the state in one go, but to do that we would need to rewrite
* wlr_scene_output_commit() in order to add the gamma to the pending
* state before committing, instead try to commit the gamma in one frame,
* and commit the rest of the state in the next one (or in the same frame if
* the gamma can not be committed).
*/
if (m->gamma_lut_changed) {
gamma_control
= wlr_gamma_control_manager_v1_get_control(gamma_control_mgr, m->wlr_output);
m->gamma_lut_changed = 0;
if (!wlr_gamma_control_v1_apply(gamma_control, &pending))
goto commit;
if (!wlr_output_test_state(m->wlr_output, &pending)) {
wlr_gamma_control_v1_send_failed_and_destroy(gamma_control);
goto commit;
}
wlr_output_commit_state(m->wlr_output, &pending);
wlr_output_schedule_frame(m->wlr_output);
} else {
commit:
wlr_scene_output_commit(m->scene_output, NULL); wlr_scene_output_commit(m->scene_output, NULL);
}
skip: skip:
/* Let clients know a frame has been rendered */ /* Let clients know a frame has been rendered */
@ -2182,7 +2151,7 @@ resize(Client *c, struct wlr_box geo, int interact)
struct wlr_box *bbox; struct wlr_box *bbox;
struct wlr_box clip; struct wlr_box clip;
if (!c->mon || !c->scene) if (!c->mon || !client_surface(c)->mapped)
return; return;
bbox = interact ? &sgeom : &c->mon->w; bbox = interact ? &sgeom : &c->mon->w;
@ -2340,17 +2309,6 @@ setfullscreen(Client *c, int fullscreen)
printstatus(); printstatus();
} }
void
setgamma(struct wl_listener *listener, void *data)
{
struct wlr_gamma_control_manager_v1_set_gamma_event *event = data;
Monitor *m = event->output->data;
if (!m)
return;
m->gamma_lut_changed = 1;
wlr_output_schedule_frame(m->wlr_output);
}
void void
setlayout(const Arg *arg) setlayout(const Arg *arg)
{ {
@ -2428,7 +2386,7 @@ setsel(struct wl_listener *listener, void *data)
void void
setup(void) setup(void)
{ {
int i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE}; int drm_fd, i, sig[] = {SIGCHLD, SIGINT, SIGTERM, SIGPIPE};
struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig}; struct sigaction sa = {.sa_flags = SA_RESTART, .sa_handler = handlesig};
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
@ -2478,6 +2436,9 @@ setup(void)
wlr_linux_dmabuf_v1_create_with_renderer(dpy, 5, drw)); wlr_linux_dmabuf_v1_create_with_renderer(dpy, 5, drw));
} }
if ((drm_fd = wlr_renderer_get_drm_fd(drw)) >= 0 && drw->features.timeline)
wlr_linux_drm_syncobj_manager_v1_create(dpy, 1, drm_fd);
/* Autocreates an allocator for us. /* Autocreates an allocator for us.
* The allocator is the bridge between the renderer and the backend. It * The allocator is the bridge between the renderer and the backend. It
* handles the buffer creation, allowing wlroots to render onto the * handles the buffer creation, allowing wlroots to render onto the
@ -2508,8 +2469,7 @@ setup(void)
activation = wlr_xdg_activation_v1_create(dpy); activation = wlr_xdg_activation_v1_create(dpy);
LISTEN_STATIC(&activation->events.request_activate, urgent); LISTEN_STATIC(&activation->events.request_activate, urgent);
gamma_control_mgr = wlr_gamma_control_manager_v1_create(dpy); wlr_scene_set_gamma_control_manager_v1(scene, wlr_gamma_control_manager_v1_create(dpy));
LISTEN_STATIC(&gamma_control_mgr->events.set_gamma, setgamma);
power_mgr = wlr_output_power_manager_v1_create(dpy); power_mgr = wlr_output_power_manager_v1_create(dpy);
LISTEN_STATIC(&power_mgr->events.set_mode, powermgrsetmode); LISTEN_STATIC(&power_mgr->events.set_mode, powermgrsetmode);
@ -2975,11 +2935,11 @@ void
virtualpointer(struct wl_listener *listener, void *data) virtualpointer(struct wl_listener *listener, void *data)
{ {
struct wlr_virtual_pointer_v1_new_pointer_event *event = data; struct wlr_virtual_pointer_v1_new_pointer_event *event = data;
struct wlr_pointer pointer = event->new_pointer->pointer; struct wlr_input_device *device = &event->new_pointer->pointer.base;
wlr_cursor_attach_input_device(cursor, &pointer.base); wlr_cursor_attach_input_device(cursor, device);
if (event->suggested_output) if (event->suggested_output)
wlr_cursor_map_input_to_output(cursor, &pointer.base, event->suggested_output); wlr_cursor_map_input_to_output(cursor, device, event->suggested_output);
} }
Monitor * Monitor *
@ -3078,18 +3038,25 @@ configurex11(struct wl_listener *listener, void *data)
{ {
Client *c = wl_container_of(listener, c, configure); Client *c = wl_container_of(listener, c, configure);
struct wlr_xwayland_surface_configure_event *event = data; struct wlr_xwayland_surface_configure_event *event = data;
/* TODO: figure out if there is another way to do this */ if (!client_surface(c) || !client_surface(c)->mapped) {
if (!c->mon) {
wlr_xwayland_surface_configure(c->surface.xwayland, wlr_xwayland_surface_configure(c->surface.xwayland,
event->x, event->y, event->width, event->height); event->x, event->y, event->width, event->height);
return; return;
} }
if (c->isfloating || client_is_unmanaged(c)) if (client_is_unmanaged(c)) {
resize(c, (struct wlr_box){.x = event->x, .y = event->y, wlr_scene_node_set_position(&c->scene->node, event->x, event->y);
.width = event->width + c->bw * 2, .height = event->height + c->bw * 2}, 0); wlr_xwayland_surface_configure(c->surface.xwayland,
else event->x, event->y, event->width, event->height);
return;
}
if ((c->isfloating && c != grabc) || !c->mon->lt[c->mon->sellt]->arrange) {
resize(c, (struct wlr_box){.x = event->x - c->bw,
.y = event->y - c->bw, .width = event->width + c->bw * 2,
.height = event->height + c->bw * 2}, 0);
} else {
arrange(c->mon); arrange(c->mon);
} }
}
void void
createnotifyx11(struct wl_listener *listener, void *data) createnotifyx11(struct wl_listener *listener, void *data)