Add dwl config
This commit is contained in:
parent
60afadae1e
commit
172b10ceac
16 changed files with 2519 additions and 0 deletions
2
brightnessctl-0.5.1/.gitignore
vendored
Normal file
2
brightnessctl-0.5.1/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
||||||
|
brightnessctl
|
||||||
|
*.swp
|
||||||
4
brightnessctl-0.5.1/90-brightnessctl.rules
Normal file
4
brightnessctl-0.5.1/90-brightnessctl.rules
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
ACTION=="add", SUBSYSTEM=="backlight", RUN+="/bin/chgrp video /sys/class/backlight/%k/brightness"
|
||||||
|
ACTION=="add", SUBSYSTEM=="backlight", RUN+="/bin/chmod g+w /sys/class/backlight/%k/brightness"
|
||||||
|
ACTION=="add", SUBSYSTEM=="leds", RUN+="/bin/chgrp input /sys/class/leds/%k/brightness"
|
||||||
|
ACTION=="add", SUBSYSTEM=="leds", RUN+="/bin/chmod g+w /sys/class/leds/%k/brightness"
|
||||||
25
brightnessctl-0.5.1/LICENSE
Normal file
25
brightnessctl-0.5.1/LICENSE
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
Copyright (c) 2016 Mykyta Holuakha
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
[Except as contained in this notice, the name of Mykyta Holubakha
|
||||||
|
shall not be used in advertising or otherwise to promote the sale, use
|
||||||
|
or other dealings in this Software without prior written authorization
|
||||||
|
from Mykyta Holubakha.]
|
||||||
40
brightnessctl-0.5.1/Makefile
Normal file
40
brightnessctl-0.5.1/Makefile
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
VERSION = 0.5
|
||||||
|
CFLAGS += -std=c99 -g -Wall -Wextra -DVERSION=\"${VERSION}\" -D_POSIX_C_SOURCE=200809L
|
||||||
|
LDLIBS = -lm
|
||||||
|
|
||||||
|
PREFIX ?= /usr
|
||||||
|
BINDIR = ${DESTDIR}${PREFIX}/bin
|
||||||
|
MANDIR = ${DESTDIR}${PREFIX}/share/man
|
||||||
|
|
||||||
|
INSTALL_UDEV_RULES = 1
|
||||||
|
|
||||||
|
INSTALL_UDEV_1 = install_udev_rules
|
||||||
|
UDEVDIR ?= /lib/udev/rules.d
|
||||||
|
|
||||||
|
MODE_0 = 4711
|
||||||
|
MODE_1 = 0755
|
||||||
|
MODE = ${MODE_${INSTALL_UDEV_RULES}}
|
||||||
|
|
||||||
|
ifdef ENABLE_SYSTEMD
|
||||||
|
CFLAGS += ${shell pkg-config --cflags libsystemd}
|
||||||
|
LDLIBS += ${shell pkg-config --libs libsystemd}
|
||||||
|
CPPFLAGS += -DENABLE_SYSTEMD
|
||||||
|
INSTALL_UDEV_RULES=0
|
||||||
|
MODE = 0755
|
||||||
|
endif
|
||||||
|
|
||||||
|
all: brightnessctl brightnessctl.1
|
||||||
|
|
||||||
|
install: all ${INSTALL_UDEV_${INSTALL_UDEV_RULES}}
|
||||||
|
install -d ${BINDIR} ${MANDIR}/man1
|
||||||
|
install -m ${MODE} brightnessctl ${BINDIR}/
|
||||||
|
install -m 0644 brightnessctl.1 ${MANDIR}/man1
|
||||||
|
|
||||||
|
install_udev_rules:
|
||||||
|
install -d ${DESTDIR}${UDEVDIR}
|
||||||
|
install -m 0644 90-brightnessctl.rules ${DESTDIR}${UDEVDIR}
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f brightnessctl
|
||||||
|
|
||||||
|
.PHONY: all install clean
|
||||||
64
brightnessctl-0.5.1/README.md
Normal file
64
brightnessctl-0.5.1/README.md
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
# brightnessctl
|
||||||
|
|
||||||
|
This program allows you read and control device brightness. Devices, by default, include backlight and LEDs (searched for in corresponding classes). If omitted, the first found device is selected.
|
||||||
|
|
||||||
|
It can also preserve current brightness before applying the operation (allowing for usecases like disabling backlight on lid close).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
The program is available in:
|
||||||
|
* [Alpine Linux](https://pkgs.alpinelinux.org/package/edge/community/x86_64/brightnessctl) - starting with 3.11 and Edge
|
||||||
|
* [Arch Linux](https://www.archlinux.org/packages/community/x86_64/brightnessctl/)
|
||||||
|
* [Void Linux](https://github.com/void-linux/void-packages/blob/master/srcpkgs/brightnessctl/template)
|
||||||
|
* [Debian](https://packages.debian.org/testing/source/brightnessctl) - starting with Buster (and derivatives)
|
||||||
|
* [Ubuntu](https://packages.ubuntu.com/source/bionic/brightnessctl) - starting with 18.04 (and derivatives)
|
||||||
|
* [openSUSE](https://build.opensuse.org/package/show/utilities/brightnessctl) - available in Tumbleweed, use OBS `utilities/brightnessctl` devel project for Leap < 15.1
|
||||||
|
* [Fedora/EPEL](https://apps.fedoraproject.org/packages/brightnessctl) (orphaned, deleted since F30, maintainer wanted)
|
||||||
|
* [NixOS/nix](https://nixos.org/nixos/packages.html?attr=brightnessctl) - starting with 17.09, please see the [NixOS Wiki page](https://nixos.wiki/wiki/Backlight#brightnessctl) for the "best-practice" configuration file based installation
|
||||||
|
|
||||||
|
One can build and install the program using `make install`. Consult the Makefile for relevant build-time options.
|
||||||
|
|
||||||
|
## Permissions
|
||||||
|
|
||||||
|
Modifying brightness requires write permissions for device files or systemd support. `brightnessctl` accomplishes this (without using `sudo`/`su`/etc.) by either of the following means:
|
||||||
|
|
||||||
|
1) installing relevant udev rules to add permissions to backlight class devices for users in `video` and leds for users in `input`. (done by default)
|
||||||
|
|
||||||
|
2) installing `brightnessctl` as a suid binary.
|
||||||
|
|
||||||
|
3) using the `systemd-logind` API.
|
||||||
|
|
||||||
|
The behavior is controlled by the `INSTALL_UDEV_RULES` flag (setting it to `1` installs the udev rules, it is the default value).
|
||||||
|
|
||||||
|
The systemd support (since v243) is controlled by the `ENABLE_SYSTEMD` flag (udev rules will not be installed by default).
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
```
|
||||||
|
Usage: brightnessctl [options] [operation] [value]
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-l, --list list devices with available brightness controls.
|
||||||
|
-q, --quiet suppress output.
|
||||||
|
-p, --pretend do not perform write operations.
|
||||||
|
-m, --machine-readable produce machine-readable output.
|
||||||
|
-n, --min-value set minimum brightness, defaults to 1.
|
||||||
|
-e, --exponent[=K] changes percentage curve to exponential.
|
||||||
|
-s, --save save previous state in a temporary file.
|
||||||
|
-r, --restore restore previous saved state.
|
||||||
|
-h, --help print this help.
|
||||||
|
-d, --device=DEVICE specify device name (can be a wildcard).
|
||||||
|
-c, --class=CLASS specify device class.
|
||||||
|
-V, --version print version and exit.
|
||||||
|
|
||||||
|
Operations:
|
||||||
|
i, info get device info.
|
||||||
|
g, get get current brightness of the device.
|
||||||
|
m, max get maximum brightness of the device.
|
||||||
|
s, set VALUE set brightness of the device.
|
||||||
|
|
||||||
|
Valid values:
|
||||||
|
specific value Example: 500
|
||||||
|
percentage value Example: 50%
|
||||||
|
specific delta Example: 50- or +10
|
||||||
|
percentage delta Example: 50%- or +10%
|
||||||
|
```
|
||||||
157
brightnessctl-0.5.1/brightnessctl.1
Normal file
157
brightnessctl-0.5.1/brightnessctl.1
Normal file
|
|
@ -0,0 +1,157 @@
|
||||||
|
.TH "BRIGHTNESSCTL" "1" "24th Jan 2018" "brightnessctl" "brightnessctl"
|
||||||
|
|
||||||
|
.SH "NAME"
|
||||||
|
brightnessctl \- read and control device brightness
|
||||||
|
|
||||||
|
|
||||||
|
.SH "SYNOPSIS"
|
||||||
|
|
||||||
|
.sp
|
||||||
|
\fIbrightnessctl\fR [options] \fI[operation]\fR [value...]
|
||||||
|
|
||||||
|
|
||||||
|
.SH "OPTIONS"
|
||||||
|
|
||||||
|
.sp
|
||||||
|
\fB\-h, \-\-help\fP
|
||||||
|
.RS 4
|
||||||
|
Print this help.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.sp
|
||||||
|
\fB\-l, \-\-list\fP
|
||||||
|
.RS 4
|
||||||
|
List devices with available brightness controls.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.sp
|
||||||
|
\fB\-q, \-\-quiet\fP
|
||||||
|
.RS 4
|
||||||
|
Suppress output.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.sp
|
||||||
|
\fB\-p, \-\-pretend\fP
|
||||||
|
.RS 4
|
||||||
|
Do not perform write operations.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.sp
|
||||||
|
\fB\-m, \-\-machine\-readable\fP
|
||||||
|
.RS 4
|
||||||
|
Produce machine\-readable output.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.sp
|
||||||
|
\fB\-n, \-\-min\-value\fP=\fIVALUE\fP
|
||||||
|
.RS 4
|
||||||
|
Set minimum brightness when using delta values, defaults to 1.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.sp
|
||||||
|
\fB\-e, \-\-exponent\fP=\fIK\fP
|
||||||
|
.RS 4
|
||||||
|
Changes percentage scaling curve to exponential (linear by default). Default exponent is 4.
|
||||||
|
|
||||||
|
Percentage equation: % = \fI[VALUE]\fR^\fI[K]\fR * \fI[MAX]\fR * 100^-\fI[K]\fR.
|
||||||
|
|
||||||
|
The exponential curve may make the adjustments perceptually equal.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.sp
|
||||||
|
\fB\-s, \-\-save\fP
|
||||||
|
.RS 4
|
||||||
|
Save state in a temporary file.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.sp
|
||||||
|
\fB\-r, \-\-restore\fP
|
||||||
|
.RS 4
|
||||||
|
Restore previously\-saved state.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.sp
|
||||||
|
\fB\-d, \-\-device\fP=\fIDEVICE\fP
|
||||||
|
.RS 4
|
||||||
|
Specify device name (can be a wildcard).
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.sp
|
||||||
|
\fB\-c, \-\-class\fP=\fICLASS\fP
|
||||||
|
.RS 4
|
||||||
|
Specify device class.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.sp
|
||||||
|
\fB\-v, \-\-version\fP
|
||||||
|
.RS 4
|
||||||
|
Print version and exit.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
|
||||||
|
.SH "OPERATIONS"
|
||||||
|
|
||||||
|
.sp
|
||||||
|
\fBi, info\fP
|
||||||
|
.RS 4
|
||||||
|
Get device info.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.sp
|
||||||
|
\fBg, get\fP
|
||||||
|
.RS 4
|
||||||
|
Get the current brightness of the device.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.sp
|
||||||
|
\fBm, max\fP
|
||||||
|
.RS 4
|
||||||
|
Get the maximum brightness of the device.
|
||||||
|
.RE
|
||||||
|
|
||||||
|
.sp
|
||||||
|
\fBs, set\fP \fIVALUE\fP
|
||||||
|
.RS 4
|
||||||
|
Set the brightness of the device.
|
||||||
|
|
||||||
|
.SS VALUES
|
||||||
|
.P
|
||||||
|
You may specify \fIVALUE\fR for the \fBset\fR command in absolute or relative form, and
|
||||||
|
as a value or a delta from the current value. For example:
|
||||||
|
.P
|
||||||
|
\fBbrightnessctl set 500\fR
|
||||||
|
.RS "4"
|
||||||
|
Sets brightness to 500.
|
||||||
|
.P
|
||||||
|
.RE
|
||||||
|
\fBbrightnessctl set 50%\fR
|
||||||
|
.RS "4"
|
||||||
|
Sets brightness to 50% of the maximum.
|
||||||
|
.P
|
||||||
|
.RE
|
||||||
|
\fBbrightnessctl set 50-\fR
|
||||||
|
.RS "4"
|
||||||
|
Subtracts 50 from the current brightness.
|
||||||
|
.P
|
||||||
|
.RE
|
||||||
|
\fBbrightnessctl set +10\fR
|
||||||
|
.RS "4"
|
||||||
|
Adds 10 to the current brightness.
|
||||||
|
.P
|
||||||
|
.RE
|
||||||
|
\fBbrightnessctl set 50%-\fR
|
||||||
|
.RS "4"
|
||||||
|
Subtracts 50% of the maximum from the current brightness.
|
||||||
|
.P
|
||||||
|
.RE
|
||||||
|
\fBbrightnessctl set +10%\fR
|
||||||
|
.RS "4"
|
||||||
|
Adds 10% of the maximum to the current brightness.
|
||||||
|
.P
|
||||||
|
.RE
|
||||||
|
.SH AUTHORS
|
||||||
|
.P
|
||||||
|
Maintained by Mykyta Holubakha, who is assisted by other open source
|
||||||
|
contributors. For more information about brightnessctl development, visit:
|
||||||
|
.P
|
||||||
|
https://github.com/Hummer12007/brightnessctl
|
||||||
668
brightnessctl-0.5.1/brightnessctl.c
Normal file
668
brightnessctl-0.5.1/brightnessctl.c
Normal file
|
|
@ -0,0 +1,668 @@
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/utsname.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fnmatch.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#ifdef ENABLE_SYSTEMD
|
||||||
|
# include <systemd/sd-bus.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char *path = "/sys/class";
|
||||||
|
static char *classes[] = { "backlight", "leds", NULL };
|
||||||
|
|
||||||
|
static char *run_dir = "/tmp/brightnessctl";
|
||||||
|
|
||||||
|
struct value;
|
||||||
|
struct device;
|
||||||
|
|
||||||
|
enum operation;
|
||||||
|
|
||||||
|
static void fail(char *, ...);
|
||||||
|
static void usage(void);
|
||||||
|
#define cat_with(...) _cat_with(__VA_ARGS__, NULL)
|
||||||
|
static char *_cat_with(char, ...);
|
||||||
|
static char *dir_child(char *, char*);
|
||||||
|
static char *device_path(struct device *);
|
||||||
|
static char *class_path(char *);
|
||||||
|
static unsigned int calc_value(struct device *, struct value *);
|
||||||
|
static int apply_operation(struct device *, enum operation, struct value *);
|
||||||
|
static bool parse_value(struct value *, char *);
|
||||||
|
static bool do_write_device(struct device *);
|
||||||
|
static bool read_device(struct device *, char *, char *);
|
||||||
|
static int read_class(struct device **, char *);
|
||||||
|
static int read_devices(struct device **);
|
||||||
|
static void print_device(struct device *);
|
||||||
|
static void list_devices(struct device **);
|
||||||
|
static struct device *find_device(struct device **, char *);
|
||||||
|
static bool save_device_data(struct device *);
|
||||||
|
static bool restore_device_data(struct device *);
|
||||||
|
static bool ensure_dir(char *);
|
||||||
|
static bool ensure_dev_dir(struct device *);
|
||||||
|
#define ensure_run_dir() ensure_dir(run_dir)
|
||||||
|
|
||||||
|
#ifdef ENABLE_SYSTEMD
|
||||||
|
static bool logind_set_brightness(struct device *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct device {
|
||||||
|
char *class;
|
||||||
|
char *id;
|
||||||
|
unsigned int curr_brightness;
|
||||||
|
unsigned int max_brightness;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum value_type { ABSOLUTE, RELATIVE };
|
||||||
|
enum delta_type { DIRECT, DELTA };
|
||||||
|
enum sign { PLUS, MINUS };
|
||||||
|
|
||||||
|
struct value {
|
||||||
|
unsigned long val;
|
||||||
|
enum value_type v_type;
|
||||||
|
enum delta_type d_type;
|
||||||
|
enum sign sign;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum operation { INFO, GET, MAX, SET };
|
||||||
|
|
||||||
|
struct params {
|
||||||
|
char *class;
|
||||||
|
char *device;
|
||||||
|
struct value val;
|
||||||
|
long min;
|
||||||
|
enum operation operation;
|
||||||
|
bool quiet;
|
||||||
|
bool list;
|
||||||
|
bool pretend;
|
||||||
|
bool mach;
|
||||||
|
bool save;
|
||||||
|
bool restore;
|
||||||
|
float exponent;
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct params p;
|
||||||
|
|
||||||
|
static const struct option options[] = {
|
||||||
|
{"class", required_argument, NULL, 'c'},
|
||||||
|
{"device", required_argument, NULL, 'd'},
|
||||||
|
{"help", no_argument, NULL, 'h'},
|
||||||
|
{"list", no_argument, NULL, 'l'},
|
||||||
|
{"machine-readable", no_argument, NULL, 'm'},
|
||||||
|
{"min-value", optional_argument, NULL, 'n'},
|
||||||
|
{"exponent", optional_argument, NULL, 'e'},
|
||||||
|
{"quiet", no_argument, NULL, 'q'},
|
||||||
|
{"pretend", no_argument, NULL, 'p'},
|
||||||
|
{"restore", no_argument, NULL, 'r'},
|
||||||
|
{"save", no_argument, NULL, 's'},
|
||||||
|
{"version", no_argument, NULL, 'V'},
|
||||||
|
{NULL,}
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool (*write_device)(struct device *) = do_write_device;
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
struct device *devs[255];
|
||||||
|
struct device *dev;
|
||||||
|
struct utsname name;
|
||||||
|
char *dev_name, *file_path, *sys_run_dir;
|
||||||
|
int n, c, phelp = 0;
|
||||||
|
if (uname(&name))
|
||||||
|
fail("Unable to determine current OS. Exiting!\n");
|
||||||
|
if (strcmp(name.sysname, "Linux"))
|
||||||
|
fail("This program only supports Linux.\n");
|
||||||
|
p.exponent = 1;
|
||||||
|
while (1) {
|
||||||
|
if ((c = getopt_long(argc, argv, "lqpmn::e::srhVc:d:", options, NULL)) < 0)
|
||||||
|
break;
|
||||||
|
switch (c) {
|
||||||
|
case 'l':
|
||||||
|
p.list = true;
|
||||||
|
break;
|
||||||
|
case 'q':
|
||||||
|
p.quiet = true;
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
p.pretend = true;
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
p.save = true;
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
p.restore = true;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
p.mach = true;
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
if (optarg)
|
||||||
|
p.min = atol(optarg);
|
||||||
|
else
|
||||||
|
p.min = 1;
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
if (optarg)
|
||||||
|
p.exponent = atof(optarg);
|
||||||
|
else
|
||||||
|
p.exponent = 4;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
usage();
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
case 'c':
|
||||||
|
p.class = strdup(optarg);
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
p.device = strdup(optarg);
|
||||||
|
break;
|
||||||
|
case 'V':
|
||||||
|
printf("%s\n", VERSION);
|
||||||
|
exit(0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
phelp++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (phelp) {
|
||||||
|
usage();
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
argc -= optind;
|
||||||
|
argv += optind;
|
||||||
|
if (p.class) {
|
||||||
|
if (!(n = read_class(devs, p.class)))
|
||||||
|
fail("Failed to read any devices of class '%s'.\n", p.class);
|
||||||
|
} else {
|
||||||
|
if (!(n = read_devices(devs)))
|
||||||
|
fail("Failed to read any devices.\n");
|
||||||
|
}
|
||||||
|
devs[n] = NULL;
|
||||||
|
if (p.list) {
|
||||||
|
list_devices(devs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
dev_name = p.device;
|
||||||
|
if (!dev_name)
|
||||||
|
dev_name = devs[0]->id;
|
||||||
|
if (argc == 0)
|
||||||
|
p.operation = INFO;
|
||||||
|
else switch (argv[0][0]) {
|
||||||
|
case 'm':
|
||||||
|
p.operation = MAX; break;
|
||||||
|
case 's':
|
||||||
|
p.operation = SET; break;
|
||||||
|
case 'g':
|
||||||
|
p.operation = GET; break;
|
||||||
|
default:
|
||||||
|
case 'i':
|
||||||
|
p.operation = INFO; break;
|
||||||
|
}
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
if (p.operation == SET && argc == 0)
|
||||||
|
fail("You need to provide a value to set.\n");
|
||||||
|
if (p.operation == SET && !parse_value(&p.val, argv[0]))
|
||||||
|
fail("Invalid value given");
|
||||||
|
if (!(dev = find_device(devs, dev_name)))
|
||||||
|
fail("Device '%s' not found.\n", dev_name);
|
||||||
|
if ((p.operation == SET || p.restore) && !p.pretend && geteuid()) {
|
||||||
|
errno = 0;
|
||||||
|
file_path = cat_with('/', path, dev->class, dev->id, "brightness");
|
||||||
|
if (access(file_path, W_OK)) {
|
||||||
|
#ifdef ENABLE_SYSTEMD
|
||||||
|
write_device = logind_set_brightness;
|
||||||
|
#else
|
||||||
|
perror("Can't modify brightness");
|
||||||
|
fail("\nYou should run this program with root privileges.\n"
|
||||||
|
"Alternatively, get write permissions for device files.\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
free(file_path);
|
||||||
|
}
|
||||||
|
if ((sys_run_dir = getenv("XDG_RUNTIME_DIR")))
|
||||||
|
run_dir = dir_child(sys_run_dir, "brightnessctl");
|
||||||
|
if (p.save)
|
||||||
|
if (!save_device_data(dev))
|
||||||
|
fprintf(stderr, "Could not save data for device '%s'.\n", dev->id);
|
||||||
|
if (p.restore) {
|
||||||
|
if (restore_device_data(dev))
|
||||||
|
write_device(dev);
|
||||||
|
}
|
||||||
|
return apply_operation(dev, p.operation, &p.val);
|
||||||
|
}
|
||||||
|
|
||||||
|
int apply_operation(struct device *dev, enum operation operation, struct value *val) {
|
||||||
|
switch (operation) {
|
||||||
|
case INFO:
|
||||||
|
print_device(dev);
|
||||||
|
return 0;
|
||||||
|
case GET:
|
||||||
|
fprintf(stdout, "%u\n", dev->curr_brightness);
|
||||||
|
return 0;
|
||||||
|
case MAX:
|
||||||
|
fprintf(stdout, "%u\n", dev->max_brightness);
|
||||||
|
return 0;
|
||||||
|
case SET:
|
||||||
|
dev->curr_brightness = calc_value(dev, val);
|
||||||
|
if (!p.pretend)
|
||||||
|
if (!write_device(dev))
|
||||||
|
goto fail;
|
||||||
|
if (!p.quiet) {
|
||||||
|
if (!p.mach)
|
||||||
|
fprintf(stdout, "Updated device '%s':\n", dev->id);
|
||||||
|
print_device(dev);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
/* FALLTHRU */
|
||||||
|
fail:
|
||||||
|
default:
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parse_value(struct value *val, char *str) {
|
||||||
|
long n;
|
||||||
|
char c;
|
||||||
|
char *buf;
|
||||||
|
errno = 0;
|
||||||
|
val->v_type = ABSOLUTE;
|
||||||
|
val->d_type = DIRECT;
|
||||||
|
val->sign = PLUS;
|
||||||
|
if (!str || !*str)
|
||||||
|
return false;
|
||||||
|
if (*str == '+' || *str == '-') {
|
||||||
|
val->sign = *str == '+' ? PLUS : MINUS;
|
||||||
|
val->d_type = DELTA;
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
n = strtol(str, &buf, 10);
|
||||||
|
if (errno || buf == str)
|
||||||
|
return false;
|
||||||
|
val->val = labs(n) % LONG_MAX;
|
||||||
|
while ((c = *(buf++))) switch(c) {
|
||||||
|
case '+':
|
||||||
|
val->sign = PLUS;
|
||||||
|
val->d_type = DELTA;
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
val->sign = MINUS;
|
||||||
|
val->d_type = DELTA;
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
val->v_type = RELATIVE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct device *find_device(struct device **devs, char *name) {
|
||||||
|
struct device *dev;
|
||||||
|
while ((dev = *(devs++)))
|
||||||
|
if (!fnmatch(name, dev->id, 0))
|
||||||
|
return dev;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void list_devices(struct device **devs) {
|
||||||
|
struct device *dev;
|
||||||
|
if (!p.mach)
|
||||||
|
fprintf(stdout, "Available devices:\n");
|
||||||
|
while ((dev = *(devs++)))
|
||||||
|
print_device(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
float val_to_percent(float val, struct device *d, bool rnd) {
|
||||||
|
if (val < 0)
|
||||||
|
return 0;
|
||||||
|
float ret = powf(val / d->max_brightness, 1.0f / p.exponent) * 100;
|
||||||
|
return rnd ? roundf(ret) : ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long percent_to_val(float percent, struct device *d) {
|
||||||
|
return roundf(powf(percent / 100, p.exponent) * d->max_brightness);
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_device(struct device *dev) {
|
||||||
|
char *format = p.mach ? "%s,%s,%d,%d%%,%d\n" :
|
||||||
|
"Device '%s' of class '%s':\n\tCurrent brightness: %d (%d%%)\n\tMax brightness: %d\n\n";
|
||||||
|
fprintf(stdout, format,
|
||||||
|
dev->id, dev->class,
|
||||||
|
dev->curr_brightness,
|
||||||
|
(int) val_to_percent(dev->curr_brightness, dev, true),
|
||||||
|
dev->max_brightness);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int calc_value(struct device *d, struct value *val) {
|
||||||
|
long new = d->curr_brightness;
|
||||||
|
if (val->d_type == DIRECT) {
|
||||||
|
new = val->v_type == ABSOLUTE ? val->val : percent_to_val(val->val, d);
|
||||||
|
goto apply;
|
||||||
|
}
|
||||||
|
long mod = val->val;
|
||||||
|
if (val->sign == MINUS)
|
||||||
|
mod *= -1;
|
||||||
|
if (val->v_type == RELATIVE) {
|
||||||
|
mod = percent_to_val(val_to_percent(d->curr_brightness, d, false) + mod, d) - d->curr_brightness;
|
||||||
|
if (val->val != 0 && mod == 0)
|
||||||
|
mod = val->sign == PLUS ? 1 : -1;
|
||||||
|
}
|
||||||
|
new += mod;
|
||||||
|
apply:
|
||||||
|
if (new < p.min)
|
||||||
|
new = p.min;
|
||||||
|
if (new < 0)
|
||||||
|
new = 0;
|
||||||
|
if (new > d->max_brightness)
|
||||||
|
new = d->max_brightness;
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ENABLE_SYSTEMD
|
||||||
|
|
||||||
|
bool logind_set_brightness(struct device *d) {
|
||||||
|
sd_bus *bus = NULL;
|
||||||
|
int r = sd_bus_default_system(&bus);
|
||||||
|
if (r < 0) {
|
||||||
|
fprintf(stderr, "Can't connect to system bus: %s\n", strerror(-r));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_bus_call_method(bus,
|
||||||
|
"org.freedesktop.login1",
|
||||||
|
"/org/freedesktop/login1/session/auto",
|
||||||
|
"org.freedesktop.login1.Session",
|
||||||
|
"SetBrightness",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
"ssu",
|
||||||
|
d->class,
|
||||||
|
d->id,
|
||||||
|
d->curr_brightness);
|
||||||
|
if (r < 0)
|
||||||
|
fprintf(stderr, "Failed to set brightness: %s\n", strerror(-r));
|
||||||
|
|
||||||
|
sd_bus_unref(bus);
|
||||||
|
|
||||||
|
return r >= 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool do_write_device(struct device *d) {
|
||||||
|
FILE *f;
|
||||||
|
char c[16];
|
||||||
|
size_t s = sprintf(c, "%u", d->curr_brightness);
|
||||||
|
errno = 0;
|
||||||
|
if (s <= 0) {
|
||||||
|
errno = EINVAL;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if ((f = fopen(dir_child(device_path(d), "brightness"), "w"))) {
|
||||||
|
if (fwrite(c, 1, s, f) < s)
|
||||||
|
goto close;
|
||||||
|
} else
|
||||||
|
goto fail;
|
||||||
|
errno = 0;
|
||||||
|
close:
|
||||||
|
fclose(f);
|
||||||
|
fail:
|
||||||
|
if (errno)
|
||||||
|
perror("Error writing device");
|
||||||
|
return !errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool read_device(struct device *d, char *class, char *id) {
|
||||||
|
DIR *dirp;
|
||||||
|
FILE *f;
|
||||||
|
char *dev_path = NULL;
|
||||||
|
char *ent_path;
|
||||||
|
int error = 0;
|
||||||
|
struct dirent *ent;
|
||||||
|
bool cur;
|
||||||
|
d->class = strdup(class);
|
||||||
|
d->id = strdup(id);
|
||||||
|
dev_path = device_path(d);
|
||||||
|
if (!(dirp = opendir(dev_path)))
|
||||||
|
goto dfail;
|
||||||
|
while ((ent = readdir(dirp))) {
|
||||||
|
if (!strcmp(ent->d_name, ".") && !strcmp(ent->d_name, ".."))
|
||||||
|
continue;
|
||||||
|
if ((cur = !strcmp(ent->d_name, "brightness")) ||
|
||||||
|
!strcmp(ent->d_name, "max_brightness")) {
|
||||||
|
if (!(f = fopen(ent_path = dir_child(dev_path, ent->d_name), "r")))
|
||||||
|
goto fail;
|
||||||
|
clearerr(f);
|
||||||
|
if (fscanf(f, "%u", cur ? &d->curr_brightness : &d->max_brightness) == EOF) {
|
||||||
|
fprintf(stderr, "End-of-file reading %s of device '%s'.",
|
||||||
|
cur ? "brightness" : "max brightness", d->id);
|
||||||
|
error++;
|
||||||
|
} else if (ferror(f)) {
|
||||||
|
fprintf(stderr, "Error reading %s of device '%s': %s.",
|
||||||
|
cur ? "brightness" : "max brightness", d->id, strerror(errno));
|
||||||
|
error++;
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
free(ent_path);
|
||||||
|
ent_path = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
errno = 0;
|
||||||
|
fail:
|
||||||
|
closedir(dirp);
|
||||||
|
dfail:
|
||||||
|
free(dev_path);
|
||||||
|
free(ent_path);
|
||||||
|
if (errno) {
|
||||||
|
perror("Error reading device");
|
||||||
|
error++;
|
||||||
|
}
|
||||||
|
return !error;
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_class(struct device **devs, char *class) {
|
||||||
|
DIR *dirp;
|
||||||
|
struct dirent *ent;
|
||||||
|
struct device *dev;
|
||||||
|
char *c_path;
|
||||||
|
int cnt = 0;
|
||||||
|
dirp = opendir(c_path = class_path(class));
|
||||||
|
if (!dirp)
|
||||||
|
return 0;
|
||||||
|
while ((ent = readdir(dirp))) {
|
||||||
|
if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, ".."))
|
||||||
|
continue;
|
||||||
|
dev = malloc(sizeof(struct device));
|
||||||
|
if (!read_device(dev, class, ent->d_name)) {
|
||||||
|
free(dev);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
devs[cnt++] = dev;
|
||||||
|
}
|
||||||
|
closedir(dirp);
|
||||||
|
free(c_path);
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
int read_devices(struct device **devs) {
|
||||||
|
size_t n = 0;
|
||||||
|
char *class;
|
||||||
|
int cnt = 0;
|
||||||
|
while ((class = classes[n++]))
|
||||||
|
cnt += read_class(devs + cnt, class);
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool save_device_data(struct device *dev) {
|
||||||
|
char c[16];
|
||||||
|
size_t s = sprintf(c, "%u", dev->curr_brightness);
|
||||||
|
char *d_path = cat_with('/', run_dir, dev->class, dev->id);
|
||||||
|
FILE *fp;
|
||||||
|
mode_t old = 0;
|
||||||
|
int error = 0;
|
||||||
|
errno = 0;
|
||||||
|
if (s <= 0) {
|
||||||
|
fprintf(stderr, "Error converting device data.");
|
||||||
|
error++;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
if (!ensure_dev_dir(dev))
|
||||||
|
goto fail;
|
||||||
|
old = umask(0);
|
||||||
|
fp = fopen(d_path, "w");
|
||||||
|
umask(old);
|
||||||
|
if (!fp)
|
||||||
|
goto fail;
|
||||||
|
if (fwrite(c, 1, s, fp) < s) {
|
||||||
|
fprintf(stderr, "Error writing to '%s'.\n", d_path);
|
||||||
|
error++;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
fail:
|
||||||
|
free(d_path);
|
||||||
|
if (errno) {
|
||||||
|
perror("Error saving device data");
|
||||||
|
error++;
|
||||||
|
}
|
||||||
|
return !error;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool restore_device_data(struct device *dev) {
|
||||||
|
char buf[16];
|
||||||
|
char *filename = cat_with('/', run_dir, dev->class, dev->id);
|
||||||
|
char *end;
|
||||||
|
FILE *fp;
|
||||||
|
memset(buf, 0, 16);
|
||||||
|
errno = 0;
|
||||||
|
if (!(fp = fopen(filename, "r")))
|
||||||
|
goto fail;
|
||||||
|
if (!fread(buf, 1, 15, fp))
|
||||||
|
goto rfail;
|
||||||
|
dev->curr_brightness = strtol(buf, &end, 10);
|
||||||
|
if (end == buf)
|
||||||
|
errno = EINVAL;
|
||||||
|
rfail:
|
||||||
|
fclose(fp);
|
||||||
|
fail:
|
||||||
|
free(filename);
|
||||||
|
if (errno) {
|
||||||
|
perror("Error restoring device data");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ensure_dir(char *dir) {
|
||||||
|
struct stat sb;
|
||||||
|
if (stat(dir, &sb)) {
|
||||||
|
if (errno != ENOENT)
|
||||||
|
return false;
|
||||||
|
errno = 0;
|
||||||
|
if (mkdir(dir, 0777)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (stat(dir, &sb))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!S_ISDIR(sb.st_mode)) {
|
||||||
|
errno = ENOTDIR;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ensure_dev_dir(struct device *dev) {
|
||||||
|
char *cpath;
|
||||||
|
bool ret;
|
||||||
|
if (!ensure_run_dir())
|
||||||
|
return false;
|
||||||
|
cpath = dir_child(run_dir, dev->class);
|
||||||
|
ret = ensure_dir(cpath);
|
||||||
|
free(cpath);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *_cat_with(char c, ...) {
|
||||||
|
size_t size = 32;
|
||||||
|
size_t length = 0;
|
||||||
|
char *buf = calloc(1, size + 1);
|
||||||
|
char *curr;
|
||||||
|
char split[2] = {c, '\0'};
|
||||||
|
va_list va;
|
||||||
|
va_start(va, c);
|
||||||
|
curr = va_arg(va, char *);
|
||||||
|
while (curr) {
|
||||||
|
length += strlen(curr);
|
||||||
|
while (length + 2 > size)
|
||||||
|
buf = realloc(buf, size *= 2);
|
||||||
|
strcat(buf, curr);
|
||||||
|
if ((curr = va_arg(va, char*))) {
|
||||||
|
length++;
|
||||||
|
strcat(buf, split);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *dir_child(char *parent, char *child) {
|
||||||
|
return cat_with('/', parent, child);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *device_path(struct device *dev) {
|
||||||
|
return cat_with('/', path, dev->class, dev->id);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *class_path(char *class) {
|
||||||
|
return dir_child(path, class);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fail(char *err_msg, ...) {
|
||||||
|
va_list va;
|
||||||
|
va_start(va, err_msg);
|
||||||
|
vfprintf(stderr, err_msg, va);
|
||||||
|
va_end(va);
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void usage() {
|
||||||
|
fprintf(stderr, "brightnessctl %s - read and control device brightness.\n\n", VERSION);
|
||||||
|
fprintf(stderr,
|
||||||
|
"Usage: brightnessctl [options] [operation] [value]\n\
|
||||||
|
\n\
|
||||||
|
Options:\n\
|
||||||
|
-l, --list\t\t\tlist devices with available brightness controls.\n\
|
||||||
|
-q, --quiet\t\t\tsuppress output.\n\
|
||||||
|
-p, --pretend\t\t\tdo not perform write operations.\n\
|
||||||
|
-m, --machine-readable\tproduce machine-readable output.\n\
|
||||||
|
-n, --min-value\t\tset minimum brightness, defaults to 1.\n\
|
||||||
|
-e, --exponent[=K]\t\tchanges percentage curve to exponential.\n\
|
||||||
|
-s, --save\t\t\tsave previous state in a temporary file.\n\
|
||||||
|
-r, --restore\t\t\trestore previous saved state.\n\
|
||||||
|
-h, --help\t\t\tprint this help.\n\
|
||||||
|
-d, --device=DEVICE\t\tspecify device name (can be a wildcard).\n\
|
||||||
|
-c, --class=CLASS\t\tspecify device class.\n\
|
||||||
|
-V, --version\t\t\tprint version and exit.\n\
|
||||||
|
\n\
|
||||||
|
Operations:\n\
|
||||||
|
i, info\t\t\tget device info.\n\
|
||||||
|
g, get\t\t\tget current brightness of the device.\n\
|
||||||
|
m, max\t\t\tget maximum brightness of the device.\n\
|
||||||
|
s, set VALUE\t\t\tset brightness of the device.\n\
|
||||||
|
\n\
|
||||||
|
Valid values:\n\
|
||||||
|
specific value\t\tExample: 500\n\
|
||||||
|
percentage value\t\tExample: 50%%\n\
|
||||||
|
specific delta\t\tExample: 50- or +10\n\
|
||||||
|
percentage delta\t\tExample: 50%%- or +10%%\n\
|
||||||
|
\n");
|
||||||
|
}
|
||||||
|
|
||||||
154
dwl-0.7/etc/portage/patches/gui-wm/dwl/autostart-0.7.patch
Normal file
154
dwl-0.7/etc/portage/patches/gui-wm/dwl/autostart-0.7.patch
Normal file
|
|
@ -0,0 +1,154 @@
|
||||||
|
From 787f7252d63945996f009828aff3c44afd0f7781 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Leonardo=20Hern=C3=A1ndez=20Hern=C3=A1ndez?=
|
||||||
|
<leohdz172@proton.me>
|
||||||
|
Date: Sat, 8 Jul 2023 17:11:36 -0600
|
||||||
|
Subject: [PATCH] port autostart patch from dwm
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
https://dwm.suckless.org/patches/cool_autostart/
|
||||||
|
Signed-off-by: Leonardo Hernández Hernández <leohdz172@proton.me>
|
||||||
|
---
|
||||||
|
config.def.h | 7 +++++++
|
||||||
|
dwl.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++-----
|
||||||
|
2 files changed, 61 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 22d2171..8dc6502 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -20,6 +20,13 @@ static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You ca
|
||||||
|
/* logging */
|
||||||
|
static int log_level = WLR_ERROR;
|
||||||
|
|
||||||
|
+/* Autostart */
|
||||||
|
+static const char *const autostart[] = {
|
||||||
|
+ "wbg", "/path/to/your/image", NULL,
|
||||||
|
+ NULL /* terminate */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+
|
||||||
|
/* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */
|
||||||
|
static const Rule rules[] = {
|
||||||
|
/* app_id title tags mask isfloating monitor */
|
||||||
|
diff --git a/dwl.c b/dwl.c
|
||||||
|
index 5bf995e..e8b8727 100644
|
||||||
|
--- a/dwl.c
|
||||||
|
+++ b/dwl.c
|
||||||
|
@@ -249,6 +249,7 @@ static void arrange(Monitor *m);
|
||||||
|
static void arrangelayer(Monitor *m, struct wl_list *list,
|
||||||
|
struct wlr_box *usable_area, int exclusive);
|
||||||
|
static void arrangelayers(Monitor *m);
|
||||||
|
+static void autostartexec(void);
|
||||||
|
static void axisnotify(struct wl_listener *listener, void *data);
|
||||||
|
static void buttonpress(struct wl_listener *listener, void *data);
|
||||||
|
static void chvt(const Arg *arg);
|
||||||
|
@@ -432,6 +433,9 @@ static xcb_atom_t netatom[NetLast];
|
||||||
|
/* attempt to encapsulate suck into one file */
|
||||||
|
#include "client.h"
|
||||||
|
|
||||||
|
+static pid_t *autostart_pids;
|
||||||
|
+static size_t autostart_len;
|
||||||
|
+
|
||||||
|
/* function implementations */
|
||||||
|
void
|
||||||
|
applybounds(Client *c, struct wlr_box *bbox)
|
||||||
|
@@ -580,6 +584,27 @@ arrangelayers(Monitor *m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+autostartexec(void) {
|
||||||
|
+ const char *const *p;
|
||||||
|
+ size_t i = 0;
|
||||||
|
+
|
||||||
|
+ /* count entries */
|
||||||
|
+ for (p = autostart; *p; autostart_len++, p++)
|
||||||
|
+ while (*++p);
|
||||||
|
+
|
||||||
|
+ autostart_pids = calloc(autostart_len, sizeof(pid_t));
|
||||||
|
+ for (p = autostart; *p; i++, p++) {
|
||||||
|
+ if ((autostart_pids[i] = fork()) == 0) {
|
||||||
|
+ setsid();
|
||||||
|
+ execvp(*p, (char *const *)p);
|
||||||
|
+ die("dwl: execvp %s:", *p);
|
||||||
|
+ }
|
||||||
|
+ /* skip arguments */
|
||||||
|
+ while (*++p);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
axisnotify(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
@@ -676,11 +701,21 @@ checkidleinhibitor(struct wlr_surface *exclude)
|
||||||
|
void
|
||||||
|
cleanup(void)
|
||||||
|
{
|
||||||
|
+ size_t i;
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
wlr_xwayland_destroy(xwayland);
|
||||||
|
xwayland = NULL;
|
||||||
|
#endif
|
||||||
|
wl_display_destroy_clients(dpy);
|
||||||
|
+
|
||||||
|
+ /* kill child processes */
|
||||||
|
+ for (i = 0; i < autostart_len; i++) {
|
||||||
|
+ if (0 < autostart_pids[i]) {
|
||||||
|
+ kill(autostart_pids[i], SIGTERM);
|
||||||
|
+ waitpid(autostart_pids[i], NULL, 0);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if (child_pid > 0) {
|
||||||
|
kill(-child_pid, SIGTERM);
|
||||||
|
waitpid(child_pid, NULL, 0);
|
||||||
|
@@ -1497,18 +1532,31 @@ void
|
||||||
|
handlesig(int signo)
|
||||||
|
{
|
||||||
|
if (signo == SIGCHLD) {
|
||||||
|
-#ifdef XWAYLAND
|
||||||
|
siginfo_t in;
|
||||||
|
/* wlroots expects to reap the XWayland process itself, so we
|
||||||
|
* use WNOWAIT to keep the child waitable until we know it's not
|
||||||
|
* XWayland.
|
||||||
|
*/
|
||||||
|
while (!waitid(P_ALL, 0, &in, WEXITED|WNOHANG|WNOWAIT) && in.si_pid
|
||||||
|
- && (!xwayland || in.si_pid != xwayland->server->pid))
|
||||||
|
- waitpid(in.si_pid, NULL, 0);
|
||||||
|
-#else
|
||||||
|
- while (waitpid(-1, NULL, WNOHANG) > 0);
|
||||||
|
+#ifdef XWAYLAND
|
||||||
|
+ && (!xwayland || in.si_pid != xwayland->server->pid)
|
||||||
|
#endif
|
||||||
|
+ ) {
|
||||||
|
+ pid_t *p, *lim;
|
||||||
|
+ waitpid(in.si_pid, NULL, 0);
|
||||||
|
+ if (in.si_pid == child_pid)
|
||||||
|
+ child_pid = -1;
|
||||||
|
+ if (!(p = autostart_pids))
|
||||||
|
+ continue;
|
||||||
|
+ lim = &p[autostart_len];
|
||||||
|
+
|
||||||
|
+ for (; p < lim; p++) {
|
||||||
|
+ if (*p == in.si_pid) {
|
||||||
|
+ *p = -1;
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
} else if (signo == SIGINT || signo == SIGTERM) {
|
||||||
|
quit(NULL);
|
||||||
|
}
|
||||||
|
@@ -2224,6 +2272,7 @@ run(char *startup_cmd)
|
||||||
|
die("startup: backend_start");
|
||||||
|
|
||||||
|
/* Now that the socket exists and the backend is started, run the startup command */
|
||||||
|
+ autostartexec();
|
||||||
|
if (startup_cmd) {
|
||||||
|
int piperw[2];
|
||||||
|
if (pipe(piperw) < 0)
|
||||||
|
--
|
||||||
|
2.45.2
|
||||||
|
|
||||||
127
dwl-0.7/etc/portage/patches/gui-wm/dwl/gaps.patch
Normal file
127
dwl-0.7/etc/portage/patches/gui-wm/dwl/gaps.patch
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
From 50e3dd4746b6cb719efb9f8213b94ac52a5320d9 Mon Sep 17 00:00:00 2001
|
||||||
|
From: peesock <kcormn@gmail.com>
|
||||||
|
Date: Mon, 24 Jun 2024 20:06:42 -0700
|
||||||
|
Subject: [PATCH] gaps!
|
||||||
|
|
||||||
|
Co-authored-by: sewn <sewn@disroot.org>
|
||||||
|
Co-authored-by: serenevoid <ajuph9224@gmail.com>
|
||||||
|
---
|
||||||
|
config.def.h | 4 ++++
|
||||||
|
dwl.c | 34 ++++++++++++++++++++++++++--------
|
||||||
|
2 files changed, 30 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 22d2171..b388b4e 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -6,6 +6,9 @@
|
||||||
|
/* appearance */
|
||||||
|
static const int sloppyfocus = 1; /* focus follows mouse */
|
||||||
|
static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */
|
||||||
|
+static const int smartgaps = 0; /* 1 means no outer gap when there is only one window */
|
||||||
|
+static int gaps = 1; /* 1 means gaps between windows are added */
|
||||||
|
+static const unsigned int gappx = 10; /* gap pixel between windows */
|
||||||
|
static const unsigned int borderpx = 1; /* border pixel of windows */
|
||||||
|
static const float rootcolor[] = COLOR(0x222222ff);
|
||||||
|
static const float bordercolor[] = COLOR(0x444444ff);
|
||||||
|
@@ -135,6 +138,7 @@ static const Key keys[] = {
|
||||||
|
{ MODKEY, XKB_KEY_l, setmfact, {.f = +0.05f} },
|
||||||
|
{ MODKEY, XKB_KEY_Return, zoom, {0} },
|
||||||
|
{ MODKEY, XKB_KEY_Tab, view, {0} },
|
||||||
|
+ { MODKEY, XKB_KEY_g, togglegaps, {0} },
|
||||||
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} },
|
||||||
|
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
|
||||||
|
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
|
||||||
|
diff --git a/dwl.c b/dwl.c
|
||||||
|
index dc0437e..dc851df 100644
|
||||||
|
--- a/dwl.c
|
||||||
|
+++ b/dwl.c
|
||||||
|
@@ -199,6 +199,7 @@ struct Monitor {
|
||||||
|
struct wlr_box w; /* window area, layout-relative */
|
||||||
|
struct wl_list layers[4]; /* LayerSurface.link */
|
||||||
|
const Layout *lt[2];
|
||||||
|
unsigned int seltags;
|
||||||
|
+ int gaps;
|
||||||
|
unsigned int sellt;
|
||||||
|
uint32_t tagset[2];
|
||||||
|
@@ -336,6 +337,7 @@ static void tagmon(const Arg *arg);
|
||||||
|
static void tile(Monitor *m);
|
||||||
|
static void togglefloating(const Arg *arg);
|
||||||
|
static void togglefullscreen(const Arg *arg);
|
||||||
|
+static void togglegaps(const Arg *arg);
|
||||||
|
static void toggletag(const Arg *arg);
|
||||||
|
static void toggleview(const Arg *arg);
|
||||||
|
static void unlocksession(struct wl_listener *listener, void *data);
|
||||||
|
@@ -949,6 +951,8 @@ createmon(struct wl_listener *listener, void *data)
|
||||||
|
|
||||||
|
wlr_output_state_init(&state);
|
||||||
|
/* Initialize monitor state using configured rules */
|
||||||
|
+ m->gaps = gaps;
|
||||||
|
+
|
||||||
|
m->tagset[0] = m->tagset[1] = 1;
|
||||||
|
for (r = monrules; r < END(monrules); r++) {
|
||||||
|
if (!r->name || strstr(wlr_output->name, r->name)) {
|
||||||
|
@@ -2638,7 +2642,7 @@ tagmon(const Arg *arg)
|
||||||
|
void
|
||||||
|
tile(Monitor *m)
|
||||||
|
{
|
||||||
|
- unsigned int mw, my, ty;
|
||||||
|
+ unsigned int h, r, e = m->gaps, mw, my, ty;
|
||||||
|
int i, n = 0;
|
||||||
|
Client *c;
|
||||||
|
|
||||||
|
@@ -2647,23 +2651,30 @@ tile(Monitor *m)
|
||||||
|
n++;
|
||||||
|
if (n == 0)
|
||||||
|
return;
|
||||||
|
+ if (smartgaps == n)
|
||||||
|
+ e = 0;
|
||||||
|
|
||||||
|
if (n > m->nmaster)
|
||||||
|
- mw = m->nmaster ? (int)roundf(m->w.width * m->mfact) : 0;
|
||||||
|
+ mw = m->nmaster ? (int)roundf((m->w.width + gappx*e) * m->mfact) : 0;
|
||||||
|
else
|
||||||
|
mw = m->w.width;
|
||||||
|
- i = my = ty = 0;
|
||||||
|
+ i = 0;
|
||||||
|
+ my = ty = gappx*e;
|
||||||
|
wl_list_for_each(c, &clients, link) {
|
||||||
|
if (!VISIBLEON(c, m) || c->isfloating || c->isfullscreen)
|
||||||
|
continue;
|
||||||
|
if (i < m->nmaster) {
|
||||||
|
- resize(c, (struct wlr_box){.x = m->w.x, .y = m->w.y + my, .width = mw,
|
||||||
|
- .height = (m->w.height - my) / (MIN(n, m->nmaster) - i)}, 0);
|
||||||
|
- my += c->geom.height;
|
||||||
|
+ r = MIN(n, m->nmaster) - i;
|
||||||
|
+ h = (m->w.height - my - gappx*e - gappx*e * (r - 1)) / r;
|
||||||
|
+ resize(c, (struct wlr_box){.x = m->w.x + gappx*e, .y = m->w.y + my,
|
||||||
|
+ .width = mw - 2*gappx*e, .height = h}, 0);
|
||||||
|
+ my += c->geom.height + gappx*e;
|
||||||
|
} else {
|
||||||
|
+ r = n - i;
|
||||||
|
+ h = (m->w.height - ty - gappx*e - gappx*e * (r - 1)) / r;
|
||||||
|
resize(c, (struct wlr_box){.x = m->w.x + mw, .y = m->w.y + ty,
|
||||||
|
- .width = m->w.width - mw, .height = (m->w.height - ty) / (n - i)}, 0);
|
||||||
|
- ty += c->geom.height;
|
||||||
|
+ .width = m->w.width - mw - gappx*e, .height = h}, 0);
|
||||||
|
+ ty += c->geom.height + gappx*e;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
@@ -2686,6 +2697,13 @@ togglefullscreen(const Arg *arg)
|
||||||
|
setfullscreen(sel, !sel->isfullscreen);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+togglegaps(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ selmon->gaps = !selmon->gaps;
|
||||||
|
+ arrange(selmon);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
toggletag(const Arg *arg)
|
||||||
|
{
|
||||||
|
--
|
||||||
|
2.45.2
|
||||||
|
|
||||||
600
dwl-0.7/etc/portage/patches/gui-wm/dwl/ipc-edited.patch
Normal file
600
dwl-0.7/etc/portage/patches/gui-wm/dwl/ipc-edited.patch
Normal file
|
|
@ -0,0 +1,600 @@
|
||||||
|
From 6c6d655b68770ce82a24fde9b58c4d97b672553a Mon Sep 17 00:00:00 2001
|
||||||
|
From: choc <notchoc@proton.me>
|
||||||
|
Date: Mon, 23 Oct 2023 10:35:17 +0800
|
||||||
|
Subject: [PATCH] implement dwl-ipc-unstable-v2
|
||||||
|
https://codeberg.org/dwl/dwl-patches/wiki/ipc
|
||||||
|
|
||||||
|
---
|
||||||
|
Makefile | 14 +-
|
||||||
|
config.def.h | 1 +
|
||||||
|
dwl.c | 257 ++++++++++++++++++++++++++----
|
||||||
|
protocols/dwl-ipc-unstable-v2.xml | 181 +++++++++++++++++++++
|
||||||
|
4 files changed, 419 insertions(+), 34 deletions(-)
|
||||||
|
create mode 100644 protocols/dwl-ipc-unstable-v2.xml
|
||||||
|
|
||||||
|
diff --git a/Makefile b/Makefile
|
||||||
|
index 8db7409..a79a080 100644
|
||||||
|
--- a/Makefile
|
||||||
|
+++ b/Makefile
|
||||||
|
@@ -17,12 +17,14 @@ DWLCFLAGS = `$(PKG_CONFIG) --cflags $(PKGS)` $(WLR_INCS) $(DWLCPPFLAGS) $(DWLDEV
|
||||||
|
LDLIBS = `$(PKG_CONFIG) --libs $(PKGS)` $(WLR_LIBS) -lm $(LIBS)
|
||||||
|
|
||||||
|
all: dwl
|
||||||
|
-dwl: dwl.o util.o
|
||||||
|
- $(CC) dwl.o util.o $(DWLCFLAGS) $(LDFLAGS) $(LDLIBS) -o $@
|
||||||
|
+dwl: dwl.o util.o dwl-ipc-unstable-v2-protocol.o
|
||||||
|
+ $(CC) dwl.o util.o dwl-ipc-unstable-v2-protocol.o $(DWLCFLAGS) $(LDFLAGS) $(LDLIBS) -o $@
|
||||||
|
dwl.o: dwl.c client.h config.h config.mk cursor-shape-v1-protocol.h \
|
||||||
|
pointer-constraints-unstable-v1-protocol.h wlr-layer-shell-unstable-v1-protocol.h \
|
||||||
|
- wlr-output-power-management-unstable-v1-protocol.h xdg-shell-protocol.h
|
||||||
|
+ wlr-output-power-management-unstable-v1-protocol.h xdg-shell-protocol.h \
|
||||||
|
+ dwl-ipc-unstable-v2-protocol.h
|
||||||
|
util.o: util.c util.h
|
||||||
|
+dwl-ipc-unstable-v2-protocol.o: dwl-ipc-unstable-v2-protocol.c dwl-ipc-unstable-v2-protocol.h
|
||||||
|
|
||||||
|
# wayland-scanner is a tool which generates C headers and rigging for Wayland
|
||||||
|
# protocols, which are specified in XML. wlroots requires you to rig these up
|
||||||
|
@@ -45,6 +47,12 @@ wlr-output-power-management-unstable-v1-protocol.h:
|
||||||
|
xdg-shell-protocol.h:
|
||||||
|
$(WAYLAND_SCANNER) server-header \
|
||||||
|
$(WAYLAND_PROTOCOLS)/stable/xdg-shell/xdg-shell.xml $@
|
||||||
|
+dwl-ipc-unstable-v2-protocol.h:
|
||||||
|
+ $(WAYLAND_SCANNER) server-header \
|
||||||
|
+ protocols/dwl-ipc-unstable-v2.xml $@
|
||||||
|
+dwl-ipc-unstable-v2-protocol.c:
|
||||||
|
+ $(WAYLAND_SCANNER) private-code \
|
||||||
|
+ protocols/dwl-ipc-unstable-v2.xml $@
|
||||||
|
|
||||||
|
config.h:
|
||||||
|
cp config.def.h $@
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 22d2171..1593033 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -127,6 +127,7 @@ static const Key keys[] = {
|
||||||
|
/* modifier key function argument */
|
||||||
|
{ MODKEY, XKB_KEY_p, spawn, {.v = menucmd} },
|
||||||
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} },
|
||||||
|
+ { MODKEY, XKB_KEY_b, togglebar, {0} },
|
||||||
|
{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },
|
||||||
|
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
|
||||||
|
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
|
||||||
|
diff --git a/dwl.c b/dwl.c
|
||||||
|
index 8a587d1..7a4949b 100644
|
||||||
|
--- a/dwl.c
|
||||||
|
+++ b/dwl.c
|
||||||
|
@@ -68,6 +68,7 @@
|
||||||
|
#include <xcb/xcb_icccm.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#include "dwl-ipc-unstable-v2-protocol.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
/* macros */
|
||||||
|
@@ -144,6 +145,12 @@ typedef struct {
|
||||||
|
uint32_t resize; /* configure serial of a pending resize */
|
||||||
|
} Client;
|
||||||
|
|
||||||
|
+typedef struct {
|
||||||
|
+ struct wl_list link;
|
||||||
|
+ struct wl_resource *resource;
|
||||||
|
+ Monitor *mon;
|
||||||
|
+} DwlIpcOutput;
|
||||||
|
+
|
||||||
|
typedef struct {
|
||||||
|
uint32_t mod;
|
||||||
|
xkb_keysym_t keysym;
|
||||||
|
@@ -189,6 +196,7 @@ typedef struct {
|
||||||
|
|
||||||
|
struct Monitor {
|
||||||
|
struct wl_list link;
|
||||||
|
+ struct wl_list dwl_ipc_outputs;
|
||||||
|
struct wlr_output *wlr_output;
|
||||||
|
struct wlr_scene_output *scene_output;
|
||||||
|
struct wlr_scene_rect *fullscreen_bg; /* See createmon() for info */
|
||||||
|
@@ -286,6 +294,17 @@ static void destroysessionlock(struct wl_listener *listener, void *data);
|
||||||
|
static void destroysessionmgr(struct wl_listener *listener, void *data);
|
||||||
|
static void destroykeyboardgroup(struct wl_listener *listener, void *data);
|
||||||
|
static Monitor *dirtomon(enum wlr_direction dir);
|
||||||
|
+static void dwl_ipc_manager_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id);
|
||||||
|
+static void dwl_ipc_manager_destroy(struct wl_resource *resource);
|
||||||
|
+static void dwl_ipc_manager_get_output(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *output);
|
||||||
|
+static void dwl_ipc_manager_release(struct wl_client *client, struct wl_resource *resource);
|
||||||
|
+static void dwl_ipc_output_destroy(struct wl_resource *resource);
|
||||||
|
+static void dwl_ipc_output_printstatus(Monitor *monitor);
|
||||||
|
+static void dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output);
|
||||||
|
+static void dwl_ipc_output_set_client_tags(struct wl_client *client, struct wl_resource *resource, uint32_t and_tags, uint32_t xor_tags);
|
||||||
|
+static void dwl_ipc_output_set_layout(struct wl_client *client, struct wl_resource *resource, uint32_t index);
|
||||||
|
+static void dwl_ipc_output_set_tags(struct wl_client *client, struct wl_resource *resource, uint32_t tagmask, uint32_t toggle_tagset);
|
||||||
|
+static void dwl_ipc_output_release(struct wl_client *client, struct wl_resource *resource);
|
||||||
|
static void focusclient(Client *c, int lift);
|
||||||
|
static void focusmon(const Arg *arg);
|
||||||
|
static void focusstack(const Arg *arg);
|
||||||
|
@@ -338,6 +357,7 @@ static void startdrag(struct wl_listener *listener, void *data);
|
||||||
|
static void tag(const Arg *arg);
|
||||||
|
static void tagmon(const Arg *arg);
|
||||||
|
static void tile(Monitor *m);
|
||||||
|
+static void togglebar(const Arg *arg);
|
||||||
|
static void togglefloating(const Arg *arg);
|
||||||
|
static void togglefullscreen(const Arg *arg);
|
||||||
|
static void toggletag(const Arg *arg);
|
||||||
|
@@ -411,6 +431,9 @@ static struct wlr_box sgeom;
|
||||||
|
static struct wl_list mons;
|
||||||
|
static Monitor *selmon;
|
||||||
|
|
||||||
|
+static struct zdwl_ipc_manager_v2_interface dwl_manager_implementation = {.release = dwl_ipc_manager_release, .get_output = dwl_ipc_manager_get_output};
|
||||||
|
+static struct zdwl_ipc_output_v2_interface dwl_output_implementation = {.release = dwl_ipc_output_release, .set_tags = dwl_ipc_output_set_tags, .set_layout = dwl_ipc_output_set_layout, .set_client_tags = dwl_ipc_output_set_client_tags};
|
||||||
|
+
|
||||||
|
#ifdef XWAYLAND
|
||||||
|
static void activatex11(struct wl_listener *listener, void *data);
|
||||||
|
static void associatex11(struct wl_listener *listener, void *data);
|
||||||
|
@@ -703,6 +726,10 @@ cleanupmon(struct wl_listener *listener, void *data)
|
||||||
|
LayerSurface *l, *tmp;
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
+ DwlIpcOutput *ipc_output, *ipc_output_tmp;
|
||||||
|
+ wl_list_for_each_safe(ipc_output, ipc_output_tmp, &m->dwl_ipc_outputs, link)
|
||||||
|
+ wl_resource_destroy(ipc_output->resource);
|
||||||
|
+
|
||||||
|
/* m->layers[i] are intentionally not unlinked */
|
||||||
|
for (i = 0; i < LENGTH(m->layers); i++) {
|
||||||
|
wl_list_for_each_safe(l, tmp, &m->layers[i], link)
|
||||||
|
@@ -983,6 +1010,8 @@ createmon(struct wl_listener *listener, void *data)
|
||||||
|
m = wlr_output->data = ecalloc(1, sizeof(*m));
|
||||||
|
m->wlr_output = wlr_output;
|
||||||
|
|
||||||
|
+ wl_list_init(&m->dwl_ipc_outputs);
|
||||||
|
+
|
||||||
|
for (i = 0; i < LENGTH(m->layers); i++)
|
||||||
|
wl_list_init(&m->layers[i]);
|
||||||
|
|
||||||
|
@@ -1334,6 +1363,192 @@ dirtomon(enum wlr_direction dir)
|
||||||
|
return selmon;
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+dwl_ipc_manager_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
|
||||||
|
+{
|
||||||
|
+ struct wl_resource *manager_resource = wl_resource_create(client, &zdwl_ipc_manager_v2_interface, version, id);
|
||||||
|
+ if (!manager_resource) {
|
||||||
|
+ wl_client_post_no_memory(client);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ wl_resource_set_implementation(manager_resource, &dwl_manager_implementation, NULL, dwl_ipc_manager_destroy);
|
||||||
|
+
|
||||||
|
+ zdwl_ipc_manager_v2_send_tags(manager_resource, TAGCOUNT);
|
||||||
|
+
|
||||||
|
+ for (unsigned int i = 0; i < LENGTH(layouts); i++)
|
||||||
|
+ zdwl_ipc_manager_v2_send_layout(manager_resource, layouts[i].symbol);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+dwl_ipc_manager_destroy(struct wl_resource *resource)
|
||||||
|
+{
|
||||||
|
+ /* No state to destroy */
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+dwl_ipc_manager_get_output(struct wl_client *client, struct wl_resource *resource, uint32_t id, struct wl_resource *output)
|
||||||
|
+{
|
||||||
|
+ DwlIpcOutput *ipc_output;
|
||||||
|
+ Monitor *monitor = wlr_output_from_resource(output)->data;
|
||||||
|
+ struct wl_resource *output_resource = wl_resource_create(client, &zdwl_ipc_output_v2_interface, wl_resource_get_version(resource), id);
|
||||||
|
+ if (!output_resource)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ ipc_output = ecalloc(1, sizeof(*ipc_output));
|
||||||
|
+ ipc_output->resource = output_resource;
|
||||||
|
+ ipc_output->mon = monitor;
|
||||||
|
+ wl_resource_set_implementation(output_resource, &dwl_output_implementation, ipc_output, dwl_ipc_output_destroy);
|
||||||
|
+ wl_list_insert(&monitor->dwl_ipc_outputs, &ipc_output->link);
|
||||||
|
+ dwl_ipc_output_printstatus_to(ipc_output);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+dwl_ipc_manager_release(struct wl_client *client, struct wl_resource *resource)
|
||||||
|
+{
|
||||||
|
+ wl_resource_destroy(resource);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+dwl_ipc_output_destroy(struct wl_resource *resource)
|
||||||
|
+{
|
||||||
|
+ DwlIpcOutput *ipc_output = wl_resource_get_user_data(resource);
|
||||||
|
+ wl_list_remove(&ipc_output->link);
|
||||||
|
+ free(ipc_output);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+dwl_ipc_output_printstatus(Monitor *monitor)
|
||||||
|
+{
|
||||||
|
+ DwlIpcOutput *ipc_output;
|
||||||
|
+ wl_list_for_each(ipc_output, &monitor->dwl_ipc_outputs, link)
|
||||||
|
+ dwl_ipc_output_printstatus_to(ipc_output);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+dwl_ipc_output_printstatus_to(DwlIpcOutput *ipc_output)
|
||||||
|
+{
|
||||||
|
+ Monitor *monitor = ipc_output->mon;
|
||||||
|
+ Client *c, *focused;
|
||||||
|
+ int tagmask, state, numclients, focused_client, tag;
|
||||||
|
+ const char *title, *appid;
|
||||||
|
+ focused = focustop(monitor);
|
||||||
|
+ zdwl_ipc_output_v2_send_active(ipc_output->resource, monitor == selmon);
|
||||||
|
+
|
||||||
|
+ for (tag = 0 ; tag < TAGCOUNT; tag++) {
|
||||||
|
+ numclients = state = focused_client = 0;
|
||||||
|
+ tagmask = 1 << tag;
|
||||||
|
+ if ((tagmask & monitor->tagset[monitor->seltags]) != 0)
|
||||||
|
+ state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE;
|
||||||
|
+
|
||||||
|
+ wl_list_for_each(c, &clients, link) {
|
||||||
|
+ if (c->mon != monitor)
|
||||||
|
+ continue;
|
||||||
|
+ if (!(c->tags & tagmask))
|
||||||
|
+ continue;
|
||||||
|
+ if (c == focused)
|
||||||
|
+ focused_client = 1;
|
||||||
|
+ if (c->isurgent)
|
||||||
|
+ state |= ZDWL_IPC_OUTPUT_V2_TAG_STATE_URGENT;
|
||||||
|
+
|
||||||
|
+ numclients++;
|
||||||
|
+ }
|
||||||
|
+ zdwl_ipc_output_v2_send_tag(ipc_output->resource, tag, state, numclients, focused_client);
|
||||||
|
+ }
|
||||||
|
+ title = focused ? client_get_title(focused) : "";
|
||||||
|
+ appid = focused ? client_get_appid(focused) : "";
|
||||||
|
+
|
||||||
|
+ zdwl_ipc_output_v2_send_layout(ipc_output->resource, monitor->lt[monitor->sellt] - layouts);
|
||||||
|
+ zdwl_ipc_output_v2_send_title(ipc_output->resource, title);
|
||||||
|
+ zdwl_ipc_output_v2_send_appid(ipc_output->resource, appid);
|
||||||
|
+ zdwl_ipc_output_v2_send_layout_symbol(ipc_output->resource, monitor->ltsymbol);
|
||||||
|
+ if (wl_resource_get_version(ipc_output->resource) >= ZDWL_IPC_OUTPUT_V2_FULLSCREEN_SINCE_VERSION) {
|
||||||
|
+ zdwl_ipc_output_v2_send_fullscreen(ipc_output->resource, focused ? focused->isfullscreen : 0);
|
||||||
|
+ }
|
||||||
|
+ if (wl_resource_get_version(ipc_output->resource) >= ZDWL_IPC_OUTPUT_V2_FLOATING_SINCE_VERSION) {
|
||||||
|
+ zdwl_ipc_output_v2_send_floating(ipc_output->resource, focused ? focused->isfloating : 0);
|
||||||
|
+ }
|
||||||
|
+ zdwl_ipc_output_v2_send_frame(ipc_output->resource);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+dwl_ipc_output_set_client_tags(struct wl_client *client, struct wl_resource *resource, uint32_t and_tags, uint32_t xor_tags)
|
||||||
|
+{
|
||||||
|
+ DwlIpcOutput *ipc_output;
|
||||||
|
+ Monitor *monitor;
|
||||||
|
+ Client *selected_client;
|
||||||
|
+ unsigned int newtags = 0;
|
||||||
|
+
|
||||||
|
+ ipc_output = wl_resource_get_user_data(resource);
|
||||||
|
+ if (!ipc_output)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ monitor = ipc_output->mon;
|
||||||
|
+ selected_client = focustop(monitor);
|
||||||
|
+ if (!selected_client)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ newtags = (selected_client->tags & and_tags) ^ xor_tags;
|
||||||
|
+ if (!newtags)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ selected_client->tags = newtags;
|
||||||
|
+ if (selmon == monitor)
|
||||||
|
+ focusclient(focustop(monitor), 1);
|
||||||
|
+ arrange(selmon);
|
||||||
|
+ printstatus();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+dwl_ipc_output_set_layout(struct wl_client *client, struct wl_resource *resource, uint32_t index)
|
||||||
|
+{
|
||||||
|
+ DwlIpcOutput *ipc_output;
|
||||||
|
+ Monitor *monitor;
|
||||||
|
+
|
||||||
|
+ ipc_output = wl_resource_get_user_data(resource);
|
||||||
|
+ if (!ipc_output)
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ monitor = ipc_output->mon;
|
||||||
|
+ if (index >= LENGTH(layouts))
|
||||||
|
+ return;
|
||||||
|
+ if (index != monitor->lt[monitor->sellt] - layouts)
|
||||||
|
+ monitor->sellt ^= 1;
|
||||||
|
+
|
||||||
|
+ monitor->lt[monitor->sellt] = &layouts[index];
|
||||||
|
+ arrange(monitor);
|
||||||
|
+ printstatus();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+dwl_ipc_output_set_tags(struct wl_client *client, struct wl_resource *resource, uint32_t tagmask, uint32_t toggle_tagset)
|
||||||
|
+{
|
||||||
|
+ DwlIpcOutput *ipc_output;
|
||||||
|
+ Monitor *monitor;
|
||||||
|
+ unsigned int newtags = tagmask & TAGMASK;
|
||||||
|
+
|
||||||
|
+ ipc_output = wl_resource_get_user_data(resource);
|
||||||
|
+ if (!ipc_output)
|
||||||
|
+ return;
|
||||||
|
+ monitor = ipc_output->mon;
|
||||||
|
+
|
||||||
|
+ if (!newtags || newtags == monitor->tagset[monitor->seltags])
|
||||||
|
+ return;
|
||||||
|
+ if (toggle_tagset)
|
||||||
|
+ monitor->seltags ^= 1;
|
||||||
|
+
|
||||||
|
+ monitor->tagset[monitor->seltags] = newtags;
|
||||||
|
+ if (selmon == monitor)
|
||||||
|
+ focusclient(focustop(monitor), 1);
|
||||||
|
+ arrange(monitor);
|
||||||
|
+ printstatus();
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+void
|
||||||
|
+dwl_ipc_output_release(struct wl_client *client, struct wl_resource *resource)
|
||||||
|
+{
|
||||||
|
+ wl_resource_destroy(resource);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
focusclient(Client *c, int lift)
|
||||||
|
{
|
||||||
|
@@ -2033,41 +2248,9 @@ void
|
||||||
|
printstatus(void)
|
||||||
|
{
|
||||||
|
Monitor *m = NULL;
|
||||||
|
- Client *c;
|
||||||
|
- uint32_t occ, urg, sel;
|
||||||
|
- const char *appid, *title;
|
||||||
|
|
||||||
|
- wl_list_for_each(m, &mons, link) {
|
||||||
|
- occ = urg = 0;
|
||||||
|
- wl_list_for_each(c, &clients, link) {
|
||||||
|
- if (c->mon != m)
|
||||||
|
- continue;
|
||||||
|
- occ |= c->tags;
|
||||||
|
- if (c->isurgent)
|
||||||
|
- urg |= c->tags;
|
||||||
|
- }
|
||||||
|
- if ((c = focustop(m))) {
|
||||||
|
- title = client_get_title(c);
|
||||||
|
- appid = 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 floating %d\n", m->wlr_output->name, c->isfloating);
|
||||||
|
- sel = c->tags;
|
||||||
|
- } else {
|
||||||
|
- printf("%s title \n", m->wlr_output->name);
|
||||||
|
- printf("%s appid \n", m->wlr_output->name);
|
||||||
|
- printf("%s fullscreen \n", m->wlr_output->name);
|
||||||
|
- printf("%s floating \n", m->wlr_output->name);
|
||||||
|
- sel = 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- printf("%s selmon %u\n", m->wlr_output->name, m == selmon);
|
||||||
|
- printf("%s tags %"PRIu32" %"PRIu32" %"PRIu32" %"PRIu32"\n",
|
||||||
|
- m->wlr_output->name, occ, m->tagset[m->seltags], sel, urg);
|
||||||
|
- printf("%s layout %s\n", m->wlr_output->name, m->ltsymbol);
|
||||||
|
- }
|
||||||
|
- fflush(stdout);
|
||||||
|
+ wl_list_for_each(m, &mons, link)
|
||||||
|
+ dwl_ipc_output_printstatus(m);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
@@ -2584,6 +2770,8 @@ setup(void)
|
||||||
|
LISTEN_STATIC(&output_mgr->events.apply, outputmgrapply);
|
||||||
|
LISTEN_STATIC(&output_mgr->events.test, outputmgrtest);
|
||||||
|
|
||||||
|
+ wl_global_create(dpy, &zdwl_ipc_manager_v2_interface, 2, NULL, dwl_ipc_manager_bind);
|
||||||
|
+
|
||||||
|
/* Make sure XWayland clients don't connect to the parent X server,
|
||||||
|
* e.g when running in the x11 backend or the wayland backend and the
|
||||||
|
* compositor has Xwayland support */
|
||||||
|
@@ -2681,6 +2869,13 @@ tile(Monitor *m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+togglebar(const Arg *arg) {
|
||||||
|
+ DwlIpcOutput *ipc_output;
|
||||||
|
+ wl_list_for_each(ipc_output, &selmon->dwl_ipc_outputs, link)
|
||||||
|
+ zdwl_ipc_output_v2_send_toggle_visibility(ipc_output->resource);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
togglefloating(const Arg *arg)
|
||||||
|
{
|
||||||
|
diff --git a/protocols/dwl-ipc-unstable-v2.xml b/protocols/dwl-ipc-unstable-v2.xml
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..0a6e7e5
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/protocols/dwl-ipc-unstable-v2.xml
|
||||||
|
@@ -0,0 +1,181 @@
|
||||||
|
+<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
+<!--
|
||||||
|
+This is largely ripped from somebar's ipc patchset; just with some personal modifications.
|
||||||
|
+I would probably just submit raphi's patchset but I don't think that would be polite.
|
||||||
|
+-->
|
||||||
|
+<protocol name="dwl_ipc_unstable_v2">
|
||||||
|
+ <description summary="inter-proccess-communication about dwl's state">
|
||||||
|
+ This protocol allows clients to update and get updates from dwl.
|
||||||
|
+
|
||||||
|
+ Warning! The protocol described in this file is experimental and
|
||||||
|
+ backward incompatible changes may be made. Backward compatible
|
||||||
|
+ changes may be added together with the corresponding interface
|
||||||
|
+ version bump.
|
||||||
|
+ Backward incompatible changes are done by bumping the version
|
||||||
|
+ number in the protocol and interface names and resetting the
|
||||||
|
+ interface version. Once the protocol is to be declared stable,
|
||||||
|
+ the 'z' prefix and the version number in the protocol and
|
||||||
|
+ interface names are removed and the interface version number is
|
||||||
|
+ reset.
|
||||||
|
+ </description>
|
||||||
|
+
|
||||||
|
+ <interface name="zdwl_ipc_manager_v2" version="2">
|
||||||
|
+ <description summary="manage dwl state">
|
||||||
|
+ This interface is exposed as a global in wl_registry.
|
||||||
|
+
|
||||||
|
+ Clients can use this interface to get a dwl_ipc_output.
|
||||||
|
+ After binding the client will recieve the dwl_ipc_manager.tags and dwl_ipc_manager.layout events.
|
||||||
|
+ The dwl_ipc_manager.tags and dwl_ipc_manager.layout events expose tags and layouts to the client.
|
||||||
|
+ </description>
|
||||||
|
+
|
||||||
|
+ <request name="release" type="destructor">
|
||||||
|
+ <description summary="release dwl_ipc_manager">
|
||||||
|
+ Indicates that the client will not the dwl_ipc_manager object anymore.
|
||||||
|
+ Objects created through this instance are not affected.
|
||||||
|
+ </description>
|
||||||
|
+ </request>
|
||||||
|
+
|
||||||
|
+ <request name="get_output">
|
||||||
|
+ <description summary="get a dwl_ipc_outout for a wl_output">
|
||||||
|
+ Get a dwl_ipc_outout for the specified wl_output.
|
||||||
|
+ </description>
|
||||||
|
+ <arg name="id" type="new_id" interface="zdwl_ipc_output_v2"/>
|
||||||
|
+ <arg name="output" type="object" interface="wl_output"/>
|
||||||
|
+ </request>
|
||||||
|
+
|
||||||
|
+ <event name="tags">
|
||||||
|
+ <description summary="Announces tag amount">
|
||||||
|
+ This event is sent after binding.
|
||||||
|
+ A roundtrip after binding guarantees the client recieved all tags.
|
||||||
|
+ </description>
|
||||||
|
+ <arg name="amount" type="uint"/>
|
||||||
|
+ </event>
|
||||||
|
+
|
||||||
|
+ <event name="layout">
|
||||||
|
+ <description summary="Announces a layout">
|
||||||
|
+ This event is sent after binding.
|
||||||
|
+ A roundtrip after binding guarantees the client recieved all layouts.
|
||||||
|
+ </description>
|
||||||
|
+ <arg name="name" type="string"/>
|
||||||
|
+ </event>
|
||||||
|
+ </interface>
|
||||||
|
+
|
||||||
|
+ <interface name="zdwl_ipc_output_v2" version="2">
|
||||||
|
+ <description summary="control dwl output">
|
||||||
|
+ Observe and control a dwl output.
|
||||||
|
+
|
||||||
|
+ Events are double-buffered:
|
||||||
|
+ Clients should cache events and redraw when a dwl_ipc_output.frame event is sent.
|
||||||
|
+
|
||||||
|
+ Request are not double-buffered:
|
||||||
|
+ The compositor will update immediately upon request.
|
||||||
|
+ </description>
|
||||||
|
+
|
||||||
|
+ <enum name="tag_state">
|
||||||
|
+ <entry name="none" value="0" summary="no state"/>
|
||||||
|
+ <entry name="active" value="1" summary="tag is active"/>
|
||||||
|
+ <entry name="urgent" value="2" summary="tag has at least one urgent client"/>
|
||||||
|
+ </enum>
|
||||||
|
+
|
||||||
|
+ <request name="release" type="destructor">
|
||||||
|
+ <description summary="release dwl_ipc_outout">
|
||||||
|
+ Indicates to that the client no longer needs this dwl_ipc_output.
|
||||||
|
+ </description>
|
||||||
|
+ </request>
|
||||||
|
+
|
||||||
|
+ <event name="toggle_visibility">
|
||||||
|
+ <description summary="Toggle client visibilty">
|
||||||
|
+ Indicates the client should hide or show themselves.
|
||||||
|
+ If the client is visible then hide, if hidden then show.
|
||||||
|
+ </description>
|
||||||
|
+ </event>
|
||||||
|
+
|
||||||
|
+ <event name="active">
|
||||||
|
+ <description summary="Update the selected output.">
|
||||||
|
+ Indicates if the output is active. Zero is invalid, nonzero is valid.
|
||||||
|
+ </description>
|
||||||
|
+ <arg name="active" type="uint"/>
|
||||||
|
+ </event>
|
||||||
|
+
|
||||||
|
+ <event name="tag">
|
||||||
|
+ <description summary="Update the state of a tag.">
|
||||||
|
+ Indicates that a tag has been updated.
|
||||||
|
+ </description>
|
||||||
|
+ <arg name="tag" type="uint" summary="Index of the tag"/>
|
||||||
|
+ <arg name="state" type="uint" enum="tag_state" summary="The state of the tag."/>
|
||||||
|
+ <arg name="clients" type="uint" summary="The number of clients in the tag."/>
|
||||||
|
+ <arg name="focused" type="uint" summary="If there is a focused client. Nonzero being valid, zero being invalid."/>
|
||||||
|
+ </event>
|
||||||
|
+
|
||||||
|
+ <event name="layout">
|
||||||
|
+ <description summary="Update the layout.">
|
||||||
|
+ Indicates a new layout is selected.
|
||||||
|
+ </description>
|
||||||
|
+ <arg name="layout" type="uint" summary="Index of the layout."/>
|
||||||
|
+ </event>
|
||||||
|
+
|
||||||
|
+ <event name="title">
|
||||||
|
+ <description summary="Update the title.">
|
||||||
|
+ Indicates the title has changed.
|
||||||
|
+ </description>
|
||||||
|
+ <arg name="title" type="string" summary="The new title name."/>
|
||||||
|
+ </event>
|
||||||
|
+
|
||||||
|
+ <event name="appid" since="1">
|
||||||
|
+ <description summary="Update the appid.">
|
||||||
|
+ Indicates the appid has changed.
|
||||||
|
+ </description>
|
||||||
|
+ <arg name="appid" type="string" summary="The new appid."/>
|
||||||
|
+ </event>
|
||||||
|
+
|
||||||
|
+ <event name="layout_symbol" since="1">
|
||||||
|
+ <description summary="Update the current layout symbol">
|
||||||
|
+ Indicates the layout has changed. Since layout symbols are dynamic.
|
||||||
|
+ As opposed to the zdwl_ipc_manager.layout event, this should take precendence when displaying.
|
||||||
|
+ You can ignore the zdwl_ipc_output.layout event.
|
||||||
|
+ </description>
|
||||||
|
+ <arg name="layout" type="string" summary="The new layout"/>
|
||||||
|
+ </event>
|
||||||
|
+
|
||||||
|
+ <event name="frame">
|
||||||
|
+ <description summary="The update sequence is done.">
|
||||||
|
+ Indicates that a sequence of status updates have finished and the client should redraw.
|
||||||
|
+ </description>
|
||||||
|
+ </event>
|
||||||
|
+
|
||||||
|
+ <request name="set_tags">
|
||||||
|
+ <description summary="Set the active tags of this output"/>
|
||||||
|
+ <arg name="tagmask" type="uint" summary="bitmask of the tags that should be set."/>
|
||||||
|
+ <arg name="toggle_tagset" type="uint" summary="toggle the selected tagset, zero for invalid, nonzero for valid."/>
|
||||||
|
+ </request>
|
||||||
|
+
|
||||||
|
+ <request name="set_client_tags">
|
||||||
|
+ <description summary="Set the tags of the focused client.">
|
||||||
|
+ The tags are updated as follows:
|
||||||
|
+ new_tags = (current_tags AND and_tags) XOR xor_tags
|
||||||
|
+ </description>
|
||||||
|
+ <arg name="and_tags" type="uint"/>
|
||||||
|
+ <arg name="xor_tags" type="uint"/>
|
||||||
|
+ </request>
|
||||||
|
+
|
||||||
|
+ <request name="set_layout">
|
||||||
|
+ <description summary="Set the layout of this output"/>
|
||||||
|
+ <arg name="index" type="uint" summary="index of a layout recieved by dwl_ipc_manager.layout"/>
|
||||||
|
+ </request>
|
||||||
|
+
|
||||||
|
+ <!-- Version 2 -->
|
||||||
|
+ <event name="fullscreen" since="2">
|
||||||
|
+ <description summary="Update fullscreen status">
|
||||||
|
+ Indicates if the selected client on this output is fullscreen.
|
||||||
|
+ </description>
|
||||||
|
+ <arg name="is_fullscreen" type="uint" summary="If the selected client is fullscreen. Nonzero is valid, zero invalid"/>
|
||||||
|
+ </event>
|
||||||
|
+
|
||||||
|
+ <event name="floating" since="2">
|
||||||
|
+ <description summary="Update the floating status">
|
||||||
|
+ Indicates if the selected client on this output is floating.
|
||||||
|
+ </description>
|
||||||
|
+ <arg name="is_floating" type="uint" summary="If the selected client is floating. Nonzero is valid, zero invalid"/>
|
||||||
|
+ </event>
|
||||||
|
+ </interface>
|
||||||
|
+</protocol>
|
||||||
|
--
|
||||||
|
2.43.0
|
||||||
|
|
||||||
79
dwl-0.7/etc/portage/patches/gui-wm/dwl/movestack.patch
Normal file
79
dwl-0.7/etc/portage/patches/gui-wm/dwl/movestack.patch
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
From b051f50233033b399db324b29ab24227257ac141 Mon Sep 17 00:00:00 2001
|
||||||
|
From: wochap <gean.marroquin@gmail.com>
|
||||||
|
Date: Tue, 5 Mar 2024 23:31:51 -0500
|
||||||
|
Subject: [PATCH] apply NikitaIvanovV movestack patch
|
||||||
|
|
||||||
|
source: https://github.com/djpohly/dwl/wiki/movestack
|
||||||
|
---
|
||||||
|
config.def.h | 2 ++
|
||||||
|
dwl.c | 35 +++++++++++++++++++++++++++++++++++
|
||||||
|
2 files changed, 37 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index db0babc..778a0dc 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -122,6 +122,8 @@ static const Key keys[] = {
|
||||||
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, spawn, {.v = termcmd} },
|
||||||
|
{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },
|
||||||
|
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
|
||||||
|
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_J, movestack, {.i = +1} },
|
||||||
|
+ { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K, movestack, {.i = -1} },
|
||||||
|
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
|
||||||
|
{ MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
|
||||||
|
{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05} },
|
||||||
|
diff --git a/dwl.c b/dwl.c
|
||||||
|
index ef27a1d..69b9756 100644
|
||||||
|
--- a/dwl.c
|
||||||
|
+++ b/dwl.c
|
||||||
|
@@ -279,6 +279,7 @@ static void maplayersurfacenotify(struct wl_listener *listener, void *data);
|
||||||
|
static void mapnotify(struct wl_listener *listener, void *data);
|
||||||
|
static void maximizenotify(struct wl_listener *listener, void *data);
|
||||||
|
static void monocle(Monitor *m);
|
||||||
|
+static void movestack(const Arg *arg);
|
||||||
|
static void motionabsolute(struct wl_listener *listener, void *data);
|
||||||
|
static void motionnotify(uint32_t time);
|
||||||
|
static void motionrelative(struct wl_listener *listener, void *data);
|
||||||
|
@@ -1603,6 +1604,40 @@ monocle(Monitor *m)
|
||||||
|
wlr_scene_node_raise_to_top(&c->scene->node);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+movestack(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ Client *c, *sel = focustop(selmon);
|
||||||
|
+
|
||||||
|
+ if (!sel) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (wl_list_length(&clients) <= 1) {
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (arg->i > 0) {
|
||||||
|
+ wl_list_for_each(c, &sel->link, link) {
|
||||||
|
+ if (VISIBLEON(c, selmon) || &c->link == &clients) {
|
||||||
|
+ break; /* found it */
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ wl_list_for_each_reverse(c, &sel->link, link) {
|
||||||
|
+ if (VISIBLEON(c, selmon) || &c->link == &clients) {
|
||||||
|
+ break; /* found it */
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ /* backup one client */
|
||||||
|
+ c = wl_container_of(c->link.prev, c, link);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ wl_list_remove(&sel->link);
|
||||||
|
+ wl_list_insert(&c->link, &sel->link);
|
||||||
|
+ arrange(selmon);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
motionabsolute(struct wl_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
--
|
||||||
|
2.42.0
|
||||||
170
dwl-0.7/etc/portage/patches/gui-wm/dwl/pertag.patch
Normal file
170
dwl-0.7/etc/portage/patches/gui-wm/dwl/pertag.patch
Normal file
|
|
@ -0,0 +1,170 @@
|
||||||
|
From d3b551ffe3ec85e16341962e322150b81af6722f Mon Sep 17 00:00:00 2001
|
||||||
|
From: wochap <gean.marroquin@gmail.com>
|
||||||
|
Date: Wed, 31 Jul 2024 08:27:26 -0500
|
||||||
|
Subject: [PATCH] makes layout, mwfact and nmaster individual for every tag
|
||||||
|
|
||||||
|
inspiration: https://github.com/djpohly/dwl/wiki/pertag
|
||||||
|
---
|
||||||
|
dwl.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----
|
||||||
|
1 file changed, 70 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dwl.c b/dwl.c
|
||||||
|
index 145fd01..2f364bc 100644
|
||||||
|
--- a/dwl.c
|
||||||
|
+++ b/dwl.c
|
||||||
|
@@ -102,6 +102,7 @@ typedef struct {
|
||||||
|
const Arg arg;
|
||||||
|
} Button;
|
||||||
|
|
||||||
|
+typedef struct Pertag Pertag;
|
||||||
|
typedef struct Monitor Monitor;
|
||||||
|
typedef struct {
|
||||||
|
/* Must keep these three elements in this order */
|
||||||
|
@@ -199,6 +200,7 @@ struct Monitor {
|
||||||
|
struct wlr_box w; /* window area, layout-relative */
|
||||||
|
struct wl_list layers[4]; /* LayerSurface.link */
|
||||||
|
const Layout *lt[2];
|
||||||
|
+ Pertag *pertag;
|
||||||
|
unsigned int seltags;
|
||||||
|
unsigned int sellt;
|
||||||
|
uint32_t tagset[2];
|
||||||
|
@@ -427,6 +429,14 @@ static xcb_atom_t netatom[NetLast];
|
||||||
|
/* attempt to encapsulate suck into one file */
|
||||||
|
#include "client.h"
|
||||||
|
|
||||||
|
+struct Pertag {
|
||||||
|
+ unsigned int curtag, prevtag; /* current and previous tag */
|
||||||
|
+ int nmasters[TAGCOUNT + 1]; /* number of windows in master area */
|
||||||
|
+ float mfacts[TAGCOUNT + 1]; /* mfacts per tag */
|
||||||
|
+ unsigned int sellts[TAGCOUNT + 1]; /* selected layouts */
|
||||||
|
+ const Layout *ltidxs[TAGCOUNT + 1][2]; /* matrix of tags and layouts indexes */
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
/* function implementations */
|
||||||
|
void
|
||||||
|
applybounds(Client *c, struct wlr_box *bbox)
|
||||||
|
@@ -712,6 +722,7 @@ cleanupmon(struct wl_listener *listener, void *data)
|
||||||
|
wlr_output_layout_remove(output_layout, m->wlr_output);
|
||||||
|
wlr_scene_output_destroy(m->scene_output);
|
||||||
|
|
||||||
|
+ free(m->pertag);
|
||||||
|
closemon(m);
|
||||||
|
wlr_scene_node_destroy(&m->fullscreen_bg->node);
|
||||||
|
free(m);
|
||||||
|
@@ -983,6 +994,18 @@ createmon(struct wl_listener *listener, void *data)
|
||||||
|
wl_list_insert(&mons, &m->link);
|
||||||
|
printstatus();
|
||||||
|
|
||||||
|
+ m->pertag = calloc(1, sizeof(Pertag));
|
||||||
|
+ m->pertag->curtag = m->pertag->prevtag = 1;
|
||||||
|
+
|
||||||
|
+ for (i = 0; i <= TAGCOUNT; i++) {
|
||||||
|
+ m->pertag->nmasters[i] = m->nmaster;
|
||||||
|
+ m->pertag->mfacts[i] = m->mfact;
|
||||||
|
+
|
||||||
|
+ m->pertag->ltidxs[i][0] = m->lt[0];
|
||||||
|
+ m->pertag->ltidxs[i][1] = m->lt[1];
|
||||||
|
+ m->pertag->sellts[i] = m->sellt;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
/* The xdg-protocol specifies:
|
||||||
|
*
|
||||||
|
* If the fullscreened surface is not opaque, the compositor must make
|
||||||
|
@@ -1472,7 +1495,7 @@ incnmaster(const Arg *arg)
|
||||||
|
{
|
||||||
|
if (!arg || !selmon)
|
||||||
|
return;
|
||||||
|
- selmon->nmaster = MAX(selmon->nmaster + arg->i, 0);
|
||||||
|
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag] = MAX(selmon->nmaster + arg->i, 0);
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2305,9 +2328,9 @@ setlayout(const Arg *arg)
|
||||||
|
if (!selmon)
|
||||||
|
return;
|
||||||
|
if (!arg || !arg->v || arg->v != selmon->lt[selmon->sellt])
|
||||||
|
- selmon->sellt ^= 1;
|
||||||
|
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag] ^= 1;
|
||||||
|
if (arg && arg->v)
|
||||||
|
- selmon->lt[selmon->sellt] = (Layout *)arg->v;
|
||||||
|
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt] = (Layout *)arg->v;
|
||||||
|
strncpy(selmon->ltsymbol, selmon->lt[selmon->sellt]->symbol, LENGTH(selmon->ltsymbol));
|
||||||
|
arrange(selmon);
|
||||||
|
printstatus();
|
||||||
|
@@ -2324,7 +2347,7 @@ setmfact(const Arg *arg)
|
||||||
|
f = arg->f < 1.0f ? arg->f + selmon->mfact : arg->f - 1.0f;
|
||||||
|
if (f < 0.1 || f > 0.9)
|
||||||
|
return;
|
||||||
|
- selmon->mfact = f;
|
||||||
|
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag] = f;
|
||||||
|
arrange(selmon);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -2701,9 +2724,29 @@ void
|
||||||
|
toggleview(const Arg *arg)
|
||||||
|
{
|
||||||
|
uint32_t newtagset;
|
||||||
|
+ size_t i;
|
||||||
|
if (!(newtagset = selmon ? selmon->tagset[selmon->seltags] ^ (arg->ui & TAGMASK) : 0))
|
||||||
|
return;
|
||||||
|
|
||||||
|
+ if (newtagset == (uint32_t)~0) {
|
||||||
|
+ selmon->pertag->prevtag = selmon->pertag->curtag;
|
||||||
|
+ selmon->pertag->curtag = 0;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* test if the user did not select the same tag */
|
||||||
|
+ if (!(newtagset & 1 << (selmon->pertag->curtag - 1))) {
|
||||||
|
+ selmon->pertag->prevtag = selmon->pertag->curtag;
|
||||||
|
+ for (i = 0; !(newtagset & 1 << i); i++) ;
|
||||||
|
+ selmon->pertag->curtag = i + 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* apply settings for this view */
|
||||||
|
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
|
||||||
|
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
|
||||||
|
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
|
||||||
|
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
|
||||||
|
+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
|
||||||
|
+
|
||||||
|
selmon->tagset[selmon->seltags] = newtagset;
|
||||||
|
focusclient(focustop(selmon), 1);
|
||||||
|
arrange(selmon);
|
||||||
|
@@ -2892,11 +2935,33 @@ urgent(struct wl_listener *listener, void *data)
|
||||||
|
void
|
||||||
|
view(const Arg *arg)
|
||||||
|
{
|
||||||
|
+ size_t i, tmptag;
|
||||||
|
+
|
||||||
|
if (!selmon || (arg->ui & TAGMASK) == selmon->tagset[selmon->seltags])
|
||||||
|
return;
|
||||||
|
selmon->seltags ^= 1; /* toggle sel tagset */
|
||||||
|
- if (arg->ui & TAGMASK)
|
||||||
|
+ if (arg->ui & ~0) {
|
||||||
|
selmon->tagset[selmon->seltags] = arg->ui & TAGMASK;
|
||||||
|
+ selmon->pertag->prevtag = selmon->pertag->curtag;
|
||||||
|
+
|
||||||
|
+ if (arg->ui == TAGMASK)
|
||||||
|
+ selmon->pertag->curtag = 0;
|
||||||
|
+ else {
|
||||||
|
+ for (i = 0; !(arg->ui & 1 << i); i++) ;
|
||||||
|
+ selmon->pertag->curtag = i + 1;
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ tmptag = selmon->pertag->prevtag;
|
||||||
|
+ selmon->pertag->prevtag = selmon->pertag->curtag;
|
||||||
|
+ selmon->pertag->curtag = tmptag;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ selmon->nmaster = selmon->pertag->nmasters[selmon->pertag->curtag];
|
||||||
|
+ selmon->mfact = selmon->pertag->mfacts[selmon->pertag->curtag];
|
||||||
|
+ selmon->sellt = selmon->pertag->sellts[selmon->pertag->curtag];
|
||||||
|
+ selmon->lt[selmon->sellt] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt];
|
||||||
|
+ selmon->lt[selmon->sellt^1] = selmon->pertag->ltidxs[selmon->pertag->curtag][selmon->sellt^1];
|
||||||
|
+
|
||||||
|
focusclient(focustop(selmon), 1);
|
||||||
|
arrange(selmon);
|
||||||
|
printstatus();
|
||||||
|
--
|
||||||
|
2.45.2
|
||||||
|
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
From 024d66e3c81d5acb35b5be51f4812fe84614530b Mon Sep 17 00:00:00 2001
|
||||||
|
From: wochap <gean.marroquin@gmail.com>
|
||||||
|
Date: Fri, 5 Jul 2024 11:07:06 -0500
|
||||||
|
Subject: [PATCH] implement xkb-rules-switcher
|
||||||
|
|
||||||
|
---
|
||||||
|
config.def.h | 17 +++++++++++------
|
||||||
|
dwl.c | 19 ++++++++++++++++++-
|
||||||
|
2 files changed, 29 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/config.def.h b/config.def.h
|
||||||
|
index 22d2171..ab73cf0 100644
|
||||||
|
--- a/config.def.h
|
||||||
|
+++ b/config.def.h
|
||||||
|
@@ -52,12 +52,16 @@ static const MonitorRule monrules[] = {
|
||||||
|
};
|
||||||
|
|
||||||
|
/* keyboard */
|
||||||
|
-static const struct xkb_rule_names xkb_rules = {
|
||||||
|
- /* can specify fields: rules, model, layout, variant, options */
|
||||||
|
- /* example:
|
||||||
|
- .options = "ctrl:nocaps",
|
||||||
|
- */
|
||||||
|
- .options = NULL,
|
||||||
|
+static const struct xkb_rule_names xkb_rules[] = {
|
||||||
|
+ {
|
||||||
|
+ /* can specify fields: rules, model, layout, variant, options */
|
||||||
|
+ .layout = "us",
|
||||||
|
+ .options = NULL,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .layout = "us",
|
||||||
|
+ .options = "compose:ralt",
|
||||||
|
+ },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const int repeat_rate = 25;
|
||||||
|
@@ -148,6 +152,7 @@ static const Key keys[] = {
|
||||||
|
{ MODKEY, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} },
|
||||||
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT} },
|
||||||
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT} },
|
||||||
|
+ { MODKEY, XKB_KEY_w, switchxkbrule, {0} },
|
||||||
|
TAGKEYS( XKB_KEY_1, XKB_KEY_exclam, 0),
|
||||||
|
TAGKEYS( XKB_KEY_2, XKB_KEY_at, 1),
|
||||||
|
TAGKEYS( XKB_KEY_3, XKB_KEY_numbersign, 2),
|
||||||
|
diff --git a/dwl.c b/dwl.c
|
||||||
|
index dc0437e..ecbdf9a 100644
|
||||||
|
--- a/dwl.c
|
||||||
|
+++ b/dwl.c
|
||||||
|
@@ -371,6 +371,7 @@ static void setsel(struct wl_listener *listener, void *data);
|
||||||
|
static void setup(void);
|
||||||
|
static void spawn(const Arg *arg);
|
||||||
|
static void startdrag(struct wl_listener *listener, void *data);
|
||||||
|
+static void switchxkbrule(const Arg *arg);
|
||||||
|
static void tag(const Arg *arg);
|
||||||
|
static void tagmon(const Arg *arg);
|
||||||
|
static void tile(Monitor *m);
|
||||||
|
@@ -400,6 +401,7 @@ static struct wl_listener lock_listener = {.notify = locksession};
|
||||||
|
static struct wlr_seat *seat;
|
||||||
|
static KeyboardGroup *kb_group;
|
||||||
|
static unsigned int cursor_mode;
|
||||||
|
+static unsigned int xkb_rule_index = 0;
|
||||||
|
static Client *grabc;
|
||||||
|
static int grabcx, grabcy; /* client-relative */
|
||||||
|
|
||||||
|
@@ -838,7 +840,7 @@ createkeyboardgroup(void)
|
||||||
|
|
||||||
|
/* Prepare an XKB keymap and assign it to the keyboard group. */
|
||||||
|
context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
|
- if (!(keymap = xkb_keymap_new_from_names(context, &xkb_rules,
|
||||||
|
+ if (!(keymap = xkb_keymap_new_from_names(context, &xkb_rules[xkb_rule_index],
|
||||||
|
XKB_KEYMAP_COMPILE_NO_FLAGS)))
|
||||||
|
die("failed to compile keymap");
|
||||||
|
|
||||||
|
@@ -2614,6 +2616,21 @@ startdrag(struct wl_listener *listener, void *data)
|
||||||
|
LISTEN_STATIC(&drag->icon->events.destroy, destroydragicon);
|
||||||
|
}
|
||||||
|
|
||||||
|
+void
|
||||||
|
+switchxkbrule(const Arg *arg)
|
||||||
|
+{
|
||||||
|
+ struct xkb_context *context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
|
||||||
|
+ struct xkb_keymap *keymap;
|
||||||
|
+
|
||||||
|
+ xkb_rule_index = (xkb_rule_index + 1) % LENGTH(xkb_rules);
|
||||||
|
+ if (!(keymap = xkb_keymap_new_from_names(context, &xkb_rules[xkb_rule_index],
|
||||||
|
+ XKB_KEYMAP_COMPILE_NO_FLAGS)))
|
||||||
|
+ die("failed to compile keymap");
|
||||||
|
+ wlr_keyboard_set_keymap(&kb_group->wlr_group->keyboard, keymap);
|
||||||
|
+ xkb_keymap_unref(keymap);
|
||||||
|
+ xkb_context_unref(context);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void
|
||||||
|
tag(const Arg *arg)
|
||||||
|
{
|
||||||
|
--
|
||||||
|
2.45.1
|
||||||
|
|
||||||
|
|
@ -0,0 +1,97 @@
|
||||||
|
From c7d77ff4dec1da5a68b4da8aa42d4ed78dc41a00 Mon Sep 17 00:00:00 2001
|
||||||
|
From: choc <notchoc@proton.me>
|
||||||
|
Date: Thu, 14 Mar 2024 11:18:37 +0800
|
||||||
|
Subject: [PATCH] fix ipc to work with pertag
|
||||||
|
|
||||||
|
---
|
||||||
|
dwl.c | 50 +++++++++++++++++++++++++++++++++++---------------
|
||||||
|
1 file changed, 35 insertions(+), 15 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/dwl.c b/dwl.c
|
||||||
|
index a1a7809..d86e6e2 100644
|
||||||
|
--- a/dwl.c
|
||||||
|
+++ b/dwl.c
|
||||||
|
@@ -1526,28 +1526,37 @@ void
|
||||||
|
dwl_ipc_output_set_layout(struct wl_client *client, struct wl_resource *resource, uint32_t index)
|
||||||
|
{
|
||||||
|
DwlIpcOutput *ipc_output;
|
||||||
|
- Monitor *monitor;
|
||||||
|
+ Client *c = NULL;
|
||||||
|
+ Monitor *monitor = NULL;
|
||||||
|
|
||||||
|
ipc_output = wl_resource_get_user_data(resource);
|
||||||
|
if (!ipc_output)
|
||||||
|
return;
|
||||||
|
-
|
||||||
|
monitor = ipc_output->mon;
|
||||||
|
+
|
||||||
|
+ if (monitor != selmon)
|
||||||
|
+ c = focustop(selmon);
|
||||||
|
+
|
||||||
|
if (index >= LENGTH(layouts))
|
||||||
|
return;
|
||||||
|
- if (index != monitor->lt[monitor->sellt] - layouts)
|
||||||
|
- monitor->sellt ^= 1;
|
||||||
|
|
||||||
|
- monitor->lt[monitor->sellt] = &layouts[index];
|
||||||
|
- arrange(monitor);
|
||||||
|
- printstatus();
|
||||||
|
+ if (c) {
|
||||||
|
+ monitor = selmon;
|
||||||
|
+ selmon = ipc_output->mon;
|
||||||
|
+ }
|
||||||
|
+ setlayout(&(Arg){.v = &layouts[index]});
|
||||||
|
+ if (c) {
|
||||||
|
+ selmon = monitor;
|
||||||
|
+ focusclient(c, 0);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dwl_ipc_output_set_tags(struct wl_client *client, struct wl_resource *resource, uint32_t tagmask, uint32_t toggle_tagset)
|
||||||
|
{
|
||||||
|
DwlIpcOutput *ipc_output;
|
||||||
|
- Monitor *monitor;
|
||||||
|
+ Client *c = NULL;
|
||||||
|
+ Monitor *monitor = NULL;
|
||||||
|
unsigned int newtags = tagmask & TAGMASK;
|
||||||
|
|
||||||
|
ipc_output = wl_resource_get_user_data(resource);
|
||||||
|
@@ -1555,16 +1564,27 @@ dwl_ipc_output_set_tags(struct wl_client *client, struct wl_resource *resource,
|
||||||
|
return;
|
||||||
|
monitor = ipc_output->mon;
|
||||||
|
|
||||||
|
- if (!newtags || newtags == monitor->tagset[monitor->seltags])
|
||||||
|
+ if (monitor != selmon)
|
||||||
|
+ c = focustop(selmon);
|
||||||
|
+
|
||||||
|
+ if (!newtags)
|
||||||
|
return;
|
||||||
|
- if (toggle_tagset)
|
||||||
|
+
|
||||||
|
+ /* view toggles seltags for us so we un-toggle it */
|
||||||
|
+ if (!toggle_tagset) {
|
||||||
|
monitor->seltags ^= 1;
|
||||||
|
+ monitor->tagset[monitor->seltags] = 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- monitor->tagset[monitor->seltags] = newtags;
|
||||||
|
- if (selmon == monitor)
|
||||||
|
- focusclient(focustop(monitor), 1);
|
||||||
|
- arrange(monitor);
|
||||||
|
- printstatus();
|
||||||
|
+ if (c) {
|
||||||
|
+ monitor = selmon;
|
||||||
|
+ selmon = ipc_output->mon;
|
||||||
|
+ }
|
||||||
|
+ view(&(Arg){.ui = newtags});
|
||||||
|
+ if (c) {
|
||||||
|
+ selmon = monitor;
|
||||||
|
+ focusclient(c, 0);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
--
|
||||||
|
2.43.0
|
||||||
|
|
||||||
230
dwl-0.7/etc/portage/savedconfig/gui-wm/dwl-0.7
Normal file
230
dwl-0.7/etc/portage/savedconfig/gui-wm/dwl-0.7
Normal file
|
|
@ -0,0 +1,230 @@
|
||||||
|
/* Taken from https://github.com/djpohly/dwl/issues/466 */
|
||||||
|
#define COLOR(hex) { ((hex >> 24) & 0xFF) / 255.0f, \
|
||||||
|
((hex >> 16) & 0xFF) / 255.0f, \
|
||||||
|
((hex >> 8) & 0xFF) / 255.0f, \
|
||||||
|
(hex & 0xFF) / 255.0f }
|
||||||
|
/* appearance */
|
||||||
|
static const int sloppyfocus = 1; /* focus follows mouse */
|
||||||
|
static const int bypass_surface_visibility = 0; /* 1 means idle inhibitors will disable idle tracking even if it's surface isn't visible */
|
||||||
|
static const int smartgaps = 1; /* 1 means no outer gap when there is only one window */
|
||||||
|
static int gaps = 1; /* 1 means gaps between windows are added */
|
||||||
|
static const unsigned int gappx = 8; /* gap pixel between windows */
|
||||||
|
static const unsigned int borderpx = 2; /* border pixel of windows */
|
||||||
|
static const float rootcolor[] = COLOR(0x000000ff);
|
||||||
|
static const float bordercolor[] = COLOR(0x444444ff);
|
||||||
|
static const float focuscolor[] = COLOR(0xa3be8cff);
|
||||||
|
static const float urgentcolor[] = COLOR(0x770000ff);
|
||||||
|
/* This conforms to the xdg-protocol. Set the alpha to zero to restore the old behavior */
|
||||||
|
static const float fullscreen_bg[] = {0.1f, 0.1f, 0.1f, 1.0f}; /* You can also use glsl colors */
|
||||||
|
|
||||||
|
/* tagging - TAGCOUNT must be no greater than 31 */
|
||||||
|
#define TAGCOUNT (9)
|
||||||
|
|
||||||
|
/* logging */
|
||||||
|
static int log_level = WLR_ERROR;
|
||||||
|
|
||||||
|
/* Autostart */
|
||||||
|
static const char *const autostart[] = {
|
||||||
|
"mako", "--background-color=#222222FF", "--text-color=#A3BE8CFF", "--border-color=#A3BE8CFF", "", NULL,
|
||||||
|
// "cyclewallpapers", "/home/tanguy/Pictures/wallpapers", NULL,
|
||||||
|
"nm-applet", NULL,
|
||||||
|
"waybar", NULL,
|
||||||
|
"swaybg", "-i", "/home/tanguy/Pictures/wallpapers/P6012286.jpg", "-m", "fill", NULL,
|
||||||
|
"swaybg", "-o", "DP-2", "-i", "/home/tanguy/Pictures/wallpapers/P6012286.jpg", "-m", "fill", NULL,
|
||||||
|
"swaybg", "-o", "eDP-1", "-i", "/home/tanguy/Pictures/wallpapers/wallpaper11.jpg", "-m", "fill", NULL,
|
||||||
|
"wlsunset", "-l", "60.10", "-L", "24.56", NULL,
|
||||||
|
// "/usr/libexec/org_kde_powerdevil", NULL,
|
||||||
|
NULL /* terminate */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* NOTE: ALWAYS keep a rule declared even if you don't use rules (e.g leave at least one example) */
|
||||||
|
static const Rule rules[] = {
|
||||||
|
/* app_id title tags mask isfloating monitor */
|
||||||
|
/* examples: */
|
||||||
|
{ "Gimp_EXAMPLE", NULL, 0, 1, -1 }, /* Start on currently visible tags floating, not tiled */
|
||||||
|
{ "firefox_EXAMPLE", NULL, 1 << 8, 0, -1 }, /* Start on ONLY tag "9" */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* layout(s) */
|
||||||
|
static const Layout layouts[] = {
|
||||||
|
/* symbol arrange function */
|
||||||
|
{ "[]=", tile },
|
||||||
|
{ "><>", NULL }, /* no layout function means floating behavior */
|
||||||
|
{ "[M]", monocle },
|
||||||
|
};
|
||||||
|
|
||||||
|
/* monitors */
|
||||||
|
/* (x=-1, y=-1) is reserved as an "autoconfigure" monitor position indicator
|
||||||
|
* WARNING: negative values other than (-1, -1) cause problems with Xwayland clients
|
||||||
|
* https://gitlab.freedesktop.org/xorg/xserver/-/issues/899
|
||||||
|
*/
|
||||||
|
/* NOTE: ALWAYS add a fallback rule, even if you are completely sure it won't be used */
|
||||||
|
static const MonitorRule monrules[] = {
|
||||||
|
/* name mfact nmaster scale layout rotate/reflect x y */
|
||||||
|
/* example of a HiDPI laptop monitor:
|
||||||
|
{ "eDP-1", 0.5f, 1, 2, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
|
||||||
|
*/
|
||||||
|
/* defaults */
|
||||||
|
{ "DP-2", 0.55f, 1, 1.0, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, 0, 0 },
|
||||||
|
{ NULL, 0.55f, 1, 1.3, &layouts[0], WL_OUTPUT_TRANSFORM_NORMAL, -1, -1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct xkb_rule_names xkb_rules[] = {
|
||||||
|
{
|
||||||
|
/* can specify fields: rules, model, layout, variant, options */
|
||||||
|
.layout = "us",
|
||||||
|
.variant = "altgr-intl",
|
||||||
|
.options = NULL,
|
||||||
|
},
|
||||||
|
// {
|
||||||
|
// .layout = "fi",
|
||||||
|
// //.variant = "",
|
||||||
|
// .options = NULL,
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// .layout = "ua",
|
||||||
|
// .variant = "phonetic",
|
||||||
|
// .options = NULL,
|
||||||
|
// },
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static const int repeat_rate = 25;
|
||||||
|
static const int repeat_delay = 600;
|
||||||
|
|
||||||
|
/* Trackpad */
|
||||||
|
static const int tap_to_click = 1;
|
||||||
|
static const int tap_and_drag = 1;
|
||||||
|
static const int drag_lock = 1;
|
||||||
|
static const int natural_scrolling = 0;
|
||||||
|
static const int disable_while_typing = 1;
|
||||||
|
static const int left_handed = 0;
|
||||||
|
static const int middle_button_emulation = 0;
|
||||||
|
/* You can choose between:
|
||||||
|
LIBINPUT_CONFIG_SCROLL_NO_SCROLL
|
||||||
|
LIBINPUT_CONFIG_SCROLL_2FG
|
||||||
|
LIBINPUT_CONFIG_SCROLL_EDGE
|
||||||
|
LIBINPUT_CONFIG_SCROLL_ON_BUTTON_DOWN
|
||||||
|
*/
|
||||||
|
static const enum libinput_config_scroll_method scroll_method = LIBINPUT_CONFIG_SCROLL_2FG;
|
||||||
|
|
||||||
|
/* You can choose between:
|
||||||
|
LIBINPUT_CONFIG_CLICK_METHOD_NONE
|
||||||
|
LIBINPUT_CONFIG_CLICK_METHOD_BUTTON_AREAS
|
||||||
|
LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER
|
||||||
|
*/
|
||||||
|
static const enum libinput_config_click_method click_method = LIBINPUT_CONFIG_CLICK_METHOD_CLICKFINGER;
|
||||||
|
|
||||||
|
/* You can choose between:
|
||||||
|
LIBINPUT_CONFIG_SEND_EVENTS_ENABLED
|
||||||
|
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED
|
||||||
|
LIBINPUT_CONFIG_SEND_EVENTS_DISABLED_ON_EXTERNAL_MOUSE
|
||||||
|
*/
|
||||||
|
static const uint32_t send_events_mode = LIBINPUT_CONFIG_SEND_EVENTS_ENABLED;
|
||||||
|
|
||||||
|
/* You can choose between:
|
||||||
|
LIBINPUT_CONFIG_ACCEL_PROFILE_FLAT
|
||||||
|
LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE
|
||||||
|
*/
|
||||||
|
static const enum libinput_config_accel_profile accel_profile = LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE;
|
||||||
|
static const double accel_speed = 0.0;
|
||||||
|
|
||||||
|
/* You can choose between:
|
||||||
|
LIBINPUT_CONFIG_TAP_MAP_LRM -- 1/2/3 finger tap maps to left/right/middle
|
||||||
|
LIBINPUT_CONFIG_TAP_MAP_LMR -- 1/2/3 finger tap maps to left/middle/right
|
||||||
|
*/
|
||||||
|
static const enum libinput_config_tap_button_map button_map = LIBINPUT_CONFIG_TAP_MAP_LRM;
|
||||||
|
|
||||||
|
/* If you want to use the windows key for MODKEY, use WLR_MODIFIER_LOGO */
|
||||||
|
#define MODKEY WLR_MODIFIER_LOGO
|
||||||
|
|
||||||
|
#define TAGKEYS(KEY,SKEY,TAG) \
|
||||||
|
{ MODKEY, KEY, view, {.ui = 1 << TAG} }, \
|
||||||
|
{ MODKEY|WLR_MODIFIER_CTRL, KEY, toggleview, {.ui = 1 << TAG} }, \
|
||||||
|
{ MODKEY|WLR_MODIFIER_SHIFT, SKEY, tag, {.ui = 1 << TAG} }, \
|
||||||
|
{ MODKEY|WLR_MODIFIER_CTRL|WLR_MODIFIER_SHIFT,SKEY,toggletag, {.ui = 1 << TAG} }
|
||||||
|
|
||||||
|
/* helper for spawning shell commands in the pre dwm-5.0 fashion */
|
||||||
|
#define SHCMD(cmd) { .v = (const char*[]){ "/bin/sh", "-c", cmd, NULL } }
|
||||||
|
|
||||||
|
/* commands */
|
||||||
|
static const char *termcmd[] = { "foot", NULL };
|
||||||
|
static const char *menucmd[] = { "rofi", "-show", "run", NULL };
|
||||||
|
static const char *lockcmd[] = { "/usr/libexec/kscreenlocker_greet", NULL };
|
||||||
|
static const char *brightupcmd[] = { "sudo", "/usr/bin/brightnessctl", "set", "10%+", NULL };
|
||||||
|
static const char *brightdowncmd[] = { "sudo", "/usr/bin/brightnessctl", "set", "10%-", NULL };
|
||||||
|
static const char *prevcmd[] = { "playerctl", "previous", NULL };
|
||||||
|
static const char *playpausecmd[] = { "playerctl", "play-pause", NULL };
|
||||||
|
static const char *nextcmd[] = { "playerctl", "next", NULL };
|
||||||
|
static const char *mutecmd[] = { "wpctl", "set-mute", "@DEFAULT_SINK@", "toggle", NULL };
|
||||||
|
static const char *volumeupcmd[] = { "wpctl", "set-volume", "@DEFAULT_SINK@", "-l", "1", "5%+", NULL };
|
||||||
|
static const char *volumedowncmd[] = { "wpctl", "set-volume", "@DEFAULT_SINK@", "5%-", NULL };
|
||||||
|
|
||||||
|
static const Key keys[] = {
|
||||||
|
/* Note that Shift changes certain key codes: c -> C, 2 -> at, etc. */
|
||||||
|
/* modifier key function argument */
|
||||||
|
{ MODKEY, XKB_KEY_p, spawn, {.v = menucmd} },
|
||||||
|
{ MODKEY, XKB_KEY_Return, spawn, {.v = termcmd} },
|
||||||
|
{ MODKEY|WLR_MODIFIER_CTRL, XKB_KEY_l, spawn, {.v = lockcmd} },
|
||||||
|
{ 0, XKB_KEY_XF86MonBrightnessUp, spawn, {.v = brightupcmd} },
|
||||||
|
{ 0, XKB_KEY_XF86MonBrightnessDown, spawn, {.v = brightdowncmd} },
|
||||||
|
{ 0, XKB_KEY_XF86AudioPrev, spawn, {.v = prevcmd} },
|
||||||
|
{ 0, XKB_KEY_XF86AudioPlay, spawn, {.v = playpausecmd} },
|
||||||
|
{ 0, XKB_KEY_XF86AudioNext, spawn, {.v = nextcmd} },
|
||||||
|
{ 0, XKB_KEY_XF86AudioMute, spawn, {.v = mutecmd} },
|
||||||
|
{ 0, XKB_KEY_XF86AudioRaiseVolume, spawn, {.v = volumeupcmd} },
|
||||||
|
{ 0, XKB_KEY_XF86AudioLowerVolume, spawn, {.v = volumedowncmd} },
|
||||||
|
{ MODKEY, XKB_KEY_b, togglebar, {0} },
|
||||||
|
{ MODKEY, XKB_KEY_j, focusstack, {.i = +1} },
|
||||||
|
{ MODKEY, XKB_KEY_k, focusstack, {.i = -1} },
|
||||||
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_J, movestack, {.i = +1} },
|
||||||
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_K, movestack, {.i = -1} },
|
||||||
|
{ MODKEY, XKB_KEY_i, incnmaster, {.i = +1} },
|
||||||
|
{ MODKEY, XKB_KEY_d, incnmaster, {.i = -1} },
|
||||||
|
{ MODKEY, XKB_KEY_h, setmfact, {.f = -0.05f} },
|
||||||
|
{ MODKEY, XKB_KEY_l, setmfact, {.f = +0.05f} },
|
||||||
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Return, zoom, {0} },
|
||||||
|
{ MODKEY, XKB_KEY_Tab, view, {0} },
|
||||||
|
{ MODKEY, XKB_KEY_g, togglegaps, {0} },
|
||||||
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_C, killclient, {0} },
|
||||||
|
{ MODKEY, XKB_KEY_t, setlayout, {.v = &layouts[0]} },
|
||||||
|
{ MODKEY, XKB_KEY_f, setlayout, {.v = &layouts[1]} },
|
||||||
|
{ MODKEY, XKB_KEY_m, setlayout, {.v = &layouts[2]} },
|
||||||
|
{ MODKEY, XKB_KEY_space, setlayout, {0} },
|
||||||
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_space, togglefloating, {0} },
|
||||||
|
{ MODKEY, XKB_KEY_e, togglefullscreen, {0} },
|
||||||
|
{ MODKEY, XKB_KEY_0, view, {.ui = ~0} },
|
||||||
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_parenright, tag, {.ui = ~0} },
|
||||||
|
{ MODKEY, XKB_KEY_comma, focusmon, {.i = WLR_DIRECTION_LEFT} },
|
||||||
|
{ MODKEY, XKB_KEY_period, focusmon, {.i = WLR_DIRECTION_RIGHT} },
|
||||||
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_less, tagmon, {.i = WLR_DIRECTION_LEFT} },
|
||||||
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_greater, tagmon, {.i = WLR_DIRECTION_RIGHT} },
|
||||||
|
// { MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_question, switchxkbrule, {0} },
|
||||||
|
{ MODKEY, XKB_KEY_Escape, switchxkbrule, {0} },
|
||||||
|
TAGKEYS( XKB_KEY_1, XKB_KEY_exclam, 0),
|
||||||
|
TAGKEYS( XKB_KEY_2, XKB_KEY_at, 1),
|
||||||
|
TAGKEYS( XKB_KEY_3, XKB_KEY_numbersign, 2),
|
||||||
|
TAGKEYS( XKB_KEY_4, XKB_KEY_dollar, 3),
|
||||||
|
TAGKEYS( XKB_KEY_5, XKB_KEY_percent, 4),
|
||||||
|
TAGKEYS( XKB_KEY_6, XKB_KEY_asciicircum, 5),
|
||||||
|
TAGKEYS( XKB_KEY_7, XKB_KEY_ampersand, 6),
|
||||||
|
TAGKEYS( XKB_KEY_8, XKB_KEY_asterisk, 7),
|
||||||
|
TAGKEYS( XKB_KEY_9, XKB_KEY_parenleft, 8),
|
||||||
|
{ MODKEY|WLR_MODIFIER_SHIFT, XKB_KEY_Q, quit, {0} },
|
||||||
|
|
||||||
|
|
||||||
|
/* Ctrl-Alt-Backspace and Ctrl-Alt-Fx used to be handled by X server */
|
||||||
|
{ WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_Terminate_Server, quit, {0} },
|
||||||
|
/* Ctrl-Alt-Fx is used to switch to another VT, if you don't know what a VT is
|
||||||
|
* do not remove them.
|
||||||
|
*/
|
||||||
|
#define CHVT(n) { WLR_MODIFIER_CTRL|WLR_MODIFIER_ALT,XKB_KEY_XF86Switch_VT_##n, chvt, {.ui = (n)} }
|
||||||
|
CHVT(1), CHVT(2), CHVT(3), CHVT(4), CHVT(5), CHVT(6),
|
||||||
|
CHVT(7), CHVT(8), CHVT(9), CHVT(10), CHVT(11), CHVT(12),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const Button buttons[] = {
|
||||||
|
{ MODKEY, BTN_LEFT, moveresize, {.ui = CurMove} },
|
||||||
|
{ MODKEY, BTN_MIDDLE, togglefloating, {0} },
|
||||||
|
{ MODKEY, BTN_RIGHT, moveresize, {.ui = CurResize} },
|
||||||
|
};
|
||||||
3
startdwl
Executable file
3
startdwl
Executable file
|
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/sh
|
||||||
|
gentoo-pipewire-launcher &
|
||||||
|
exec dbus-run-session ssh-agent /usr/bin/dwl
|
||||||
Loading…
Add table
Reference in a new issue