commit
77bfbc4f7f
35
Makefile
35
Makefile
@ -33,6 +33,14 @@ $(error "Failed to query $(PKG_CONFIG) for package 'systemd'!")
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq (0,${WAYLAND})
|
||||||
|
DATA_DIR_WAYLAND_PROTOCOLS ?= $(shell $(PKG_CONFIG) wayland-protocols --variable=pkgdatadir)
|
||||||
|
DATA_DIR_WAYLAND_PROTOCOLS := ${DATA_DIR_WAYLAND_PROTOCOLS}
|
||||||
|
ifeq (,${DATA_DIR_WAYLAND_PROTOCOLS})
|
||||||
|
$(warning "Failed to query $(PKG_CONFIG) for package 'wayland-protocols'!")
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
LIBS := $(shell $(PKG_CONFIG) --libs ${pkg_config_packs})
|
LIBS := $(shell $(PKG_CONFIG) --libs ${pkg_config_packs})
|
||||||
INCS := $(shell $(PKG_CONFIG) --cflags ${pkg_config_packs})
|
INCS := $(shell $(PKG_CONFIG) --cflags ${pkg_config_packs})
|
||||||
|
|
||||||
@ -45,7 +53,14 @@ endif
|
|||||||
CFLAGS := ${DEFAULT_CPPFLAGS} ${CPPFLAGS} ${DEFAULT_CFLAGS} ${CFLAGS} ${INCS} -MMD -MP
|
CFLAGS := ${DEFAULT_CPPFLAGS} ${CPPFLAGS} ${DEFAULT_CFLAGS} ${CFLAGS} ${INCS} -MMD -MP
|
||||||
LDFLAGS := ${DEFAULT_LDFLAGS} ${LDFLAGS} ${LIBS}
|
LDFLAGS := ${DEFAULT_LDFLAGS} ${LDFLAGS} ${LIBS}
|
||||||
|
|
||||||
|
|
||||||
|
ifeq (0,${WAYLAND})
|
||||||
|
# without wayland support
|
||||||
|
SRC := $(sort $(shell ${FIND} src/ -not \( -path src/wayland -prune \) -name '*.c'))
|
||||||
|
else
|
||||||
|
# with Wayland support
|
||||||
SRC := $(sort $(shell ${FIND} src/ -name '*.c'))
|
SRC := $(sort $(shell ${FIND} src/ -name '*.c'))
|
||||||
|
endif
|
||||||
OBJ := ${SRC:.c=.o}
|
OBJ := ${SRC:.c=.o}
|
||||||
TEST_SRC := $(sort $(shell ${FIND} test/ -name '*.c'))
|
TEST_SRC := $(sort $(shell ${FIND} test/ -name '*.c'))
|
||||||
TEST_OBJ := $(TEST_SRC:.c=.o)
|
TEST_OBJ := $(TEST_SRC:.c=.o)
|
||||||
@ -118,7 +133,7 @@ docs/dunstctl.1: docs/dunstctl.pod
|
|||||||
doc-doxygen:
|
doc-doxygen:
|
||||||
${DOXYGEN} docs/internal/Doxyfile
|
${DOXYGEN} docs/internal/Doxyfile
|
||||||
|
|
||||||
.PHONY: service service-dbus service-systemd
|
.PHONY: service service-dbus service-systemd wayland-protocols
|
||||||
service: service-dbus
|
service: service-dbus
|
||||||
service-dbus:
|
service-dbus:
|
||||||
@${SED} "s|##PREFIX##|$(PREFIX)|" org.knopwob.dunst.service.in > org.knopwob.dunst.service
|
@${SED} "s|##PREFIX##|$(PREFIX)|" org.knopwob.dunst.service.in > org.knopwob.dunst.service
|
||||||
@ -128,7 +143,20 @@ service-systemd:
|
|||||||
@${SED} "s|##PREFIX##|$(PREFIX)|" dunst.systemd.service.in > dunst.systemd.service
|
@${SED} "s|##PREFIX##|$(PREFIX)|" dunst.systemd.service.in > dunst.systemd.service
|
||||||
endif
|
endif
|
||||||
|
|
||||||
.PHONY: clean clean-dunst clean-dunstify clean-doc clean-tests clean-coverage clean-coverage-run
|
ifneq (0,${WAYLAND})
|
||||||
|
wayland-protocols: src/wayland/protocols/wlr-layer-shell-unstable-v1.xml
|
||||||
|
mkdir -p src/wayland/protocols
|
||||||
|
wayland-scanner private-code ${DATA_DIR_WAYLAND_PROTOCOLS}/stable/xdg-shell/xdg-shell.xml src/wayland/protocols/xdg-shell.h
|
||||||
|
wayland-scanner client-header ${DATA_DIR_WAYLAND_PROTOCOLS}/stable/xdg-shell/xdg-shell.xml src/wayland/protocols/xdg-shell-client-header.h
|
||||||
|
wayland-scanner client-header ${DATA_DIR_WAYLAND_PROTOCOLS}/unstable/xdg-output/xdg-output-unstable-v1.xml src/wayland/protocols/xdg-output-unstable-v1-client-header.h
|
||||||
|
wayland-scanner private-code ${DATA_DIR_WAYLAND_PROTOCOLS}/unstable/xdg-output/xdg-output-unstable-v1.xml src/wayland/protocols/xdg-output-unstable-v1.h
|
||||||
|
wayland-scanner client-header src/wayland/protocols/wlr-layer-shell-unstable-v1.xml src/wayland/protocols/wlr-layer-shell-unstable-v1-client-header.h
|
||||||
|
wayland-scanner private-code src/wayland/protocols/wlr-layer-shell-unstable-v1.xml src/wayland/protocols/wlr-layer-shell-unstable-v1.h
|
||||||
|
wayland-scanner client-header src/wayland/protocols/idle.xml src/wayland/protocols/idle-client-header.h
|
||||||
|
wayland-scanner private-code src/wayland/protocols/idle.xml src/wayland/protocols/idle.h
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: clean clean-dunst clean-dunstify clean-doc clean-tests clean-coverage clean-coverage-run clean-wayland-protocols
|
||||||
clean: clean-dunst clean-dunstify clean-doc clean-tests clean-coverage clean-coverage-run
|
clean: clean-dunst clean-dunstify clean-doc clean-tests clean-coverage clean-coverage-run
|
||||||
|
|
||||||
clean-dunst:
|
clean-dunst:
|
||||||
@ -158,6 +186,9 @@ clean-coverage-run:
|
|||||||
${FIND} . -type f -name '*.gcov' -delete
|
${FIND} . -type f -name '*.gcov' -delete
|
||||||
${FIND} . -type f -name '*.gcda' -delete
|
${FIND} . -type f -name '*.gcda' -delete
|
||||||
|
|
||||||
|
clean-wayland-protocols:
|
||||||
|
rm -f src/wayland/protocols/*.h
|
||||||
|
|
||||||
.PHONY: install install-dunst install-dunstctl install-doc \
|
.PHONY: install install-dunst install-dunstctl install-doc \
|
||||||
install-service install-service-dbus install-service-systemd \
|
install-service install-service-dbus install-service-systemd \
|
||||||
uninstall uninstall-dunstctl \
|
uninstall uninstall-dunstctl \
|
||||||
|
@ -26,6 +26,8 @@ Dunst has a number of build dependencies that must be present before attempting
|
|||||||
- pango/cairo
|
- pango/cairo
|
||||||
- libgtk-3-dev
|
- libgtk-3-dev
|
||||||
- libnotify (for dunstify only)
|
- libnotify (for dunstify only)
|
||||||
|
- wayland-client (can build without, see [make parameters](#make-parameters))
|
||||||
|
- wayland-protocols (optional, for recompiling protocols)
|
||||||
|
|
||||||
### Building
|
### Building
|
||||||
|
|
||||||
@ -38,11 +40,13 @@ sudo make install
|
|||||||
|
|
||||||
### Make parameters
|
### Make parameters
|
||||||
|
|
||||||
|
- `DESTDIR=<PATH>`: Set the destination directory of the installation. (Default: `/`)
|
||||||
- `PREFIX=<PATH>`: Set the prefix of the installation. (Default: `/usr/local`)
|
- `PREFIX=<PATH>`: Set the prefix of the installation. (Default: `/usr/local`)
|
||||||
- `BINDIR=<PATH>`: Set the `dunst` executable's path (Default: `${PREFIX}/bin`)
|
- `BINDIR=<PATH>`: Set the `dunst` executable's path (Default: `${PREFIX}/bin`)
|
||||||
- `DATADIR=<PATH>`: Set the path for shared files. (Default: `${PREFIX}/share`)
|
- `DATADIR=<PATH>`: Set the path for shared files. (Default: `${PREFIX}/share`)
|
||||||
- `MANDIR=<PATH>`: Set the prefix of the manpage. (Default: `${DATADIR}/man`)
|
- `MANDIR=<PATH>`: Set the prefix of the manpage. (Default: `${DATADIR}/man`)
|
||||||
- `SYSTEMD=(0|1)`: Enable/Disable the systemd unit. (Default: detected via `pkg-config`)
|
- `SYSTEMD=(0|1)`: Enable/Disable the systemd unit. (Default: detected via `pkg-config`)
|
||||||
|
- `WAYLAND=(0|1)`: Enable/Disable wayland support. (Default: 1)
|
||||||
- `SERVICEDIR_SYSTEMD=<PATH>`: The path to put the systemd user service file. Unused, if `SYSTEMD=0`. (Default: detected via `pkg-config`)
|
- `SERVICEDIR_SYSTEMD=<PATH>`: The path to put the systemd user service file. Unused, if `SYSTEMD=0`. (Default: detected via `pkg-config`)
|
||||||
- `SERVICEDIR_DBUS=<PATH>`: The path to put the dbus service file. (Default: detected via `pkg-config`)
|
- `SERVICEDIR_DBUS=<PATH>`: The path to put the dbus service file. (Default: detected via `pkg-config`)
|
||||||
|
|
||||||
|
5
config.h
5
config.h
@ -48,6 +48,9 @@ struct settings defaults = {
|
|||||||
.notification_height = 0, /* if notification height < font height and padding, it will be raised */
|
.notification_height = 0, /* if notification height < font height and padding, it will be raised */
|
||||||
.corner_radius = 0,
|
.corner_radius = 0,
|
||||||
|
|
||||||
|
.force_xinerama = false,
|
||||||
|
.force_xwayland = false,
|
||||||
|
|
||||||
.separator_height = 2, /* height of the separator line between two notifications */
|
.separator_height = 2, /* height of the separator line between two notifications */
|
||||||
.padding = 0,
|
.padding = 0,
|
||||||
.h_padding = 0, /* horizontal padding */
|
.h_padding = 0, /* horizontal padding */
|
||||||
@ -122,6 +125,8 @@ struct settings defaults = {
|
|||||||
.progress_bar_frame_width = 1,
|
.progress_bar_frame_width = 1,
|
||||||
|
|
||||||
.progress_bar = true,
|
.progress_bar = true,
|
||||||
|
|
||||||
|
.layer = ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rule default_rules[] = {
|
struct rule default_rules[] = {
|
||||||
|
20
config.mk
20
config.mk
@ -20,14 +20,23 @@ VALGRIND ?= valgrind
|
|||||||
# if you don't want to use systemd albeit installed
|
# if you don't want to use systemd albeit installed
|
||||||
#SYSTEMD ?= 0
|
#SYSTEMD ?= 0
|
||||||
|
|
||||||
|
# Disable dependency on wayland. This will force dunst to use
|
||||||
|
# xwayland on wayland compositors
|
||||||
|
# You can also use "make WAYLAND=0" to build without wayland
|
||||||
|
# WAYLAND ?= 0
|
||||||
|
|
||||||
|
ifneq (0, ${WAYLAND})
|
||||||
|
ENABLE_WAYLAND= -DENABLE_WAYLAND
|
||||||
|
endif
|
||||||
|
|
||||||
# uncomment to disable parsing of dunstrc
|
# uncomment to disable parsing of dunstrc
|
||||||
# or use "CFLAGS=-DSTATIC_CONFIG make" to build
|
# or use "CFLAGS=-DSTATIC_CONFIG make" to build
|
||||||
#STATIC= -DSTATIC_CONFIG # Warning: This is deprecated behavior
|
#STATIC= -DSTATIC_CONFIG # Warning: This is deprecated behavior
|
||||||
|
|
||||||
# flags
|
# flags
|
||||||
DEFAULT_CPPFLAGS = -D_DEFAULT_SOURCE -DVERSION=\"${VERSION}\"
|
DEFAULT_CPPFLAGS = -D_DEFAULT_SOURCE -DVERSION=\"${VERSION}\"
|
||||||
DEFAULT_CFLAGS = -g --std=gnu99 -pedantic -Wall -Wno-overlength-strings -Os ${STATIC}
|
DEFAULT_CFLAGS = -g --std=gnu99 -pedantic -Wall -Wno-overlength-strings -Os ${STATIC} ${ENABLE_WAYLAND}
|
||||||
DEFAULT_LDFLAGS = -lm
|
DEFAULT_LDFLAGS = -lm -lrt
|
||||||
|
|
||||||
CPPFLAGS_DEBUG := -DDEBUG_BUILD
|
CPPFLAGS_DEBUG := -DDEBUG_BUILD
|
||||||
CFLAGS_DEBUG := -O0
|
CFLAGS_DEBUG := -O0
|
||||||
@ -41,11 +50,16 @@ pkg_config_packs := gio-2.0 \
|
|||||||
xinerama \
|
xinerama \
|
||||||
xext \
|
xext \
|
||||||
"xrandr >= 1.5" \
|
"xrandr >= 1.5" \
|
||||||
xscrnsaver
|
xscrnsaver \
|
||||||
|
|
||||||
|
|
||||||
# dunstify also needs libnotify
|
# dunstify also needs libnotify
|
||||||
pkg_config_packs += libnotify
|
pkg_config_packs += libnotify
|
||||||
|
|
||||||
|
ifneq (0,${WAYLAND})
|
||||||
|
pkg_config_packs += wayland-client
|
||||||
|
endif
|
||||||
|
|
||||||
ifneq (,$(findstring STATIC_CONFIG,$(CFLAGS)))
|
ifneq (,$(findstring STATIC_CONFIG,$(CFLAGS)))
|
||||||
$(warning STATIC_CONFIG is deprecated behavior. It will get removed in future releases)
|
$(warning STATIC_CONFIG is deprecated behavior. It will get removed in future releases)
|
||||||
endif
|
endif
|
||||||
|
@ -82,6 +82,10 @@ starts at 0. See the B<follow> setting.
|
|||||||
Defines where the notifications should be placed in a multi-monitor setup. All
|
Defines where the notifications should be placed in a multi-monitor setup. All
|
||||||
values except I<none> override the B<monitor> setting.
|
values except I<none> override the B<monitor> setting.
|
||||||
|
|
||||||
|
On Wayland there is no difference between mouse and keyboard focus. When either
|
||||||
|
of the is used, the compositor will choose an output. This will generally be
|
||||||
|
the output last interacted with.
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
|
|
||||||
=item B<none>
|
=item B<none>
|
||||||
@ -264,7 +268,27 @@ Set to 0 to disable.
|
|||||||
A client can mark a notification as transient to bypass this setting and timeout
|
A client can mark a notification as transient to bypass this setting and timeout
|
||||||
anyway. Use a rule with 'set_transient = no' to disable this behavior.
|
anyway. Use a rule with 'set_transient = no' to disable this behavior.
|
||||||
|
|
||||||
Note: this doesn't work on wayland yet.
|
Note: this doesn't work on xwayland.
|
||||||
|
|
||||||
|
=item B<layer> (Wayland only)
|
||||||
|
|
||||||
|
One of bottom, top or overlay.
|
||||||
|
|
||||||
|
Place dunst notifications on the selected layer. Using overlay
|
||||||
|
will cause notifications to be displayed above fullscreen windows, though
|
||||||
|
this may also occur at top depending on your compositor.
|
||||||
|
|
||||||
|
In Wayland, Notifications won't be delayed when in fullscreen (like when
|
||||||
|
setting B<fullscreen> to pushback in X11). This is a Wayland limitation.
|
||||||
|
|
||||||
|
The bottom layer is below all windows and above the background.
|
||||||
|
|
||||||
|
Default: overlay
|
||||||
|
|
||||||
|
=item B<force_xwayland> (values: [true/false], default: false) (Wayland only)
|
||||||
|
|
||||||
|
Force the use of X11 output, even on a wayland compositor. This setting
|
||||||
|
has no effect when not using a Wayland compositor.
|
||||||
|
|
||||||
=item B<font> (default: "Monospace 8")
|
=item B<font> (default: "Monospace 8")
|
||||||
|
|
||||||
@ -497,7 +521,7 @@ Do not display log messages, which have lower precedence than specified
|
|||||||
verbosity. This won't affect printing notifications on the terminal. Use
|
verbosity. This won't affect printing notifications on the terminal. Use
|
||||||
the '-print' option for this.
|
the '-print' option for this.
|
||||||
|
|
||||||
=item B<force_xinerama> (values: [true/false], default: false)
|
=item B<force_xinerama> (values: [true/false], default: false) (X11 only)
|
||||||
|
|
||||||
Use the Xinerama extension instead of RandR for multi-monitor support. This
|
Use the Xinerama extension instead of RandR for multi-monitor support. This
|
||||||
setting is provided for compatibility with older nVidia drivers that do not
|
setting is provided for compatibility with older nVidia drivers that do not
|
||||||
@ -552,7 +576,7 @@ the notification sent before the user defined timeout.
|
|||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
=head2 Shortcut section B<DEPRECATED SEE DUNSTCTL>
|
=head2 Shortcut section B<DEPRECATED SEE DUNSTCTL> (X11 only)
|
||||||
|
|
||||||
Keyboard shortcuts are defined in the following format: "Modifier+key" where the
|
Keyboard shortcuts are defined in the following format: "Modifier+key" where the
|
||||||
modifier is one of ctrl,mod1,mod2,mod3,mod4 and key is any keyboard key.
|
modifier is one of ctrl,mod1,mod2,mod3,mod4 and key is any keyboard key.
|
||||||
@ -662,6 +686,29 @@ Past notifications are redisplayed in a first-in-last-out order, meaning that
|
|||||||
pressing the history key once will bring up the most recent notification that
|
pressing the history key once will bring up the most recent notification that
|
||||||
had been closed/timed out.
|
had been closed/timed out.
|
||||||
|
|
||||||
|
=head1 WAYLAND
|
||||||
|
|
||||||
|
Dunst has Wayland support since version 1.6.0. Because the Wayland protocol
|
||||||
|
is more focused on security, some things that are possible in X11 are not
|
||||||
|
possible in Wayland. Those differences are reflected in the configuration.
|
||||||
|
The main things that change are that dunst on Wayland cannot use global
|
||||||
|
hotkeys (they are deprecated anyways, use dunstctl) and it cannot detect
|
||||||
|
if an application is fullscreen. If you want to see notifications when in
|
||||||
|
fullscreen, set B<layer = overlay> in the global options.
|
||||||
|
|
||||||
|
Note that the same limitations exist when using xwayland.
|
||||||
|
If something doesn't quite work in Wayland, please file a bug report. In the
|
||||||
|
mean time, you can try if the X11 output does work on wayland. Use
|
||||||
|
B<force_xwayland = true> for that.
|
||||||
|
|
||||||
|
If you have your dunst notifications on the same side of your display as your
|
||||||
|
status bar, you might notice that your notifications appear a bit higher or
|
||||||
|
lower than on X11. This is because the notification cannot be placed on top of
|
||||||
|
your status bar. The notifications are placed relative to your status bar,
|
||||||
|
making them appear higher or lower by the height of your status bar. We cannot
|
||||||
|
do anything about that behavior, so you will need to change your B<geometry>
|
||||||
|
variable accordingly.
|
||||||
|
|
||||||
=head1 RULES
|
=head1 RULES
|
||||||
|
|
||||||
Rules allow the conditional modification of notifications. They are defined by
|
Rules allow the conditional modification of notifications. They are defined by
|
||||||
@ -774,7 +821,7 @@ Equivalent to the C<format> setting.
|
|||||||
|
|
||||||
The frame color color of the notification. See COLORS for possible values.
|
The frame color color of the notification. See COLORS for possible values.
|
||||||
|
|
||||||
=item C<fullscreen>
|
=item C<fullscreen> (X11 only)
|
||||||
|
|
||||||
One of show, delay, or pushback.
|
One of show, delay, or pushback.
|
||||||
|
|
||||||
@ -789,6 +836,10 @@ Or pushback which is equivalent to delay with the difference that already
|
|||||||
existing notifications are paused and hidden until the focus to the fullscreen
|
existing notifications are paused and hidden until the focus to the fullscreen
|
||||||
window is lost.
|
window is lost.
|
||||||
|
|
||||||
|
See B<layer> to change fullscreen behavior in Wayland
|
||||||
|
|
||||||
|
Default: show
|
||||||
|
|
||||||
=item C<new_icon>
|
=item C<new_icon>
|
||||||
|
|
||||||
Updates the icon of the notification, it should be a path to a valid image.
|
Updates the icon of the notification, it should be a path to a valid image.
|
||||||
|
10
dunstrc
10
dunstrc
@ -247,6 +247,16 @@
|
|||||||
# user defined timeout.
|
# user defined timeout.
|
||||||
ignore_dbusclose = false
|
ignore_dbusclose = false
|
||||||
|
|
||||||
|
### Wayland ###
|
||||||
|
# These settings are Wayland-specific. They have no effect when using X11
|
||||||
|
|
||||||
|
# Uncomment this if you want to let notications appear under fullscreen
|
||||||
|
# applications (default: overlay)
|
||||||
|
# layer = top
|
||||||
|
|
||||||
|
# Set this to true to use X11 output on Wayland.
|
||||||
|
force_xwayland = false
|
||||||
|
|
||||||
### Legacy
|
### Legacy
|
||||||
|
|
||||||
# Use the Xinerama extension instead of RandR for multi-monitor support.
|
# Use the Xinerama extension instead of RandR for multi-monitor support.
|
||||||
|
21
src/dbus.c
21
src/dbus.c
@ -560,6 +560,27 @@ void signal_notification_closed(struct notification *n, enum reason reason)
|
|||||||
if (err) {
|
if (err) {
|
||||||
LOG_W("Unable to close notification: %s", err->message);
|
LOG_W("Unable to close notification: %s", err->message);
|
||||||
g_error_free(err);
|
g_error_free(err);
|
||||||
|
} else {
|
||||||
|
char* reason_string;
|
||||||
|
switch (reason) {
|
||||||
|
case REASON_TIME:
|
||||||
|
reason_string="time";
|
||||||
|
break;
|
||||||
|
case REASON_USER:
|
||||||
|
reason_string="user";
|
||||||
|
break;
|
||||||
|
case REASON_SIG:
|
||||||
|
reason_string="signal";
|
||||||
|
break;
|
||||||
|
case REASON_UNDEF:
|
||||||
|
reason_string="undfined";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
reason_string="unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_D("Queues: Closing notification for reason: %s", reason_string);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ PangoFontDescription *pango_fdesc;
|
|||||||
|
|
||||||
void draw_setup(void)
|
void draw_setup(void)
|
||||||
{
|
{
|
||||||
const struct output *out = output_create();
|
const struct output *out = output_create(settings.force_xwayland);
|
||||||
output = out;
|
output = out;
|
||||||
|
|
||||||
out->init();
|
out->init();
|
||||||
|
@ -9,7 +9,6 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <X11/Xlib.h>
|
|
||||||
|
|
||||||
#include "dbus.h"
|
#include "dbus.h"
|
||||||
#include "draw.h"
|
#include "draw.h"
|
||||||
@ -57,6 +56,7 @@ static gboolean run(void *data);
|
|||||||
|
|
||||||
void wake_up(void)
|
void wake_up(void)
|
||||||
{
|
{
|
||||||
|
LOG_D("Waking up");
|
||||||
run(NULL);
|
run(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,6 +86,8 @@ static gboolean run(void *data)
|
|||||||
gint64 sleep = queues_get_next_datachange(now);
|
gint64 sleep = queues_get_next_datachange(now);
|
||||||
gint64 timeout_at = now + sleep;
|
gint64 timeout_at = now + sleep;
|
||||||
|
|
||||||
|
LOG_D("Sleeping for %li ms", sleep/1000);
|
||||||
|
|
||||||
if (sleep >= 0) {
|
if (sleep >= 0) {
|
||||||
if (next_timeout < now || timeout_at < next_timeout) {
|
if (next_timeout < now || timeout_at < next_timeout) {
|
||||||
g_timeout_add(sleep/1000, run, NULL);
|
g_timeout_add(sleep/1000, run, NULL);
|
||||||
|
67
src/input.c
Normal file
67
src/input.c
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#include "input.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "settings.h"
|
||||||
|
#include "queues.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <linux/input-event-codes.h>
|
||||||
|
|
||||||
|
void input_handle_click(unsigned int button, bool button_down, int mouse_x, int mouse_y){
|
||||||
|
LOG_I("Pointer handle button %i: %i", button, button_down);
|
||||||
|
|
||||||
|
if (button_down) {
|
||||||
|
// make sure it only reacts on button release
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum mouse_action *acts;
|
||||||
|
|
||||||
|
switch (button) {
|
||||||
|
case BTN_LEFT:
|
||||||
|
acts = settings.mouse_left_click;
|
||||||
|
break;
|
||||||
|
case BTN_MIDDLE:
|
||||||
|
acts = settings.mouse_middle_click;
|
||||||
|
break;
|
||||||
|
case BTN_RIGHT:
|
||||||
|
acts = settings.mouse_right_click;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG_W("Unsupported mouse button: '%d'", button);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; acts[i]; i++) {
|
||||||
|
enum mouse_action act = acts[i];
|
||||||
|
if (act == MOUSE_CLOSE_ALL) {
|
||||||
|
queues_history_push_all();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (act == MOUSE_DO_ACTION || act == MOUSE_CLOSE_CURRENT) {
|
||||||
|
int y = settings.separator_height;
|
||||||
|
struct notification *n = NULL;
|
||||||
|
int first = true;
|
||||||
|
for (const GList *iter = queues_get_displayed(); iter;
|
||||||
|
iter = iter->next) {
|
||||||
|
n = iter->data;
|
||||||
|
if (mouse_y > y && mouse_y < y + n->displayed_height)
|
||||||
|
break;
|
||||||
|
|
||||||
|
y += n->displayed_height + settings.separator_height;
|
||||||
|
if (first)
|
||||||
|
y += settings.frame_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n) {
|
||||||
|
if (act == MOUSE_CLOSE_CURRENT) {
|
||||||
|
n->marked_for_closure = REASON_USER;
|
||||||
|
} else {
|
||||||
|
notification_do_action(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
wake_up();
|
||||||
|
}
|
||||||
|
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
18
src/input.h
Normal file
18
src/input.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef DUNST_INPUT_H
|
||||||
|
#define DUNST_INPUT_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle incoming mouse click events
|
||||||
|
*
|
||||||
|
* @param button code, A linux input event code
|
||||||
|
* @param button_down State of the button
|
||||||
|
* @param mouse_x X-position of the mouse, relative to the window
|
||||||
|
* @param mouse_y Y-position of the mouse, relative to the window
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void input_handle_click(unsigned int button, bool button_down, int mouse_x, int mouse_y);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
@ -189,6 +189,18 @@ bool string_parse_urgency(const char *s, enum urgency *ret)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool string_parse_layer(const char *s, enum zwlr_layer_shell_v1_layer *ret)
|
||||||
|
{
|
||||||
|
ASSERT_OR_RET(STR_FULL(s), false);
|
||||||
|
ASSERT_OR_RET(ret, false);
|
||||||
|
|
||||||
|
STRING_PARSE_RET("bottom", ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM);
|
||||||
|
STRING_PARSE_RET("top", ZWLR_LAYER_SHELL_V1_LAYER_TOP);
|
||||||
|
STRING_PARSE_RET("overlay", ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
struct section *new_section(const char *name)
|
struct section *new_section(const char *name)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < section_count; i++) {
|
for (int i = 0; i < section_count; i++) {
|
||||||
|
@ -20,6 +20,7 @@ bool string_parse_mouse_action(const char *s, enum mouse_action *ret);
|
|||||||
bool string_parse_mouse_action_list(char **s, enum mouse_action **ret);
|
bool string_parse_mouse_action_list(char **s, enum mouse_action **ret);
|
||||||
bool string_parse_sepcolor(const char *s, struct separator_color_data *ret);
|
bool string_parse_sepcolor(const char *s, struct separator_color_data *ret);
|
||||||
bool string_parse_urgency(const char *s, enum urgency *ret);
|
bool string_parse_urgency(const char *s, enum urgency *ret);
|
||||||
|
bool string_parse_layer(const char *s, enum zwlr_layer_shell_v1_layer *ret);
|
||||||
|
|
||||||
int load_ini_file(FILE *);
|
int load_ini_file(FILE *);
|
||||||
char *ini_get_path(const char *section, const char *key, const char *def);
|
char *ini_get_path(const char *section, const char *key, const char *def);
|
||||||
|
54
src/output.c
54
src/output.c
@ -3,9 +3,12 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "x11/x.h"
|
#include "x11/x.h"
|
||||||
#include "x11/screen.h"
|
#include "x11/screen.h"
|
||||||
/* #include "wayland/wl.h" */ // Not yet
|
|
||||||
|
|
||||||
const bool is_running_wayland(void){
|
#ifdef ENABLE_WAYLAND
|
||||||
|
#include "wayland/wl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const bool is_running_wayland(void) {
|
||||||
char* wayland_display = getenv("WAYLAND_DISPLAY");
|
char* wayland_display = getenv("WAYLAND_DISPLAY");
|
||||||
return !(wayland_display == NULL);
|
return !(wayland_display == NULL);
|
||||||
}
|
}
|
||||||
@ -30,33 +33,40 @@ const struct output output_x11 = {
|
|||||||
have_fullscreen_window
|
have_fullscreen_window
|
||||||
};
|
};
|
||||||
|
|
||||||
/* const struct output output_wl = { */
|
#ifdef ENABLE_WAYLAND
|
||||||
/* wl_init, */
|
const struct output output_wl = {
|
||||||
/* wl_deinit, */
|
wl_init,
|
||||||
|
wl_deinit,
|
||||||
|
|
||||||
/* wl_win_create, */
|
wl_win_create,
|
||||||
/* wl_win_destroy, */
|
wl_win_destroy,
|
||||||
|
|
||||||
/* wl_win_show, */
|
wl_win_show,
|
||||||
/* wl_win_hide, */
|
wl_win_hide,
|
||||||
|
|
||||||
/* wl_display_surface, */
|
wl_display_surface,
|
||||||
/* wl_win_visible, */
|
wl_win_visible,
|
||||||
/* wl_win_get_context, */
|
wl_win_get_context,
|
||||||
|
|
||||||
/* wl_get_active_screen, */
|
wl_get_active_screen,
|
||||||
|
|
||||||
/* wl_is_idle, */
|
wl_is_idle,
|
||||||
/* wl_have_fullscreen_window */
|
wl_have_fullscreen_window
|
||||||
/* }; */
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
const struct output* output_create(void)
|
const struct output* output_create(bool force_xwayland)
|
||||||
{
|
{
|
||||||
if (is_running_wayland()) {
|
#ifdef ENABLE_WAYLAND
|
||||||
LOG_I("System is running wayland");
|
if (!force_xwayland && is_running_wayland()) {
|
||||||
} else{
|
LOG_I("Using Wayland output");
|
||||||
LOG_I("System is running X11");
|
return &output_wl;
|
||||||
}
|
} else {
|
||||||
|
LOG_I("Using X11 output");
|
||||||
return &output_x11;
|
return &output_x11;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
return &output_x11;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
||||||
|
@ -47,7 +47,7 @@ struct output {
|
|||||||
bool (*have_fullscreen_window)(void);
|
bool (*have_fullscreen_window)(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct output* output_create(void);
|
const struct output* output_create(bool force_xwayland);
|
||||||
|
|
||||||
const bool is_running_wayland(void);
|
const bool is_running_wayland(void);
|
||||||
|
|
||||||
|
@ -144,8 +144,7 @@ static bool queues_notification_is_finished(struct notification *n, struct dunst
|
|||||||
bool is_idle = status.fullscreen ? false : status.idle;
|
bool is_idle = status.fullscreen ? false : status.idle;
|
||||||
|
|
||||||
/* don't timeout when user is idle */
|
/* don't timeout when user is idle */
|
||||||
/* NOTE: Idle is not working on wayland */
|
if (is_idle && !n->transient) {
|
||||||
if (is_idle && !n->transient && !is_running_wayland()) {
|
|
||||||
n->start = time_monotonic_now();
|
n->start = time_monotonic_now();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "rules.h"
|
#include "rules.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "x11/x.h"
|
#include "x11/x.h"
|
||||||
|
#include "output.h"
|
||||||
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
|
|
||||||
@ -118,6 +119,12 @@ void load_settings(char *cmdline_config_path)
|
|||||||
"Force the use of the Xinerama extension"
|
"Force the use of the Xinerama extension"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
settings.force_xwayland = option_get_bool(
|
||||||
|
"global",
|
||||||
|
"force_xwayland", "-force_xwayland", false,
|
||||||
|
"Force the use of the xwayland output"
|
||||||
|
);
|
||||||
|
|
||||||
settings.font = option_get_string(
|
settings.font = option_get_string(
|
||||||
"global",
|
"global",
|
||||||
"font", "-font/-fn", defaults.font,
|
"font", "-font/-fn", defaults.font,
|
||||||
@ -209,6 +216,22 @@ void load_settings(char *cmdline_config_path)
|
|||||||
"Don't timeout notifications if user is longer idle than threshold"
|
"Don't timeout notifications if user is longer idle than threshold"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#ifndef ENABLE_WAYLAND
|
||||||
|
if (is_running_wayland()){
|
||||||
|
/* We are using xwayland now. Setting force_xwayland to make sure
|
||||||
|
* the idle workaround below is activated */
|
||||||
|
settings.force_xwayland = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (settings.force_xwayland && is_running_wayland()) {
|
||||||
|
if (settings.idle_threshold > 0)
|
||||||
|
LOG_W("Using xwayland. Disabling idle.");
|
||||||
|
/* There is no way to detect if the user is idle
|
||||||
|
* on xwayland, so turn this feature off */
|
||||||
|
settings.idle_threshold = 0;
|
||||||
|
}
|
||||||
|
|
||||||
settings.monitor = option_get_int(
|
settings.monitor = option_get_int(
|
||||||
"global",
|
"global",
|
||||||
"monitor", "-mon/-monitor", defaults.monitor,
|
"monitor", "-mon/-monitor", defaults.monitor,
|
||||||
@ -486,6 +509,22 @@ void load_settings(char *cmdline_config_path)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
char *c = option_get_string(
|
||||||
|
"global",
|
||||||
|
"layer", "-layer", "overlay",
|
||||||
|
"Select the layer where notifications should be placed"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!string_parse_layer(c, &settings.layer)) {
|
||||||
|
if (c)
|
||||||
|
LOG_W("Unknown layer: '%s'", c);
|
||||||
|
settings.layer = defaults.layer;
|
||||||
|
}
|
||||||
|
g_free(c);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
settings.min_icon_size = option_get_int(
|
settings.min_icon_size = option_get_int(
|
||||||
"global",
|
"global",
|
||||||
"min_icon_size", "-min_icon_size", defaults.min_icon_size,
|
"min_icon_size", "-min_icon_size", defaults.min_icon_size,
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifdef ENABLE_WAYLAND
|
||||||
|
#include "wayland/protocols/wlr-layer-shell-unstable-v1-client-header.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "markup.h"
|
#include "markup.h"
|
||||||
#include "notification.h"
|
#include "notification.h"
|
||||||
#include "x11/x.h"
|
#include "x11/x.h"
|
||||||
@ -15,6 +19,16 @@ enum vertical_alignment { VERTICAL_TOP, VERTICAL_CENTER, VERTICAL_BOTTOM };
|
|||||||
enum separator_color { SEP_FOREGROUND, SEP_AUTO, SEP_FRAME, SEP_CUSTOM };
|
enum separator_color { SEP_FOREGROUND, SEP_AUTO, SEP_FRAME, SEP_CUSTOM };
|
||||||
enum follow_mode { FOLLOW_NONE, FOLLOW_MOUSE, FOLLOW_KEYBOARD };
|
enum follow_mode { FOLLOW_NONE, FOLLOW_MOUSE, FOLLOW_KEYBOARD };
|
||||||
enum mouse_action { MOUSE_NONE, MOUSE_DO_ACTION, MOUSE_CLOSE_CURRENT, MOUSE_CLOSE_ALL };
|
enum mouse_action { MOUSE_NONE, MOUSE_DO_ACTION, MOUSE_CLOSE_CURRENT, MOUSE_CLOSE_ALL };
|
||||||
|
#ifndef ZWLR_LAYER_SHELL_V1_LAYER_ENUM
|
||||||
|
#define ZWLR_LAYER_SHELL_V1_LAYER_ENUM
|
||||||
|
// Needed for compiling without wayland dependency
|
||||||
|
enum zwlr_layer_shell_v1_layer {
|
||||||
|
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND = 0,
|
||||||
|
ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM = 1,
|
||||||
|
ZWLR_LAYER_SHELL_V1_LAYER_TOP = 2,
|
||||||
|
ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY = 3,
|
||||||
|
};
|
||||||
|
#endif /* ZWLR_LAYER_SHELL_V1_LAYER_ENUM */
|
||||||
|
|
||||||
struct separator_color_data {
|
struct separator_color_data {
|
||||||
enum separator_color type;
|
enum separator_color type;
|
||||||
@ -88,6 +102,7 @@ struct settings {
|
|||||||
struct keyboard_shortcut history_ks;
|
struct keyboard_shortcut history_ks;
|
||||||
struct keyboard_shortcut context_ks;
|
struct keyboard_shortcut context_ks;
|
||||||
bool force_xinerama;
|
bool force_xinerama;
|
||||||
|
bool force_xwayland;
|
||||||
int corner_radius;
|
int corner_radius;
|
||||||
enum mouse_action *mouse_left_click;
|
enum mouse_action *mouse_left_click;
|
||||||
enum mouse_action *mouse_middle_click;
|
enum mouse_action *mouse_middle_click;
|
||||||
@ -97,6 +112,7 @@ struct settings {
|
|||||||
int progress_bar_max_width;
|
int progress_bar_max_width;
|
||||||
int progress_bar_frame_width;
|
int progress_bar_frame_width;
|
||||||
bool progress_bar;
|
bool progress_bar;
|
||||||
|
enum zwlr_layer_shell_v1_layer layer;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct settings settings;
|
extern struct settings settings;
|
||||||
|
192
src/wayland/libgwater-wayland.c
Normal file
192
src/wayland/libgwater-wayland.c
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
/*
|
||||||
|
* libgwater-wayland - Wayland GSource
|
||||||
|
*
|
||||||
|
* Copyright © 2014-2017 Quentin "Sardem FF7" Glidic
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif /* HAVE_CONFIG_H */
|
||||||
|
|
||||||
|
#ifdef G_LOG_DOMAIN
|
||||||
|
#undef G_LOG_DOMAIN
|
||||||
|
#endif /* G_LOG_DOMAIN */
|
||||||
|
#define G_LOG_DOMAIN "GWaterWayland"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include <wayland-client.h>
|
||||||
|
|
||||||
|
#include "libgwater-wayland.h"
|
||||||
|
|
||||||
|
struct _GWaterWaylandSource {
|
||||||
|
GSource source;
|
||||||
|
gboolean display_owned;
|
||||||
|
struct wl_display *display;
|
||||||
|
gpointer fd;
|
||||||
|
int error;
|
||||||
|
};
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_g_water_wayland_source_prepare(GSource *source, gint *timeout)
|
||||||
|
{
|
||||||
|
GWaterWaylandSource *self = (GWaterWaylandSource *)source;
|
||||||
|
|
||||||
|
*timeout = 0;
|
||||||
|
if ( wl_display_prepare_read(self->display) != 0 )
|
||||||
|
return TRUE;
|
||||||
|
else if ( wl_display_flush(self->display) < 0 )
|
||||||
|
{
|
||||||
|
self->error = errno;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
*timeout = -1;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_g_water_wayland_source_check(GSource *source)
|
||||||
|
{
|
||||||
|
GWaterWaylandSource *self = (GWaterWaylandSource *)source;
|
||||||
|
|
||||||
|
if ( self->error > 0 )
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
GIOCondition revents;
|
||||||
|
revents = g_source_query_unix_fd(source, self->fd);
|
||||||
|
|
||||||
|
if ( revents & G_IO_IN )
|
||||||
|
{
|
||||||
|
if ( wl_display_read_events(self->display) < 0 )
|
||||||
|
self->error = errno;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
wl_display_cancel_read(self->display);
|
||||||
|
|
||||||
|
return ( revents > 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
_g_water_wayland_source_dispatch(GSource *source, GSourceFunc callback, gpointer user_data)
|
||||||
|
{
|
||||||
|
GWaterWaylandSource *self = (GWaterWaylandSource *)source;
|
||||||
|
GIOCondition revents;
|
||||||
|
|
||||||
|
revents = g_source_query_unix_fd(source, self->fd);
|
||||||
|
if ( ( self->error > 0 ) || ( revents & (G_IO_ERR | G_IO_HUP) ) )
|
||||||
|
{
|
||||||
|
errno = self->error;
|
||||||
|
self->error = 0;
|
||||||
|
if ( callback != NULL )
|
||||||
|
return callback(user_data);
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( wl_display_dispatch_pending(self->display) < 0 )
|
||||||
|
{
|
||||||
|
if ( callback != NULL )
|
||||||
|
return callback(user_data);
|
||||||
|
return G_SOURCE_REMOVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return G_SOURCE_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_g_water_wayland_source_finalize(GSource *source)
|
||||||
|
{
|
||||||
|
GWaterWaylandSource *self = (GWaterWaylandSource *)source;
|
||||||
|
|
||||||
|
if ( self->display_owned )
|
||||||
|
wl_display_disconnect(self->display);
|
||||||
|
}
|
||||||
|
|
||||||
|
static GSourceFuncs _g_water_wayland_source_funcs = {
|
||||||
|
.prepare = _g_water_wayland_source_prepare,
|
||||||
|
.check = _g_water_wayland_source_check,
|
||||||
|
.dispatch = _g_water_wayland_source_dispatch,
|
||||||
|
.finalize = _g_water_wayland_source_finalize,
|
||||||
|
};
|
||||||
|
|
||||||
|
GWaterWaylandSource *
|
||||||
|
g_water_wayland_source_new(GMainContext *context, const gchar *name)
|
||||||
|
{
|
||||||
|
struct wl_display *display;
|
||||||
|
GWaterWaylandSource *self;
|
||||||
|
|
||||||
|
display = wl_display_connect(name);
|
||||||
|
if ( display == NULL )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
self = g_water_wayland_source_new_for_display(context, display);
|
||||||
|
self->display_owned = TRUE;
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
GWaterWaylandSource *
|
||||||
|
g_water_wayland_source_new_for_display(GMainContext *context, struct wl_display *display)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail(display != NULL, NULL);
|
||||||
|
|
||||||
|
GSource *source;
|
||||||
|
GWaterWaylandSource *self;
|
||||||
|
|
||||||
|
source = g_source_new(&_g_water_wayland_source_funcs, sizeof(GWaterWaylandSource));
|
||||||
|
self = (GWaterWaylandSource *)source;
|
||||||
|
self->display = display;
|
||||||
|
|
||||||
|
self->fd = g_source_add_unix_fd(source, wl_display_get_fd(self->display), G_IO_IN | G_IO_ERR | G_IO_HUP);
|
||||||
|
|
||||||
|
g_source_attach(source, context);
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_water_wayland_source_free(GWaterWaylandSource *self)
|
||||||
|
{
|
||||||
|
GSource * source = (GSource *)self;
|
||||||
|
g_return_if_fail(self != NULL);
|
||||||
|
|
||||||
|
g_source_destroy(source);
|
||||||
|
|
||||||
|
g_source_unref(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
g_water_wayland_source_set_error_callback(GWaterWaylandSource *self, GSourceFunc callback, gpointer user_data, GDestroyNotify destroy_notify)
|
||||||
|
{
|
||||||
|
g_return_if_fail(self != NULL);
|
||||||
|
|
||||||
|
g_source_set_callback((GSource *)self, callback, user_data, destroy_notify);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wl_display *
|
||||||
|
g_water_wayland_source_get_display(GWaterWaylandSource *self)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail(self != NULL, NULL);
|
||||||
|
|
||||||
|
return self->display;
|
||||||
|
}
|
42
src/wayland/libgwater-wayland.h
Normal file
42
src/wayland/libgwater-wayland.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* libgwater-wayland - Wayland GSource
|
||||||
|
*
|
||||||
|
* Copyright © 2014-2017 Quentin "Sardem FF7" Glidic
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __G_WATER_WAYLAND_H__
|
||||||
|
#define __G_WATER_WAYLAND_H__
|
||||||
|
|
||||||
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
|
typedef struct _GWaterWaylandSource GWaterWaylandSource;
|
||||||
|
|
||||||
|
GWaterWaylandSource *g_water_wayland_source_new(GMainContext *context, const gchar *name);
|
||||||
|
GWaterWaylandSource *g_water_wayland_source_new_for_display(GMainContext *context, struct wl_display *display);
|
||||||
|
void g_water_wayland_source_free(GWaterWaylandSource *self);
|
||||||
|
|
||||||
|
void g_water_wayland_source_set_error_callback(GWaterWaylandSource *self, GSourceFunc callback, gpointer user_data, GDestroyNotify destroy_notify);
|
||||||
|
struct wl_display *g_water_wayland_source_get_display(GWaterWaylandSource *source);
|
||||||
|
|
||||||
|
G_END_DECLS
|
||||||
|
|
||||||
|
#endif /* __G_WATER_WAYLAND_H__ */
|
150
src/wayland/pool-buffer.c
Normal file
150
src/wayland/pool-buffer.c
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
#define _POSIX_C_SOURCE 200112L
|
||||||
|
#include <cairo/cairo.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <wayland-client.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "pool-buffer.h"
|
||||||
|
|
||||||
|
static void randname(char *buf) {
|
||||||
|
struct timespec ts;
|
||||||
|
clock_gettime(CLOCK_REALTIME, &ts);
|
||||||
|
long r = ts.tv_nsec;
|
||||||
|
for (int i = 0; i < 6; ++i) {
|
||||||
|
buf[i] = 'A'+(r&15)+(r&16)*2;
|
||||||
|
r >>= 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int anonymous_shm_open(void) {
|
||||||
|
char name[] = "/dunst-XXXXXX";
|
||||||
|
int retries = 100;
|
||||||
|
|
||||||
|
do {
|
||||||
|
randname(name + strlen(name) - 6);
|
||||||
|
|
||||||
|
--retries;
|
||||||
|
// shm_open guarantees that O_CLOEXEC is set
|
||||||
|
int fd = shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||||
|
if (fd >= 0) {
|
||||||
|
shm_unlink(name);
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
} while (retries > 0 && errno == EEXIST);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int create_shm_file(off_t size) {
|
||||||
|
int fd = anonymous_shm_open();
|
||||||
|
if (fd < 0) {
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ftruncate(fd, size) < 0) {
|
||||||
|
close(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void buffer_handle_release(void *data, struct wl_buffer *wl_buffer) {
|
||||||
|
struct pool_buffer *buffer = data;
|
||||||
|
buffer->busy = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_buffer_listener buffer_listener = {
|
||||||
|
.release = buffer_handle_release,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct pool_buffer *create_buffer(struct wl_shm *shm,
|
||||||
|
struct pool_buffer *buf, int32_t width, int32_t height) {
|
||||||
|
const enum wl_shm_format wl_fmt = WL_SHM_FORMAT_ARGB8888;
|
||||||
|
const cairo_format_t cairo_fmt = CAIRO_FORMAT_ARGB32;
|
||||||
|
|
||||||
|
uint32_t stride = cairo_format_stride_for_width(cairo_fmt, width);
|
||||||
|
size_t size = stride * height;
|
||||||
|
|
||||||
|
void *data = NULL;
|
||||||
|
if (size > 0) {
|
||||||
|
int fd = create_shm_file(size);
|
||||||
|
if (fd == -1) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
|
if (data == MAP_FAILED) {
|
||||||
|
close(fd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, size);
|
||||||
|
buf->buffer =
|
||||||
|
wl_shm_pool_create_buffer(pool, 0, width, height, stride, wl_fmt);
|
||||||
|
wl_buffer_add_listener(buf->buffer, &buffer_listener, buf);
|
||||||
|
wl_shm_pool_destroy(pool);
|
||||||
|
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
buf->data = data;
|
||||||
|
buf->size = size;
|
||||||
|
buf->width = width;
|
||||||
|
buf->height = height;
|
||||||
|
buf->surface = cairo_image_surface_create_for_data(data, cairo_fmt, width,
|
||||||
|
height, stride);
|
||||||
|
buf->cairo = cairo_create(buf->surface);
|
||||||
|
buf->pango = pango_cairo_create_context(buf->cairo);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void finish_buffer(struct pool_buffer *buffer) {
|
||||||
|
if (buffer->buffer) {
|
||||||
|
wl_buffer_destroy(buffer->buffer);
|
||||||
|
}
|
||||||
|
if (buffer->cairo) {
|
||||||
|
cairo_destroy(buffer->cairo);
|
||||||
|
}
|
||||||
|
if (buffer->surface) {
|
||||||
|
cairo_surface_destroy(buffer->surface);
|
||||||
|
}
|
||||||
|
if (buffer->pango) {
|
||||||
|
g_object_unref(buffer->pango);
|
||||||
|
}
|
||||||
|
if (buffer->data) {
|
||||||
|
munmap(buffer->data, buffer->size);
|
||||||
|
}
|
||||||
|
memset(buffer, 0, sizeof(struct pool_buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pool_buffer *get_next_buffer(struct wl_shm *shm,
|
||||||
|
struct pool_buffer pool[static 2], uint32_t width, uint32_t height) {
|
||||||
|
struct pool_buffer *buffer = NULL;
|
||||||
|
for (size_t i = 0; i < 2; ++i) {
|
||||||
|
if (pool[i].busy) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
buffer = &pool[i];
|
||||||
|
}
|
||||||
|
if (!buffer) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (buffer->width != width || buffer->height != height) {
|
||||||
|
finish_buffer(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!buffer->buffer) {
|
||||||
|
if (!create_buffer(shm, buffer, width, height)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
26
src/wayland/pool-buffer.h
Normal file
26
src/wayland/pool-buffer.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#ifndef DUNST_POOL_BUFFER_H
|
||||||
|
#define DUNST_POOL_BUFFER_H
|
||||||
|
|
||||||
|
#include <cairo/cairo.h>
|
||||||
|
#include <pango/pangocairo.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <wayland-client.h>
|
||||||
|
|
||||||
|
struct pool_buffer {
|
||||||
|
struct wl_buffer *buffer;
|
||||||
|
cairo_surface_t *surface;
|
||||||
|
cairo_t *cairo;
|
||||||
|
PangoContext *pango;
|
||||||
|
uint32_t width, height;
|
||||||
|
void *data;
|
||||||
|
size_t size;
|
||||||
|
bool busy;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct pool_buffer *get_next_buffer(struct wl_shm *shm,
|
||||||
|
struct pool_buffer pool[static 2], uint32_t width, uint32_t height);
|
||||||
|
void finish_buffer(struct pool_buffer *buffer);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
233
src/wayland/protocols/idle-client-header.h
Normal file
233
src/wayland/protocols/idle-client-header.h
Normal file
@ -0,0 +1,233 @@
|
|||||||
|
/* Generated by wayland-scanner 1.18.0 */
|
||||||
|
|
||||||
|
#ifndef IDLE_CLIENT_PROTOCOL_H
|
||||||
|
#define IDLE_CLIENT_PROTOCOL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "wayland-client.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page page_idle The idle protocol
|
||||||
|
* @section page_ifaces_idle Interfaces
|
||||||
|
* - @subpage page_iface_org_kde_kwin_idle - User idle time manager
|
||||||
|
* - @subpage page_iface_org_kde_kwin_idle_timeout -
|
||||||
|
* @section page_copyright_idle Copyright
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Martin Gräßlin
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2.1 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
struct org_kde_kwin_idle;
|
||||||
|
struct org_kde_kwin_idle_timeout;
|
||||||
|
struct wl_seat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page page_iface_org_kde_kwin_idle org_kde_kwin_idle
|
||||||
|
* @section page_iface_org_kde_kwin_idle_desc Description
|
||||||
|
*
|
||||||
|
* This interface allows to monitor user idle time on a given seat. The interface
|
||||||
|
* allows to register timers which trigger after no user activity was registered
|
||||||
|
* on the seat for a given interval. It notifies when user activity resumes.
|
||||||
|
*
|
||||||
|
* This is useful for applications wanting to perform actions when the user is not
|
||||||
|
* interacting with the system, e.g. chat applications setting the user as away, power
|
||||||
|
* management features to dim screen, etc..
|
||||||
|
* @section page_iface_org_kde_kwin_idle_api API
|
||||||
|
* See @ref iface_org_kde_kwin_idle.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_org_kde_kwin_idle The org_kde_kwin_idle interface
|
||||||
|
*
|
||||||
|
* This interface allows to monitor user idle time on a given seat. The interface
|
||||||
|
* allows to register timers which trigger after no user activity was registered
|
||||||
|
* on the seat for a given interval. It notifies when user activity resumes.
|
||||||
|
*
|
||||||
|
* This is useful for applications wanting to perform actions when the user is not
|
||||||
|
* interacting with the system, e.g. chat applications setting the user as away, power
|
||||||
|
* management features to dim screen, etc..
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface org_kde_kwin_idle_interface;
|
||||||
|
/**
|
||||||
|
* @page page_iface_org_kde_kwin_idle_timeout org_kde_kwin_idle_timeout
|
||||||
|
* @section page_iface_org_kde_kwin_idle_timeout_api API
|
||||||
|
* See @ref iface_org_kde_kwin_idle_timeout.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_org_kde_kwin_idle_timeout The org_kde_kwin_idle_timeout interface
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface org_kde_kwin_idle_timeout_interface;
|
||||||
|
|
||||||
|
#define ORG_KDE_KWIN_IDLE_GET_IDLE_TIMEOUT 0
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_org_kde_kwin_idle
|
||||||
|
*/
|
||||||
|
#define ORG_KDE_KWIN_IDLE_GET_IDLE_TIMEOUT_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_org_kde_kwin_idle */
|
||||||
|
static inline void
|
||||||
|
org_kde_kwin_idle_set_user_data(struct org_kde_kwin_idle *org_kde_kwin_idle, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) org_kde_kwin_idle, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_org_kde_kwin_idle */
|
||||||
|
static inline void *
|
||||||
|
org_kde_kwin_idle_get_user_data(struct org_kde_kwin_idle *org_kde_kwin_idle)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) org_kde_kwin_idle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
org_kde_kwin_idle_get_version(struct org_kde_kwin_idle *org_kde_kwin_idle)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) org_kde_kwin_idle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_org_kde_kwin_idle */
|
||||||
|
static inline void
|
||||||
|
org_kde_kwin_idle_destroy(struct org_kde_kwin_idle *org_kde_kwin_idle)
|
||||||
|
{
|
||||||
|
wl_proxy_destroy((struct wl_proxy *) org_kde_kwin_idle);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_org_kde_kwin_idle
|
||||||
|
*/
|
||||||
|
static inline struct org_kde_kwin_idle_timeout *
|
||||||
|
org_kde_kwin_idle_get_idle_timeout(struct org_kde_kwin_idle *org_kde_kwin_idle, struct wl_seat *seat, uint32_t timeout)
|
||||||
|
{
|
||||||
|
struct wl_proxy *id;
|
||||||
|
|
||||||
|
id = wl_proxy_marshal_constructor((struct wl_proxy *) org_kde_kwin_idle,
|
||||||
|
ORG_KDE_KWIN_IDLE_GET_IDLE_TIMEOUT, &org_kde_kwin_idle_timeout_interface, NULL, seat, timeout);
|
||||||
|
|
||||||
|
return (struct org_kde_kwin_idle_timeout *) id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_org_kde_kwin_idle_timeout
|
||||||
|
* @struct org_kde_kwin_idle_timeout_listener
|
||||||
|
*/
|
||||||
|
struct org_kde_kwin_idle_timeout_listener {
|
||||||
|
/**
|
||||||
|
* Triggered when there has not been any user activity in the requested idle time interval
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void (*idle)(void *data,
|
||||||
|
struct org_kde_kwin_idle_timeout *org_kde_kwin_idle_timeout);
|
||||||
|
/**
|
||||||
|
* Triggered on the first user activity after an idle event
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void (*resumed)(void *data,
|
||||||
|
struct org_kde_kwin_idle_timeout *org_kde_kwin_idle_timeout);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_org_kde_kwin_idle_timeout
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
org_kde_kwin_idle_timeout_add_listener(struct org_kde_kwin_idle_timeout *org_kde_kwin_idle_timeout,
|
||||||
|
const struct org_kde_kwin_idle_timeout_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
return wl_proxy_add_listener((struct wl_proxy *) org_kde_kwin_idle_timeout,
|
||||||
|
(void (**)(void)) listener, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ORG_KDE_KWIN_IDLE_TIMEOUT_RELEASE 0
|
||||||
|
#define ORG_KDE_KWIN_IDLE_TIMEOUT_SIMULATE_USER_ACTIVITY 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_org_kde_kwin_idle_timeout
|
||||||
|
*/
|
||||||
|
#define ORG_KDE_KWIN_IDLE_TIMEOUT_IDLE_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_org_kde_kwin_idle_timeout
|
||||||
|
*/
|
||||||
|
#define ORG_KDE_KWIN_IDLE_TIMEOUT_RESUMED_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_org_kde_kwin_idle_timeout
|
||||||
|
*/
|
||||||
|
#define ORG_KDE_KWIN_IDLE_TIMEOUT_RELEASE_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_org_kde_kwin_idle_timeout
|
||||||
|
*/
|
||||||
|
#define ORG_KDE_KWIN_IDLE_TIMEOUT_SIMULATE_USER_ACTIVITY_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_org_kde_kwin_idle_timeout */
|
||||||
|
static inline void
|
||||||
|
org_kde_kwin_idle_timeout_set_user_data(struct org_kde_kwin_idle_timeout *org_kde_kwin_idle_timeout, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) org_kde_kwin_idle_timeout, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_org_kde_kwin_idle_timeout */
|
||||||
|
static inline void *
|
||||||
|
org_kde_kwin_idle_timeout_get_user_data(struct org_kde_kwin_idle_timeout *org_kde_kwin_idle_timeout)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) org_kde_kwin_idle_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
org_kde_kwin_idle_timeout_get_version(struct org_kde_kwin_idle_timeout *org_kde_kwin_idle_timeout)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) org_kde_kwin_idle_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_org_kde_kwin_idle_timeout */
|
||||||
|
static inline void
|
||||||
|
org_kde_kwin_idle_timeout_destroy(struct org_kde_kwin_idle_timeout *org_kde_kwin_idle_timeout)
|
||||||
|
{
|
||||||
|
wl_proxy_destroy((struct wl_proxy *) org_kde_kwin_idle_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_org_kde_kwin_idle_timeout
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
org_kde_kwin_idle_timeout_release(struct org_kde_kwin_idle_timeout *org_kde_kwin_idle_timeout)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal((struct wl_proxy *) org_kde_kwin_idle_timeout,
|
||||||
|
ORG_KDE_KWIN_IDLE_TIMEOUT_RELEASE);
|
||||||
|
|
||||||
|
wl_proxy_destroy((struct wl_proxy *) org_kde_kwin_idle_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_org_kde_kwin_idle_timeout
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
org_kde_kwin_idle_timeout_simulate_user_activity(struct org_kde_kwin_idle_timeout *org_kde_kwin_idle_timeout)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal((struct wl_proxy *) org_kde_kwin_idle_timeout,
|
||||||
|
ORG_KDE_KWIN_IDLE_TIMEOUT_SIMULATE_USER_ACTIVITY);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
68
src/wayland/protocols/idle.h
Normal file
68
src/wayland/protocols/idle.h
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/* Generated by wayland-scanner 1.18.0 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2015 Martin Gräßlin
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 2.1 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
#ifndef __has_attribute
|
||||||
|
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||||
|
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||||
|
#else
|
||||||
|
#define WL_PRIVATE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const struct wl_interface org_kde_kwin_idle_timeout_interface;
|
||||||
|
extern const struct wl_interface wl_seat_interface;
|
||||||
|
|
||||||
|
static const struct wl_interface *idle_types[] = {
|
||||||
|
&org_kde_kwin_idle_timeout_interface,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message org_kde_kwin_idle_requests[] = {
|
||||||
|
{ "get_idle_timeout", "nou", idle_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface org_kde_kwin_idle_interface = {
|
||||||
|
"org_kde_kwin_idle", 1,
|
||||||
|
1, org_kde_kwin_idle_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message org_kde_kwin_idle_timeout_requests[] = {
|
||||||
|
{ "release", "", idle_types + 0 },
|
||||||
|
{ "simulate_user_activity", "", idle_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message org_kde_kwin_idle_timeout_events[] = {
|
||||||
|
{ "idle", "", idle_types + 0 },
|
||||||
|
{ "resumed", "", idle_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface org_kde_kwin_idle_timeout_interface = {
|
||||||
|
"org_kde_kwin_idle_timeout", 1,
|
||||||
|
2, org_kde_kwin_idle_timeout_requests,
|
||||||
|
2, org_kde_kwin_idle_timeout_events,
|
||||||
|
};
|
||||||
|
|
49
src/wayland/protocols/idle.xml
Normal file
49
src/wayland/protocols/idle.xml
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="idle">
|
||||||
|
<copyright><![CDATA[
|
||||||
|
Copyright (C) 2015 Martin Gräßlin
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation, either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
]]></copyright>
|
||||||
|
<interface name="org_kde_kwin_idle" version="1">
|
||||||
|
<description summary="User idle time manager">
|
||||||
|
This interface allows to monitor user idle time on a given seat. The interface
|
||||||
|
allows to register timers which trigger after no user activity was registered
|
||||||
|
on the seat for a given interval. It notifies when user activity resumes.
|
||||||
|
|
||||||
|
This is useful for applications wanting to perform actions when the user is not
|
||||||
|
interacting with the system, e.g. chat applications setting the user as away, power
|
||||||
|
management features to dim screen, etc..
|
||||||
|
</description>
|
||||||
|
<request name="get_idle_timeout">
|
||||||
|
<arg name="id" type="new_id" interface="org_kde_kwin_idle_timeout"/>
|
||||||
|
<arg name="seat" type="object" interface="wl_seat"/>
|
||||||
|
<arg name="timeout" type="uint" summary="The idle timeout in msec"/>
|
||||||
|
</request>
|
||||||
|
</interface>
|
||||||
|
<interface name="org_kde_kwin_idle_timeout" version="1">
|
||||||
|
<request name="release" type="destructor">
|
||||||
|
<description summary="release the timeout object"/>
|
||||||
|
</request>
|
||||||
|
<request name="simulate_user_activity">
|
||||||
|
<description summary="Simulates user activity for this timeout, behaves just like real user activity on the seat"/>
|
||||||
|
</request>
|
||||||
|
<event name="idle">
|
||||||
|
<description summary="Triggered when there has not been any user activity in the requested idle time interval"/>
|
||||||
|
</event>
|
||||||
|
<event name="resumed">
|
||||||
|
<description summary="Triggered on the first user activity after an idle event"/>
|
||||||
|
</event>
|
||||||
|
</interface>
|
||||||
|
</protocol>
|
@ -0,0 +1,559 @@
|
|||||||
|
/* Generated by wayland-scanner 1.18.0 */
|
||||||
|
|
||||||
|
#ifndef WLR_LAYER_SHELL_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||||
|
#define WLR_LAYER_SHELL_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "wayland-client.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page page_wlr_layer_shell_unstable_v1 The wlr_layer_shell_unstable_v1 protocol
|
||||||
|
* @section page_ifaces_wlr_layer_shell_unstable_v1 Interfaces
|
||||||
|
* - @subpage page_iface_zwlr_layer_shell_v1 - create surfaces that are layers of the desktop
|
||||||
|
* - @subpage page_iface_zwlr_layer_surface_v1 - layer metadata interface
|
||||||
|
* @section page_copyright_wlr_layer_shell_unstable_v1 Copyright
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* Copyright © 2017 Drew DeVault
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this
|
||||||
|
* software and its documentation for any purpose is hereby granted
|
||||||
|
* without fee, provided that the above copyright notice appear in
|
||||||
|
* all copies and that both that copyright notice and this permission
|
||||||
|
* notice appear in supporting documentation, and that the name of
|
||||||
|
* the copyright holders not be used in advertising or publicity
|
||||||
|
* pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no
|
||||||
|
* representations about the suitability of this software for any
|
||||||
|
* purpose. It is provided "as is" without express or implied
|
||||||
|
* warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||||
|
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||||
|
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
* THIS SOFTWARE.
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
struct wl_output;
|
||||||
|
struct wl_surface;
|
||||||
|
struct xdg_popup;
|
||||||
|
struct zwlr_layer_shell_v1;
|
||||||
|
struct zwlr_layer_surface_v1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page page_iface_zwlr_layer_shell_v1 zwlr_layer_shell_v1
|
||||||
|
* @section page_iface_zwlr_layer_shell_v1_desc Description
|
||||||
|
*
|
||||||
|
* Clients can use this interface to assign the surface_layer role to
|
||||||
|
* wl_surfaces. Such surfaces are assigned to a "layer" of the output and
|
||||||
|
* rendered with a defined z-depth respective to each other. They may also be
|
||||||
|
* anchored to the edges and corners of a screen and specify input handling
|
||||||
|
* semantics. This interface should be suitable for the implementation of
|
||||||
|
* many desktop shell components, and a broad number of other applications
|
||||||
|
* that interact with the desktop.
|
||||||
|
* @section page_iface_zwlr_layer_shell_v1_api API
|
||||||
|
* See @ref iface_zwlr_layer_shell_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_zwlr_layer_shell_v1 The zwlr_layer_shell_v1 interface
|
||||||
|
*
|
||||||
|
* Clients can use this interface to assign the surface_layer role to
|
||||||
|
* wl_surfaces. Such surfaces are assigned to a "layer" of the output and
|
||||||
|
* rendered with a defined z-depth respective to each other. They may also be
|
||||||
|
* anchored to the edges and corners of a screen and specify input handling
|
||||||
|
* semantics. This interface should be suitable for the implementation of
|
||||||
|
* many desktop shell components, and a broad number of other applications
|
||||||
|
* that interact with the desktop.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface zwlr_layer_shell_v1_interface;
|
||||||
|
/**
|
||||||
|
* @page page_iface_zwlr_layer_surface_v1 zwlr_layer_surface_v1
|
||||||
|
* @section page_iface_zwlr_layer_surface_v1_desc Description
|
||||||
|
*
|
||||||
|
* An interface that may be implemented by a wl_surface, for surfaces that
|
||||||
|
* are designed to be rendered as a layer of a stacked desktop-like
|
||||||
|
* environment.
|
||||||
|
*
|
||||||
|
* Layer surface state (size, anchor, exclusive zone, margin, interactivity)
|
||||||
|
* is double-buffered, and will be applied at the time wl_surface.commit of
|
||||||
|
* the corresponding wl_surface is called.
|
||||||
|
* @section page_iface_zwlr_layer_surface_v1_api API
|
||||||
|
* See @ref iface_zwlr_layer_surface_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_zwlr_layer_surface_v1 The zwlr_layer_surface_v1 interface
|
||||||
|
*
|
||||||
|
* An interface that may be implemented by a wl_surface, for surfaces that
|
||||||
|
* are designed to be rendered as a layer of a stacked desktop-like
|
||||||
|
* environment.
|
||||||
|
*
|
||||||
|
* Layer surface state (size, anchor, exclusive zone, margin, interactivity)
|
||||||
|
* is double-buffered, and will be applied at the time wl_surface.commit of
|
||||||
|
* the corresponding wl_surface is called.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface zwlr_layer_surface_v1_interface;
|
||||||
|
|
||||||
|
#ifndef ZWLR_LAYER_SHELL_V1_ERROR_ENUM
|
||||||
|
#define ZWLR_LAYER_SHELL_V1_ERROR_ENUM
|
||||||
|
enum zwlr_layer_shell_v1_error {
|
||||||
|
/**
|
||||||
|
* wl_surface has another role
|
||||||
|
*/
|
||||||
|
ZWLR_LAYER_SHELL_V1_ERROR_ROLE = 0,
|
||||||
|
/**
|
||||||
|
* layer value is invalid
|
||||||
|
*/
|
||||||
|
ZWLR_LAYER_SHELL_V1_ERROR_INVALID_LAYER = 1,
|
||||||
|
/**
|
||||||
|
* wl_surface has a buffer attached or committed
|
||||||
|
*/
|
||||||
|
ZWLR_LAYER_SHELL_V1_ERROR_ALREADY_CONSTRUCTED = 2,
|
||||||
|
};
|
||||||
|
#endif /* ZWLR_LAYER_SHELL_V1_ERROR_ENUM */
|
||||||
|
|
||||||
|
#ifndef ZWLR_LAYER_SHELL_V1_LAYER_ENUM
|
||||||
|
#define ZWLR_LAYER_SHELL_V1_LAYER_ENUM
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_shell_v1
|
||||||
|
* available layers for surfaces
|
||||||
|
*
|
||||||
|
* These values indicate which layers a surface can be rendered in. They
|
||||||
|
* are ordered by z depth, bottom-most first. Traditional shell surfaces
|
||||||
|
* will typically be rendered between the bottom and top layers.
|
||||||
|
* Fullscreen shell surfaces are typically rendered at the top layer.
|
||||||
|
* Multiple surfaces can share a single layer, and ordering within a
|
||||||
|
* single layer is undefined.
|
||||||
|
*/
|
||||||
|
enum zwlr_layer_shell_v1_layer {
|
||||||
|
ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND = 0,
|
||||||
|
ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM = 1,
|
||||||
|
ZWLR_LAYER_SHELL_V1_LAYER_TOP = 2,
|
||||||
|
ZWLR_LAYER_SHELL_V1_LAYER_OVERLAY = 3,
|
||||||
|
};
|
||||||
|
#endif /* ZWLR_LAYER_SHELL_V1_LAYER_ENUM */
|
||||||
|
|
||||||
|
#define ZWLR_LAYER_SHELL_V1_GET_LAYER_SURFACE 0
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_shell_v1
|
||||||
|
*/
|
||||||
|
#define ZWLR_LAYER_SHELL_V1_GET_LAYER_SURFACE_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_zwlr_layer_shell_v1 */
|
||||||
|
static inline void
|
||||||
|
zwlr_layer_shell_v1_set_user_data(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zwlr_layer_shell_v1, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zwlr_layer_shell_v1 */
|
||||||
|
static inline void *
|
||||||
|
zwlr_layer_shell_v1_get_user_data(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zwlr_layer_shell_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zwlr_layer_shell_v1_get_version(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zwlr_layer_shell_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zwlr_layer_shell_v1 */
|
||||||
|
static inline void
|
||||||
|
zwlr_layer_shell_v1_destroy(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_destroy((struct wl_proxy *) zwlr_layer_shell_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_shell_v1
|
||||||
|
*
|
||||||
|
* Create a layer surface for an existing surface. This assigns the role of
|
||||||
|
* layer_surface, or raises a protocol error if another role is already
|
||||||
|
* assigned.
|
||||||
|
*
|
||||||
|
* Creating a layer surface from a wl_surface which has a buffer attached
|
||||||
|
* or committed is a client error, and any attempts by a client to attach
|
||||||
|
* or manipulate a buffer prior to the first layer_surface.configure call
|
||||||
|
* must also be treated as errors.
|
||||||
|
*
|
||||||
|
* You may pass NULL for output to allow the compositor to decide which
|
||||||
|
* output to use. Generally this will be the one that the user most
|
||||||
|
* recently interacted with.
|
||||||
|
*
|
||||||
|
* Clients can specify a namespace that defines the purpose of the layer
|
||||||
|
* surface.
|
||||||
|
*/
|
||||||
|
static inline struct zwlr_layer_surface_v1 *
|
||||||
|
zwlr_layer_shell_v1_get_layer_surface(struct zwlr_layer_shell_v1 *zwlr_layer_shell_v1, struct wl_surface *surface, struct wl_output *output, uint32_t layer, const char *namespace)
|
||||||
|
{
|
||||||
|
struct wl_proxy *id;
|
||||||
|
|
||||||
|
id = wl_proxy_marshal_constructor((struct wl_proxy *) zwlr_layer_shell_v1,
|
||||||
|
ZWLR_LAYER_SHELL_V1_GET_LAYER_SURFACE, &zwlr_layer_surface_v1_interface, NULL, surface, output, layer, namespace);
|
||||||
|
|
||||||
|
return (struct zwlr_layer_surface_v1 *) id;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef ZWLR_LAYER_SURFACE_V1_ERROR_ENUM
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_ERROR_ENUM
|
||||||
|
enum zwlr_layer_surface_v1_error {
|
||||||
|
/**
|
||||||
|
* provided surface state is invalid
|
||||||
|
*/
|
||||||
|
ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_SURFACE_STATE = 0,
|
||||||
|
/**
|
||||||
|
* size is invalid
|
||||||
|
*/
|
||||||
|
ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_SIZE = 1,
|
||||||
|
/**
|
||||||
|
* anchor bitfield is invalid
|
||||||
|
*/
|
||||||
|
ZWLR_LAYER_SURFACE_V1_ERROR_INVALID_ANCHOR = 2,
|
||||||
|
};
|
||||||
|
#endif /* ZWLR_LAYER_SURFACE_V1_ERROR_ENUM */
|
||||||
|
|
||||||
|
#ifndef ZWLR_LAYER_SURFACE_V1_ANCHOR_ENUM
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_ANCHOR_ENUM
|
||||||
|
enum zwlr_layer_surface_v1_anchor {
|
||||||
|
/**
|
||||||
|
* the top edge of the anchor rectangle
|
||||||
|
*/
|
||||||
|
ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP = 1,
|
||||||
|
/**
|
||||||
|
* the bottom edge of the anchor rectangle
|
||||||
|
*/
|
||||||
|
ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM = 2,
|
||||||
|
/**
|
||||||
|
* the left edge of the anchor rectangle
|
||||||
|
*/
|
||||||
|
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT = 4,
|
||||||
|
/**
|
||||||
|
* the right edge of the anchor rectangle
|
||||||
|
*/
|
||||||
|
ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT = 8,
|
||||||
|
};
|
||||||
|
#endif /* ZWLR_LAYER_SURFACE_V1_ANCHOR_ENUM */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
* @struct zwlr_layer_surface_v1_listener
|
||||||
|
*/
|
||||||
|
struct zwlr_layer_surface_v1_listener {
|
||||||
|
/**
|
||||||
|
* suggest a surface change
|
||||||
|
*
|
||||||
|
* The configure event asks the client to resize its surface.
|
||||||
|
*
|
||||||
|
* Clients should arrange their surface for the new states, and
|
||||||
|
* then send an ack_configure request with the serial sent in this
|
||||||
|
* configure event at some point before committing the new surface.
|
||||||
|
*
|
||||||
|
* The client is free to dismiss all but the last configure event
|
||||||
|
* it received.
|
||||||
|
*
|
||||||
|
* The width and height arguments specify the size of the window in
|
||||||
|
* surface-local coordinates.
|
||||||
|
*
|
||||||
|
* The size is a hint, in the sense that the client is free to
|
||||||
|
* ignore it if it doesn't resize, pick a smaller size (to satisfy
|
||||||
|
* aspect ratio or resize in steps of NxM pixels). If the client
|
||||||
|
* picks a smaller size and is anchored to two opposite anchors
|
||||||
|
* (e.g. 'top' and 'bottom'), the surface will be centered on this
|
||||||
|
* axis.
|
||||||
|
*
|
||||||
|
* If the width or height arguments are zero, it means the client
|
||||||
|
* should decide its own window dimension.
|
||||||
|
*/
|
||||||
|
void (*configure)(void *data,
|
||||||
|
struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1,
|
||||||
|
uint32_t serial,
|
||||||
|
uint32_t width,
|
||||||
|
uint32_t height);
|
||||||
|
/**
|
||||||
|
* surface should be closed
|
||||||
|
*
|
||||||
|
* The closed event is sent by the compositor when the surface
|
||||||
|
* will no longer be shown. The output may have been destroyed or
|
||||||
|
* the user may have asked for it to be removed. Further changes to
|
||||||
|
* the surface will be ignored. The client should destroy the
|
||||||
|
* resource after receiving this event, and create a new surface if
|
||||||
|
* they so choose.
|
||||||
|
*/
|
||||||
|
void (*closed)(void *data,
|
||||||
|
struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
zwlr_layer_surface_v1_add_listener(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1,
|
||||||
|
const struct zwlr_layer_surface_v1_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
return wl_proxy_add_listener((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||||
|
(void (**)(void)) listener, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_SET_SIZE 0
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_SET_ANCHOR 1
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_SET_EXCLUSIVE_ZONE 2
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_SET_MARGIN 3
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_SET_KEYBOARD_INTERACTIVITY 4
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_GET_POPUP 5
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_ACK_CONFIGURE 6
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_DESTROY 7
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*/
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_CONFIGURE_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*/
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_CLOSED_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*/
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_SET_SIZE_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*/
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_SET_ANCHOR_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*/
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_SET_EXCLUSIVE_ZONE_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*/
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_SET_MARGIN_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*/
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_SET_KEYBOARD_INTERACTIVITY_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*/
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_GET_POPUP_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*/
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_ACK_CONFIGURE_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*/
|
||||||
|
#define ZWLR_LAYER_SURFACE_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_zwlr_layer_surface_v1 */
|
||||||
|
static inline void
|
||||||
|
zwlr_layer_surface_v1_set_user_data(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zwlr_layer_surface_v1, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zwlr_layer_surface_v1 */
|
||||||
|
static inline void *
|
||||||
|
zwlr_layer_surface_v1_get_user_data(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zwlr_layer_surface_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zwlr_layer_surface_v1_get_version(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zwlr_layer_surface_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*
|
||||||
|
* Sets the size of the surface in surface-local coordinates. The
|
||||||
|
* compositor will display the surface centered with respect to its
|
||||||
|
* anchors.
|
||||||
|
*
|
||||||
|
* If you pass 0 for either value, the compositor will assign it and
|
||||||
|
* inform you of the assignment in the configure event. You must set your
|
||||||
|
* anchor to opposite edges in the dimensions you omit; not doing so is a
|
||||||
|
* protocol error. Both values are 0 by default.
|
||||||
|
*
|
||||||
|
* Size is double-buffered, see wl_surface.commit.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwlr_layer_surface_v1_set_size(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t width, uint32_t height)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||||
|
ZWLR_LAYER_SURFACE_V1_SET_SIZE, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*
|
||||||
|
* Requests that the compositor anchor the surface to the specified edges
|
||||||
|
* and corners. If two orthoginal edges are specified (e.g. 'top' and
|
||||||
|
* 'left'), then the anchor point will be the intersection of the edges
|
||||||
|
* (e.g. the top left corner of the output); otherwise the anchor point
|
||||||
|
* will be centered on that edge, or in the center if none is specified.
|
||||||
|
*
|
||||||
|
* Anchor is double-buffered, see wl_surface.commit.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwlr_layer_surface_v1_set_anchor(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t anchor)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||||
|
ZWLR_LAYER_SURFACE_V1_SET_ANCHOR, anchor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*
|
||||||
|
* Requests that the compositor avoids occluding an area of the surface
|
||||||
|
* with other surfaces. The compositor's use of this information is
|
||||||
|
* implementation-dependent - do not assume that this region will not
|
||||||
|
* actually be occluded.
|
||||||
|
*
|
||||||
|
* A positive value is only meaningful if the surface is anchored to an
|
||||||
|
* edge, rather than a corner. The zone is the number of surface-local
|
||||||
|
* coordinates from the edge that are considered exclusive.
|
||||||
|
*
|
||||||
|
* Surfaces that do not wish to have an exclusive zone may instead specify
|
||||||
|
* how they should interact with surfaces that do. If set to zero, the
|
||||||
|
* surface indicates that it would like to be moved to avoid occluding
|
||||||
|
* surfaces with a positive excluzive zone. If set to -1, the surface
|
||||||
|
* indicates that it would not like to be moved to accomodate for other
|
||||||
|
* surfaces, and the compositor should extend it all the way to the edges
|
||||||
|
* it is anchored to.
|
||||||
|
*
|
||||||
|
* For example, a panel might set its exclusive zone to 10, so that
|
||||||
|
* maximized shell surfaces are not shown on top of it. A notification
|
||||||
|
* might set its exclusive zone to 0, so that it is moved to avoid
|
||||||
|
* occluding the panel, but shell surfaces are shown underneath it. A
|
||||||
|
* wallpaper or lock screen might set their exclusive zone to -1, so that
|
||||||
|
* they stretch below or over the panel.
|
||||||
|
*
|
||||||
|
* The default value is 0.
|
||||||
|
*
|
||||||
|
* Exclusive zone is double-buffered, see wl_surface.commit.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwlr_layer_surface_v1_set_exclusive_zone(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, int32_t zone)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||||
|
ZWLR_LAYER_SURFACE_V1_SET_EXCLUSIVE_ZONE, zone);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*
|
||||||
|
* Requests that the surface be placed some distance away from the anchor
|
||||||
|
* point on the output, in surface-local coordinates. Setting this value
|
||||||
|
* for edges you are not anchored to has no effect.
|
||||||
|
*
|
||||||
|
* The exclusive zone includes the margin.
|
||||||
|
*
|
||||||
|
* Margin is double-buffered, see wl_surface.commit.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwlr_layer_surface_v1_set_margin(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, int32_t top, int32_t right, int32_t bottom, int32_t left)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||||
|
ZWLR_LAYER_SURFACE_V1_SET_MARGIN, top, right, bottom, left);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*
|
||||||
|
* Set to 1 to request that the seat send keyboard events to this layer
|
||||||
|
* surface. For layers below the shell surface layer, the seat will use
|
||||||
|
* normal focus semantics. For layers above the shell surface layers, the
|
||||||
|
* seat will always give exclusive keyboard focus to the top-most layer
|
||||||
|
* which has keyboard interactivity set to true.
|
||||||
|
*
|
||||||
|
* Layer surfaces receive pointer, touch, and tablet events normally. If
|
||||||
|
* you do not want to receive them, set the input region on your surface
|
||||||
|
* to an empty region.
|
||||||
|
*
|
||||||
|
* Events is double-buffered, see wl_surface.commit.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwlr_layer_surface_v1_set_keyboard_interactivity(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t keyboard_interactivity)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||||
|
ZWLR_LAYER_SURFACE_V1_SET_KEYBOARD_INTERACTIVITY, keyboard_interactivity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*
|
||||||
|
* This assigns an xdg_popup's parent to this layer_surface. This popup
|
||||||
|
* should have been created via xdg_surface::get_popup with the parent set
|
||||||
|
* to NULL, and this request must be invoked before committing the popup's
|
||||||
|
* initial state.
|
||||||
|
*
|
||||||
|
* See the documentation of xdg_popup for more details about what an
|
||||||
|
* xdg_popup is and how it is used.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwlr_layer_surface_v1_get_popup(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, struct xdg_popup *popup)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||||
|
ZWLR_LAYER_SURFACE_V1_GET_POPUP, popup);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*
|
||||||
|
* When a configure event is received, if a client commits the
|
||||||
|
* surface in response to the configure event, then the client
|
||||||
|
* must make an ack_configure request sometime before the commit
|
||||||
|
* request, passing along the serial of the configure event.
|
||||||
|
*
|
||||||
|
* If the client receives multiple configure events before it
|
||||||
|
* can respond to one, it only has to ack the last configure event.
|
||||||
|
*
|
||||||
|
* A client is not required to commit immediately after sending
|
||||||
|
* an ack_configure request - it may even ack_configure several times
|
||||||
|
* before its next surface commit.
|
||||||
|
*
|
||||||
|
* A client may send multiple ack_configure requests before committing, but
|
||||||
|
* only the last request sent before a commit indicates which configure
|
||||||
|
* event the client really is responding to.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwlr_layer_surface_v1_ack_configure(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1, uint32_t serial)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||||
|
ZWLR_LAYER_SURFACE_V1_ACK_CONFIGURE, serial);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zwlr_layer_surface_v1
|
||||||
|
*
|
||||||
|
* This request destroys the layer surface.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zwlr_layer_surface_v1_destroy(struct zwlr_layer_surface_v1 *zwlr_layer_surface_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal((struct wl_proxy *) zwlr_layer_surface_v1,
|
||||||
|
ZWLR_LAYER_SURFACE_V1_DESTROY);
|
||||||
|
|
||||||
|
wl_proxy_destroy((struct wl_proxy *) zwlr_layer_surface_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
91
src/wayland/protocols/wlr-layer-shell-unstable-v1.h
Normal file
91
src/wayland/protocols/wlr-layer-shell-unstable-v1.h
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
/* Generated by wayland-scanner 1.18.0 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2017 Drew DeVault
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, distribute, and sell this
|
||||||
|
* software and its documentation for any purpose is hereby granted
|
||||||
|
* without fee, provided that the above copyright notice appear in
|
||||||
|
* all copies and that both that copyright notice and this permission
|
||||||
|
* notice appear in supporting documentation, and that the name of
|
||||||
|
* the copyright holders not be used in advertising or publicity
|
||||||
|
* pertaining to distribution of the software without specific,
|
||||||
|
* written prior permission. The copyright holders make no
|
||||||
|
* representations about the suitability of this software for any
|
||||||
|
* purpose. It is provided "as is" without express or implied
|
||||||
|
* warranty.
|
||||||
|
*
|
||||||
|
* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||||
|
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||||
|
* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||||
|
* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
* THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
#ifndef __has_attribute
|
||||||
|
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||||
|
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||||
|
#else
|
||||||
|
#define WL_PRIVATE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const struct wl_interface wl_output_interface;
|
||||||
|
extern const struct wl_interface wl_surface_interface;
|
||||||
|
extern const struct wl_interface xdg_popup_interface;
|
||||||
|
extern const struct wl_interface zwlr_layer_surface_v1_interface;
|
||||||
|
|
||||||
|
static const struct wl_interface *wlr_layer_shell_unstable_v1_types[] = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&zwlr_layer_surface_v1_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&wl_output_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&xdg_popup_interface,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zwlr_layer_shell_v1_requests[] = {
|
||||||
|
{ "get_layer_surface", "no?ous", wlr_layer_shell_unstable_v1_types + 4 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface zwlr_layer_shell_v1_interface = {
|
||||||
|
"zwlr_layer_shell_v1", 1,
|
||||||
|
1, zwlr_layer_shell_v1_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zwlr_layer_surface_v1_requests[] = {
|
||||||
|
{ "set_size", "uu", wlr_layer_shell_unstable_v1_types + 0 },
|
||||||
|
{ "set_anchor", "u", wlr_layer_shell_unstable_v1_types + 0 },
|
||||||
|
{ "set_exclusive_zone", "i", wlr_layer_shell_unstable_v1_types + 0 },
|
||||||
|
{ "set_margin", "iiii", wlr_layer_shell_unstable_v1_types + 0 },
|
||||||
|
{ "set_keyboard_interactivity", "u", wlr_layer_shell_unstable_v1_types + 0 },
|
||||||
|
{ "get_popup", "o", wlr_layer_shell_unstable_v1_types + 9 },
|
||||||
|
{ "ack_configure", "u", wlr_layer_shell_unstable_v1_types + 0 },
|
||||||
|
{ "destroy", "", wlr_layer_shell_unstable_v1_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zwlr_layer_surface_v1_events[] = {
|
||||||
|
{ "configure", "uuu", wlr_layer_shell_unstable_v1_types + 0 },
|
||||||
|
{ "closed", "", wlr_layer_shell_unstable_v1_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface zwlr_layer_surface_v1_interface = {
|
||||||
|
"zwlr_layer_surface_v1", 1,
|
||||||
|
8, zwlr_layer_surface_v1_requests,
|
||||||
|
2, zwlr_layer_surface_v1_events,
|
||||||
|
};
|
||||||
|
|
285
src/wayland/protocols/wlr-layer-shell-unstable-v1.xml
Normal file
285
src/wayland/protocols/wlr-layer-shell-unstable-v1.xml
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<protocol name="wlr_layer_shell_unstable_v1">
|
||||||
|
<copyright>
|
||||||
|
Copyright © 2017 Drew DeVault
|
||||||
|
|
||||||
|
Permission to use, copy, modify, distribute, and sell this
|
||||||
|
software and its documentation for any purpose is hereby granted
|
||||||
|
without fee, provided that the above copyright notice appear in
|
||||||
|
all copies and that both that copyright notice and this permission
|
||||||
|
notice appear in supporting documentation, and that the name of
|
||||||
|
the copyright holders not be used in advertising or publicity
|
||||||
|
pertaining to distribution of the software without specific,
|
||||||
|
written prior permission. The copyright holders make no
|
||||||
|
representations about the suitability of this software for any
|
||||||
|
purpose. It is provided "as is" without express or implied
|
||||||
|
warranty.
|
||||||
|
|
||||||
|
THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
|
||||||
|
SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
|
FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
||||||
|
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||||
|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
THIS SOFTWARE.
|
||||||
|
</copyright>
|
||||||
|
|
||||||
|
<interface name="zwlr_layer_shell_v1" version="1">
|
||||||
|
<description summary="create surfaces that are layers of the desktop">
|
||||||
|
Clients can use this interface to assign the surface_layer role to
|
||||||
|
wl_surfaces. Such surfaces are assigned to a "layer" of the output and
|
||||||
|
rendered with a defined z-depth respective to each other. They may also be
|
||||||
|
anchored to the edges and corners of a screen and specify input handling
|
||||||
|
semantics. This interface should be suitable for the implementation of
|
||||||
|
many desktop shell components, and a broad number of other applications
|
||||||
|
that interact with the desktop.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="get_layer_surface">
|
||||||
|
<description summary="create a layer_surface from a surface">
|
||||||
|
Create a layer surface for an existing surface. This assigns the role of
|
||||||
|
layer_surface, or raises a protocol error if another role is already
|
||||||
|
assigned.
|
||||||
|
|
||||||
|
Creating a layer surface from a wl_surface which has a buffer attached
|
||||||
|
or committed is a client error, and any attempts by a client to attach
|
||||||
|
or manipulate a buffer prior to the first layer_surface.configure call
|
||||||
|
must also be treated as errors.
|
||||||
|
|
||||||
|
You may pass NULL for output to allow the compositor to decide which
|
||||||
|
output to use. Generally this will be the one that the user most
|
||||||
|
recently interacted with.
|
||||||
|
|
||||||
|
Clients can specify a namespace that defines the purpose of the layer
|
||||||
|
surface.
|
||||||
|
</description>
|
||||||
|
<arg name="id" type="new_id" interface="zwlr_layer_surface_v1"/>
|
||||||
|
<arg name="surface" type="object" interface="wl_surface"/>
|
||||||
|
<arg name="output" type="object" interface="wl_output" allow-null="true"/>
|
||||||
|
<arg name="layer" type="uint" enum="layer" summary="layer to add this surface to"/>
|
||||||
|
<arg name="namespace" type="string" summary="namespace for the layer surface"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<enum name="error">
|
||||||
|
<entry name="role" value="0" summary="wl_surface has another role"/>
|
||||||
|
<entry name="invalid_layer" value="1" summary="layer value is invalid"/>
|
||||||
|
<entry name="already_constructed" value="2" summary="wl_surface has a buffer attached or committed"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<enum name="layer">
|
||||||
|
<description summary="available layers for surfaces">
|
||||||
|
These values indicate which layers a surface can be rendered in. They
|
||||||
|
are ordered by z depth, bottom-most first. Traditional shell surfaces
|
||||||
|
will typically be rendered between the bottom and top layers.
|
||||||
|
Fullscreen shell surfaces are typically rendered at the top layer.
|
||||||
|
Multiple surfaces can share a single layer, and ordering within a
|
||||||
|
single layer is undefined.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<entry name="background" value="0"/>
|
||||||
|
<entry name="bottom" value="1"/>
|
||||||
|
<entry name="top" value="2"/>
|
||||||
|
<entry name="overlay" value="3"/>
|
||||||
|
</enum>
|
||||||
|
</interface>
|
||||||
|
|
||||||
|
<interface name="zwlr_layer_surface_v1" version="1">
|
||||||
|
<description summary="layer metadata interface">
|
||||||
|
An interface that may be implemented by a wl_surface, for surfaces that
|
||||||
|
are designed to be rendered as a layer of a stacked desktop-like
|
||||||
|
environment.
|
||||||
|
|
||||||
|
Layer surface state (size, anchor, exclusive zone, margin, interactivity)
|
||||||
|
is double-buffered, and will be applied at the time wl_surface.commit of
|
||||||
|
the corresponding wl_surface is called.
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<request name="set_size">
|
||||||
|
<description summary="sets the size of the surface">
|
||||||
|
Sets the size of the surface in surface-local coordinates. The
|
||||||
|
compositor will display the surface centered with respect to its
|
||||||
|
anchors.
|
||||||
|
|
||||||
|
If you pass 0 for either value, the compositor will assign it and
|
||||||
|
inform you of the assignment in the configure event. You must set your
|
||||||
|
anchor to opposite edges in the dimensions you omit; not doing so is a
|
||||||
|
protocol error. Both values are 0 by default.
|
||||||
|
|
||||||
|
Size is double-buffered, see wl_surface.commit.
|
||||||
|
</description>
|
||||||
|
<arg name="width" type="uint"/>
|
||||||
|
<arg name="height" type="uint"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_anchor">
|
||||||
|
<description summary="configures the anchor point of the surface">
|
||||||
|
Requests that the compositor anchor the surface to the specified edges
|
||||||
|
and corners. If two orthoginal edges are specified (e.g. 'top' and
|
||||||
|
'left'), then the anchor point will be the intersection of the edges
|
||||||
|
(e.g. the top left corner of the output); otherwise the anchor point
|
||||||
|
will be centered on that edge, or in the center if none is specified.
|
||||||
|
|
||||||
|
Anchor is double-buffered, see wl_surface.commit.
|
||||||
|
</description>
|
||||||
|
<arg name="anchor" type="uint" enum="anchor"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_exclusive_zone">
|
||||||
|
<description summary="configures the exclusive geometry of this surface">
|
||||||
|
Requests that the compositor avoids occluding an area of the surface
|
||||||
|
with other surfaces. The compositor's use of this information is
|
||||||
|
implementation-dependent - do not assume that this region will not
|
||||||
|
actually be occluded.
|
||||||
|
|
||||||
|
A positive value is only meaningful if the surface is anchored to an
|
||||||
|
edge, rather than a corner. The zone is the number of surface-local
|
||||||
|
coordinates from the edge that are considered exclusive.
|
||||||
|
|
||||||
|
Surfaces that do not wish to have an exclusive zone may instead specify
|
||||||
|
how they should interact with surfaces that do. If set to zero, the
|
||||||
|
surface indicates that it would like to be moved to avoid occluding
|
||||||
|
surfaces with a positive excluzive zone. If set to -1, the surface
|
||||||
|
indicates that it would not like to be moved to accomodate for other
|
||||||
|
surfaces, and the compositor should extend it all the way to the edges
|
||||||
|
it is anchored to.
|
||||||
|
|
||||||
|
For example, a panel might set its exclusive zone to 10, so that
|
||||||
|
maximized shell surfaces are not shown on top of it. A notification
|
||||||
|
might set its exclusive zone to 0, so that it is moved to avoid
|
||||||
|
occluding the panel, but shell surfaces are shown underneath it. A
|
||||||
|
wallpaper or lock screen might set their exclusive zone to -1, so that
|
||||||
|
they stretch below or over the panel.
|
||||||
|
|
||||||
|
The default value is 0.
|
||||||
|
|
||||||
|
Exclusive zone is double-buffered, see wl_surface.commit.
|
||||||
|
</description>
|
||||||
|
<arg name="zone" type="int"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_margin">
|
||||||
|
<description summary="sets a margin from the anchor point">
|
||||||
|
Requests that the surface be placed some distance away from the anchor
|
||||||
|
point on the output, in surface-local coordinates. Setting this value
|
||||||
|
for edges you are not anchored to has no effect.
|
||||||
|
|
||||||
|
The exclusive zone includes the margin.
|
||||||
|
|
||||||
|
Margin is double-buffered, see wl_surface.commit.
|
||||||
|
</description>
|
||||||
|
<arg name="top" type="int"/>
|
||||||
|
<arg name="right" type="int"/>
|
||||||
|
<arg name="bottom" type="int"/>
|
||||||
|
<arg name="left" type="int"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="set_keyboard_interactivity">
|
||||||
|
<description summary="requests keyboard events">
|
||||||
|
Set to 1 to request that the seat send keyboard events to this layer
|
||||||
|
surface. For layers below the shell surface layer, the seat will use
|
||||||
|
normal focus semantics. For layers above the shell surface layers, the
|
||||||
|
seat will always give exclusive keyboard focus to the top-most layer
|
||||||
|
which has keyboard interactivity set to true.
|
||||||
|
|
||||||
|
Layer surfaces receive pointer, touch, and tablet events normally. If
|
||||||
|
you do not want to receive them, set the input region on your surface
|
||||||
|
to an empty region.
|
||||||
|
|
||||||
|
Events is double-buffered, see wl_surface.commit.
|
||||||
|
</description>
|
||||||
|
<arg name="keyboard_interactivity" type="uint"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="get_popup">
|
||||||
|
<description summary="assign this layer_surface as an xdg_popup parent">
|
||||||
|
This assigns an xdg_popup's parent to this layer_surface. This popup
|
||||||
|
should have been created via xdg_surface::get_popup with the parent set
|
||||||
|
to NULL, and this request must be invoked before committing the popup's
|
||||||
|
initial state.
|
||||||
|
|
||||||
|
See the documentation of xdg_popup for more details about what an
|
||||||
|
xdg_popup is and how it is used.
|
||||||
|
</description>
|
||||||
|
<arg name="popup" type="object" interface="xdg_popup"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="ack_configure">
|
||||||
|
<description summary="ack a configure event">
|
||||||
|
When a configure event is received, if a client commits the
|
||||||
|
surface in response to the configure event, then the client
|
||||||
|
must make an ack_configure request sometime before the commit
|
||||||
|
request, passing along the serial of the configure event.
|
||||||
|
|
||||||
|
If the client receives multiple configure events before it
|
||||||
|
can respond to one, it only has to ack the last configure event.
|
||||||
|
|
||||||
|
A client is not required to commit immediately after sending
|
||||||
|
an ack_configure request - it may even ack_configure several times
|
||||||
|
before its next surface commit.
|
||||||
|
|
||||||
|
A client may send multiple ack_configure requests before committing, but
|
||||||
|
only the last request sent before a commit indicates which configure
|
||||||
|
event the client really is responding to.
|
||||||
|
</description>
|
||||||
|
<arg name="serial" type="uint" summary="the serial from the configure event"/>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<request name="destroy" type="destructor">
|
||||||
|
<description summary="destroy the layer_surface">
|
||||||
|
This request destroys the layer surface.
|
||||||
|
</description>
|
||||||
|
</request>
|
||||||
|
|
||||||
|
<event name="configure">
|
||||||
|
<description summary="suggest a surface change">
|
||||||
|
The configure event asks the client to resize its surface.
|
||||||
|
|
||||||
|
Clients should arrange their surface for the new states, and then send
|
||||||
|
an ack_configure request with the serial sent in this configure event at
|
||||||
|
some point before committing the new surface.
|
||||||
|
|
||||||
|
The client is free to dismiss all but the last configure event it
|
||||||
|
received.
|
||||||
|
|
||||||
|
The width and height arguments specify the size of the window in
|
||||||
|
surface-local coordinates.
|
||||||
|
|
||||||
|
The size is a hint, in the sense that the client is free to ignore it if
|
||||||
|
it doesn't resize, pick a smaller size (to satisfy aspect ratio or
|
||||||
|
resize in steps of NxM pixels). If the client picks a smaller size and
|
||||||
|
is anchored to two opposite anchors (e.g. 'top' and 'bottom'), the
|
||||||
|
surface will be centered on this axis.
|
||||||
|
|
||||||
|
If the width or height arguments are zero, it means the client should
|
||||||
|
decide its own window dimension.
|
||||||
|
</description>
|
||||||
|
<arg name="serial" type="uint"/>
|
||||||
|
<arg name="width" type="uint"/>
|
||||||
|
<arg name="height" type="uint"/>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<event name="closed">
|
||||||
|
<description summary="surface should be closed">
|
||||||
|
The closed event is sent by the compositor when the surface will no
|
||||||
|
longer be shown. The output may have been destroyed or the user may
|
||||||
|
have asked for it to be removed. Further changes to the surface will be
|
||||||
|
ignored. The client should destroy the resource after receiving this
|
||||||
|
event, and create a new surface if they so choose.
|
||||||
|
</description>
|
||||||
|
</event>
|
||||||
|
|
||||||
|
<enum name="error">
|
||||||
|
<entry name="invalid_surface_state" value="0" summary="provided surface state is invalid"/>
|
||||||
|
<entry name="invalid_size" value="1" summary="size is invalid"/>
|
||||||
|
<entry name="invalid_anchor" value="2" summary="anchor bitfield is invalid"/>
|
||||||
|
</enum>
|
||||||
|
|
||||||
|
<enum name="anchor" bitfield="true">
|
||||||
|
<entry name="top" value="1" summary="the top edge of the anchor rectangle"/>
|
||||||
|
<entry name="bottom" value="2" summary="the bottom edge of the anchor rectangle"/>
|
||||||
|
<entry name="left" value="4" summary="the left edge of the anchor rectangle"/>
|
||||||
|
<entry name="right" value="8" summary="the right edge of the anchor rectangle"/>
|
||||||
|
</enum>
|
||||||
|
</interface>
|
||||||
|
</protocol>
|
409
src/wayland/protocols/xdg-output-unstable-v1-client-header.h
Normal file
409
src/wayland/protocols/xdg-output-unstable-v1-client-header.h
Normal file
@ -0,0 +1,409 @@
|
|||||||
|
/* Generated by wayland-scanner 1.18.0 */
|
||||||
|
|
||||||
|
#ifndef XDG_OUTPUT_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||||
|
#define XDG_OUTPUT_UNSTABLE_V1_CLIENT_PROTOCOL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "wayland-client.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page page_xdg_output_unstable_v1 The xdg_output_unstable_v1 protocol
|
||||||
|
* Protocol to describe output regions
|
||||||
|
*
|
||||||
|
* @section page_desc_xdg_output_unstable_v1 Description
|
||||||
|
*
|
||||||
|
* This protocol aims at describing outputs in a way which is more in line
|
||||||
|
* with the concept of an output on desktop oriented systems.
|
||||||
|
*
|
||||||
|
* Some information are more specific to the concept of an output for
|
||||||
|
* a desktop oriented system and may not make sense in other applications,
|
||||||
|
* such as IVI systems for example.
|
||||||
|
*
|
||||||
|
* Typically, the global compositor space on a desktop system is made of
|
||||||
|
* a contiguous or overlapping set of rectangular regions.
|
||||||
|
*
|
||||||
|
* Some of the information provided in this protocol might be identical
|
||||||
|
* to their counterparts already available from wl_output, in which case
|
||||||
|
* the information provided by this protocol should be preferred to their
|
||||||
|
* equivalent in wl_output. The goal is to move the desktop specific
|
||||||
|
* concepts (such as output location within the global compositor space,
|
||||||
|
* the connector name and types, etc.) out of the core wl_output protocol.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @section page_ifaces_xdg_output_unstable_v1 Interfaces
|
||||||
|
* - @subpage page_iface_zxdg_output_manager_v1 - manage xdg_output objects
|
||||||
|
* - @subpage page_iface_zxdg_output_v1 - compositor logical output region
|
||||||
|
* @section page_copyright_xdg_output_unstable_v1 Copyright
|
||||||
|
* <pre>
|
||||||
|
*
|
||||||
|
* Copyright © 2017 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* 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 (including the next
|
||||||
|
* paragraph) 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.
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
struct wl_output;
|
||||||
|
struct zxdg_output_manager_v1;
|
||||||
|
struct zxdg_output_v1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page page_iface_zxdg_output_manager_v1 zxdg_output_manager_v1
|
||||||
|
* @section page_iface_zxdg_output_manager_v1_desc Description
|
||||||
|
*
|
||||||
|
* A global factory interface for xdg_output objects.
|
||||||
|
* @section page_iface_zxdg_output_manager_v1_api API
|
||||||
|
* See @ref iface_zxdg_output_manager_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_zxdg_output_manager_v1 The zxdg_output_manager_v1 interface
|
||||||
|
*
|
||||||
|
* A global factory interface for xdg_output objects.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface zxdg_output_manager_v1_interface;
|
||||||
|
/**
|
||||||
|
* @page page_iface_zxdg_output_v1 zxdg_output_v1
|
||||||
|
* @section page_iface_zxdg_output_v1_desc Description
|
||||||
|
*
|
||||||
|
* An xdg_output describes part of the compositor geometry.
|
||||||
|
*
|
||||||
|
* This typically corresponds to a monitor that displays part of the
|
||||||
|
* compositor space.
|
||||||
|
*
|
||||||
|
* For objects version 3 onwards, after all xdg_output properties have been
|
||||||
|
* sent (when the object is created and when properties are updated), a
|
||||||
|
* wl_output.done event is sent. This allows changes to the output
|
||||||
|
* properties to be seen as atomic, even if they happen via multiple events.
|
||||||
|
* @section page_iface_zxdg_output_v1_api API
|
||||||
|
* See @ref iface_zxdg_output_v1.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @defgroup iface_zxdg_output_v1 The zxdg_output_v1 interface
|
||||||
|
*
|
||||||
|
* An xdg_output describes part of the compositor geometry.
|
||||||
|
*
|
||||||
|
* This typically corresponds to a monitor that displays part of the
|
||||||
|
* compositor space.
|
||||||
|
*
|
||||||
|
* For objects version 3 onwards, after all xdg_output properties have been
|
||||||
|
* sent (when the object is created and when properties are updated), a
|
||||||
|
* wl_output.done event is sent. This allows changes to the output
|
||||||
|
* properties to be seen as atomic, even if they happen via multiple events.
|
||||||
|
*/
|
||||||
|
extern const struct wl_interface zxdg_output_v1_interface;
|
||||||
|
|
||||||
|
#define ZXDG_OUTPUT_MANAGER_V1_DESTROY 0
|
||||||
|
#define ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT 1
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_output_manager_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_OUTPUT_MANAGER_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_output_manager_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_zxdg_output_manager_v1 */
|
||||||
|
static inline void
|
||||||
|
zxdg_output_manager_v1_set_user_data(struct zxdg_output_manager_v1 *zxdg_output_manager_v1, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zxdg_output_manager_v1, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zxdg_output_manager_v1 */
|
||||||
|
static inline void *
|
||||||
|
zxdg_output_manager_v1_get_user_data(struct zxdg_output_manager_v1 *zxdg_output_manager_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zxdg_output_manager_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zxdg_output_manager_v1_get_version(struct zxdg_output_manager_v1 *zxdg_output_manager_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zxdg_output_manager_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_output_manager_v1
|
||||||
|
*
|
||||||
|
* Using this request a client can tell the server that it is not
|
||||||
|
* going to use the xdg_output_manager object anymore.
|
||||||
|
*
|
||||||
|
* Any objects already created through this instance are not affected.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zxdg_output_manager_v1_destroy(struct zxdg_output_manager_v1 *zxdg_output_manager_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal((struct wl_proxy *) zxdg_output_manager_v1,
|
||||||
|
ZXDG_OUTPUT_MANAGER_V1_DESTROY);
|
||||||
|
|
||||||
|
wl_proxy_destroy((struct wl_proxy *) zxdg_output_manager_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_output_manager_v1
|
||||||
|
*
|
||||||
|
* This creates a new xdg_output object for the given wl_output.
|
||||||
|
*/
|
||||||
|
static inline struct zxdg_output_v1 *
|
||||||
|
zxdg_output_manager_v1_get_xdg_output(struct zxdg_output_manager_v1 *zxdg_output_manager_v1, struct wl_output *output)
|
||||||
|
{
|
||||||
|
struct wl_proxy *id;
|
||||||
|
|
||||||
|
id = wl_proxy_marshal_constructor((struct wl_proxy *) zxdg_output_manager_v1,
|
||||||
|
ZXDG_OUTPUT_MANAGER_V1_GET_XDG_OUTPUT, &zxdg_output_v1_interface, NULL, output);
|
||||||
|
|
||||||
|
return (struct zxdg_output_v1 *) id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_output_v1
|
||||||
|
* @struct zxdg_output_v1_listener
|
||||||
|
*/
|
||||||
|
struct zxdg_output_v1_listener {
|
||||||
|
/**
|
||||||
|
* position of the output within the global compositor space
|
||||||
|
*
|
||||||
|
* The position event describes the location of the wl_output
|
||||||
|
* within the global compositor space.
|
||||||
|
*
|
||||||
|
* The logical_position event is sent after creating an xdg_output
|
||||||
|
* (see xdg_output_manager.get_xdg_output) and whenever the
|
||||||
|
* location of the output changes within the global compositor
|
||||||
|
* space.
|
||||||
|
* @param x x position within the global compositor space
|
||||||
|
* @param y y position within the global compositor space
|
||||||
|
*/
|
||||||
|
void (*logical_position)(void *data,
|
||||||
|
struct zxdg_output_v1 *zxdg_output_v1,
|
||||||
|
int32_t x,
|
||||||
|
int32_t y);
|
||||||
|
/**
|
||||||
|
* size of the output in the global compositor space
|
||||||
|
*
|
||||||
|
* The logical_size event describes the size of the output in the
|
||||||
|
* global compositor space.
|
||||||
|
*
|
||||||
|
* For example, a surface without any buffer scale, transformation
|
||||||
|
* nor rotation set, with the size matching the logical_size will
|
||||||
|
* have the same size as the corresponding output when displayed.
|
||||||
|
*
|
||||||
|
* Most regular Wayland clients should not pay attention to the
|
||||||
|
* logical size and would rather rely on xdg_shell interfaces.
|
||||||
|
*
|
||||||
|
* Some clients such as Xwayland, however, need this to configure
|
||||||
|
* their surfaces in the global compositor space as the compositor
|
||||||
|
* may apply a different scale from what is advertised by the
|
||||||
|
* output scaling property (to achieve fractional scaling, for
|
||||||
|
* example).
|
||||||
|
*
|
||||||
|
* For example, for a wl_output mode 3840×2160 and a scale factor
|
||||||
|
* 2:
|
||||||
|
*
|
||||||
|
* - A compositor not scaling the surface buffers will advertise a
|
||||||
|
* logical size of 3840×2160,
|
||||||
|
*
|
||||||
|
* - A compositor automatically scaling the surface buffers will
|
||||||
|
* advertise a logical size of 1920×1080,
|
||||||
|
*
|
||||||
|
* - A compositor using a fractional scale of 1.5 will advertise a
|
||||||
|
* logical size to 2560×1620.
|
||||||
|
*
|
||||||
|
* For example, for a wl_output mode 1920×1080 and a 90 degree
|
||||||
|
* rotation, the compositor will advertise a logical size of
|
||||||
|
* 1080x1920.
|
||||||
|
*
|
||||||
|
* The logical_size event is sent after creating an xdg_output (see
|
||||||
|
* xdg_output_manager.get_xdg_output) and whenever the logical size
|
||||||
|
* of the output changes, either as a result of a change in the
|
||||||
|
* applied scale or because of a change in the corresponding output
|
||||||
|
* mode(see wl_output.mode) or transform (see wl_output.transform).
|
||||||
|
* @param width width in global compositor space
|
||||||
|
* @param height height in global compositor space
|
||||||
|
*/
|
||||||
|
void (*logical_size)(void *data,
|
||||||
|
struct zxdg_output_v1 *zxdg_output_v1,
|
||||||
|
int32_t width,
|
||||||
|
int32_t height);
|
||||||
|
/**
|
||||||
|
* all information about the output have been sent
|
||||||
|
*
|
||||||
|
* This event is sent after all other properties of an xdg_output
|
||||||
|
* have been sent.
|
||||||
|
*
|
||||||
|
* This allows changes to the xdg_output properties to be seen as
|
||||||
|
* atomic, even if they happen via multiple events.
|
||||||
|
*
|
||||||
|
* For objects version 3 onwards, this event is deprecated.
|
||||||
|
* Compositors are not required to send it anymore and must send
|
||||||
|
* wl_output.done instead.
|
||||||
|
*/
|
||||||
|
void (*done)(void *data,
|
||||||
|
struct zxdg_output_v1 *zxdg_output_v1);
|
||||||
|
/**
|
||||||
|
* name of this output
|
||||||
|
*
|
||||||
|
* Many compositors will assign names to their outputs, show them
|
||||||
|
* to the user, allow them to be configured by name, etc. The
|
||||||
|
* client may wish to know this name as well to offer the user
|
||||||
|
* similar behaviors.
|
||||||
|
*
|
||||||
|
* The naming convention is compositor defined, but limited to
|
||||||
|
* alphanumeric characters and dashes (-). Each name is unique
|
||||||
|
* among all wl_output globals, but if a wl_output global is
|
||||||
|
* destroyed the same name may be reused later. The names will also
|
||||||
|
* remain consistent across sessions with the same hardware and
|
||||||
|
* software configuration.
|
||||||
|
*
|
||||||
|
* Examples of names include 'HDMI-A-1', 'WL-1', 'X11-1', etc.
|
||||||
|
* However, do not assume that the name is a reflection of an
|
||||||
|
* underlying DRM connector, X11 connection, etc.
|
||||||
|
*
|
||||||
|
* The name event is sent after creating an xdg_output (see
|
||||||
|
* xdg_output_manager.get_xdg_output). This event is only sent once
|
||||||
|
* per xdg_output, and the name does not change over the lifetime
|
||||||
|
* of the wl_output global.
|
||||||
|
* @param name output name
|
||||||
|
* @since 2
|
||||||
|
*/
|
||||||
|
void (*name)(void *data,
|
||||||
|
struct zxdg_output_v1 *zxdg_output_v1,
|
||||||
|
const char *name);
|
||||||
|
/**
|
||||||
|
* human-readable description of this output
|
||||||
|
*
|
||||||
|
* Many compositors can produce human-readable descriptions of
|
||||||
|
* their outputs. The client may wish to know this description as
|
||||||
|
* well, to communicate the user for various purposes.
|
||||||
|
*
|
||||||
|
* The description is a UTF-8 string with no convention defined for
|
||||||
|
* its contents. Examples might include 'Foocorp 11" Display' or
|
||||||
|
* 'Virtual X11 output via :1'.
|
||||||
|
*
|
||||||
|
* The description event is sent after creating an xdg_output (see
|
||||||
|
* xdg_output_manager.get_xdg_output) and whenever the description
|
||||||
|
* changes. The description is optional, and may not be sent at
|
||||||
|
* all.
|
||||||
|
*
|
||||||
|
* For objects of version 2 and lower, this event is only sent once
|
||||||
|
* per xdg_output, and the description does not change over the
|
||||||
|
* lifetime of the wl_output global.
|
||||||
|
* @param description output description
|
||||||
|
* @since 2
|
||||||
|
*/
|
||||||
|
void (*description)(void *data,
|
||||||
|
struct zxdg_output_v1 *zxdg_output_v1,
|
||||||
|
const char *description);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_output_v1
|
||||||
|
*/
|
||||||
|
static inline int
|
||||||
|
zxdg_output_v1_add_listener(struct zxdg_output_v1 *zxdg_output_v1,
|
||||||
|
const struct zxdg_output_v1_listener *listener, void *data)
|
||||||
|
{
|
||||||
|
return wl_proxy_add_listener((struct wl_proxy *) zxdg_output_v1,
|
||||||
|
(void (**)(void)) listener, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ZXDG_OUTPUT_V1_DESTROY 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_output_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_OUTPUT_V1_LOGICAL_POSITION_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_output_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_OUTPUT_V1_LOGICAL_SIZE_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_output_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_OUTPUT_V1_DONE_SINCE_VERSION 1
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_output_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_OUTPUT_V1_NAME_SINCE_VERSION 2
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_output_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_OUTPUT_V1_DESCRIPTION_SINCE_VERSION 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_output_v1
|
||||||
|
*/
|
||||||
|
#define ZXDG_OUTPUT_V1_DESTROY_SINCE_VERSION 1
|
||||||
|
|
||||||
|
/** @ingroup iface_zxdg_output_v1 */
|
||||||
|
static inline void
|
||||||
|
zxdg_output_v1_set_user_data(struct zxdg_output_v1 *zxdg_output_v1, void *user_data)
|
||||||
|
{
|
||||||
|
wl_proxy_set_user_data((struct wl_proxy *) zxdg_output_v1, user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup iface_zxdg_output_v1 */
|
||||||
|
static inline void *
|
||||||
|
zxdg_output_v1_get_user_data(struct zxdg_output_v1 *zxdg_output_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_user_data((struct wl_proxy *) zxdg_output_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline uint32_t
|
||||||
|
zxdg_output_v1_get_version(struct zxdg_output_v1 *zxdg_output_v1)
|
||||||
|
{
|
||||||
|
return wl_proxy_get_version((struct wl_proxy *) zxdg_output_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup iface_zxdg_output_v1
|
||||||
|
*
|
||||||
|
* Using this request a client can tell the server that it is not
|
||||||
|
* going to use the xdg_output object anymore.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
zxdg_output_v1_destroy(struct zxdg_output_v1 *zxdg_output_v1)
|
||||||
|
{
|
||||||
|
wl_proxy_marshal((struct wl_proxy *) zxdg_output_v1,
|
||||||
|
ZXDG_OUTPUT_V1_DESTROY);
|
||||||
|
|
||||||
|
wl_proxy_destroy((struct wl_proxy *) zxdg_output_v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
78
src/wayland/protocols/xdg-output-unstable-v1.h
Normal file
78
src/wayland/protocols/xdg-output-unstable-v1.h
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
/* Generated by wayland-scanner 1.18.0 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2017 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* 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 (including the next
|
||||||
|
* paragraph) 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
#ifndef __has_attribute
|
||||||
|
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||||
|
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||||
|
#else
|
||||||
|
#define WL_PRIVATE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const struct wl_interface wl_output_interface;
|
||||||
|
extern const struct wl_interface zxdg_output_v1_interface;
|
||||||
|
|
||||||
|
static const struct wl_interface *xdg_output_unstable_v1_types[] = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&zxdg_output_v1_interface,
|
||||||
|
&wl_output_interface,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zxdg_output_manager_v1_requests[] = {
|
||||||
|
{ "destroy", "", xdg_output_unstable_v1_types + 0 },
|
||||||
|
{ "get_xdg_output", "no", xdg_output_unstable_v1_types + 2 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface zxdg_output_manager_v1_interface = {
|
||||||
|
"zxdg_output_manager_v1", 3,
|
||||||
|
2, zxdg_output_manager_v1_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zxdg_output_v1_requests[] = {
|
||||||
|
{ "destroy", "", xdg_output_unstable_v1_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message zxdg_output_v1_events[] = {
|
||||||
|
{ "logical_position", "ii", xdg_output_unstable_v1_types + 0 },
|
||||||
|
{ "logical_size", "ii", xdg_output_unstable_v1_types + 0 },
|
||||||
|
{ "done", "", xdg_output_unstable_v1_types + 0 },
|
||||||
|
{ "name", "2s", xdg_output_unstable_v1_types + 0 },
|
||||||
|
{ "description", "2s", xdg_output_unstable_v1_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface zxdg_output_v1_interface = {
|
||||||
|
"zxdg_output_v1", 3,
|
||||||
|
1, zxdg_output_v1_requests,
|
||||||
|
5, zxdg_output_v1_events,
|
||||||
|
};
|
||||||
|
|
1970
src/wayland/protocols/xdg-shell-client-header.h
Normal file
1970
src/wayland/protocols/xdg-shell-client-header.h
Normal file
File diff suppressed because it is too large
Load Diff
181
src/wayland/protocols/xdg-shell.h
Normal file
181
src/wayland/protocols/xdg-shell.h
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
/* Generated by wayland-scanner 1.18.0 */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright © 2008-2013 Kristian Høgsberg
|
||||||
|
* Copyright © 2013 Rafael Antognolli
|
||||||
|
* Copyright © 2013 Jasper St. Pierre
|
||||||
|
* Copyright © 2010-2013 Intel Corporation
|
||||||
|
* Copyright © 2015-2017 Samsung Electronics Co., Ltd
|
||||||
|
* Copyright © 2015-2017 Red Hat Inc.
|
||||||
|
*
|
||||||
|
* 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 (including the next
|
||||||
|
* paragraph) 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "wayland-util.h"
|
||||||
|
|
||||||
|
#ifndef __has_attribute
|
||||||
|
# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4)
|
||||||
|
#define WL_PRIVATE __attribute__ ((visibility("hidden")))
|
||||||
|
#else
|
||||||
|
#define WL_PRIVATE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern const struct wl_interface wl_output_interface;
|
||||||
|
extern const struct wl_interface wl_seat_interface;
|
||||||
|
extern const struct wl_interface wl_surface_interface;
|
||||||
|
extern const struct wl_interface xdg_popup_interface;
|
||||||
|
extern const struct wl_interface xdg_positioner_interface;
|
||||||
|
extern const struct wl_interface xdg_surface_interface;
|
||||||
|
extern const struct wl_interface xdg_toplevel_interface;
|
||||||
|
|
||||||
|
static const struct wl_interface *xdg_shell_types[] = {
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&xdg_positioner_interface,
|
||||||
|
&xdg_surface_interface,
|
||||||
|
&wl_surface_interface,
|
||||||
|
&xdg_toplevel_interface,
|
||||||
|
&xdg_popup_interface,
|
||||||
|
&xdg_surface_interface,
|
||||||
|
&xdg_positioner_interface,
|
||||||
|
&xdg_toplevel_interface,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&wl_output_interface,
|
||||||
|
&wl_seat_interface,
|
||||||
|
NULL,
|
||||||
|
&xdg_positioner_interface,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_wm_base_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "create_positioner", "n", xdg_shell_types + 4 },
|
||||||
|
{ "get_xdg_surface", "no", xdg_shell_types + 5 },
|
||||||
|
{ "pong", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_wm_base_events[] = {
|
||||||
|
{ "ping", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_wm_base_interface = {
|
||||||
|
"xdg_wm_base", 3,
|
||||||
|
4, xdg_wm_base_requests,
|
||||||
|
1, xdg_wm_base_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_positioner_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_size", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_anchor_rect", "iiii", xdg_shell_types + 0 },
|
||||||
|
{ "set_anchor", "u", xdg_shell_types + 0 },
|
||||||
|
{ "set_gravity", "u", xdg_shell_types + 0 },
|
||||||
|
{ "set_constraint_adjustment", "u", xdg_shell_types + 0 },
|
||||||
|
{ "set_offset", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_reactive", "3", xdg_shell_types + 0 },
|
||||||
|
{ "set_parent_size", "3ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_parent_configure", "3u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_positioner_interface = {
|
||||||
|
"xdg_positioner", 3,
|
||||||
|
10, xdg_positioner_requests,
|
||||||
|
0, NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_surface_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "get_toplevel", "n", xdg_shell_types + 7 },
|
||||||
|
{ "get_popup", "n?oo", xdg_shell_types + 8 },
|
||||||
|
{ "set_window_geometry", "iiii", xdg_shell_types + 0 },
|
||||||
|
{ "ack_configure", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_surface_events[] = {
|
||||||
|
{ "configure", "u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_surface_interface = {
|
||||||
|
"xdg_surface", 3,
|
||||||
|
5, xdg_surface_requests,
|
||||||
|
1, xdg_surface_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_toplevel_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_parent", "?o", xdg_shell_types + 11 },
|
||||||
|
{ "set_title", "s", xdg_shell_types + 0 },
|
||||||
|
{ "set_app_id", "s", xdg_shell_types + 0 },
|
||||||
|
{ "show_window_menu", "ouii", xdg_shell_types + 12 },
|
||||||
|
{ "move", "ou", xdg_shell_types + 16 },
|
||||||
|
{ "resize", "ouu", xdg_shell_types + 18 },
|
||||||
|
{ "set_max_size", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_min_size", "ii", xdg_shell_types + 0 },
|
||||||
|
{ "set_maximized", "", xdg_shell_types + 0 },
|
||||||
|
{ "unset_maximized", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_fullscreen", "?o", xdg_shell_types + 21 },
|
||||||
|
{ "unset_fullscreen", "", xdg_shell_types + 0 },
|
||||||
|
{ "set_minimized", "", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_toplevel_events[] = {
|
||||||
|
{ "configure", "iia", xdg_shell_types + 0 },
|
||||||
|
{ "close", "", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_toplevel_interface = {
|
||||||
|
"xdg_toplevel", 3,
|
||||||
|
14, xdg_toplevel_requests,
|
||||||
|
2, xdg_toplevel_events,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_popup_requests[] = {
|
||||||
|
{ "destroy", "", xdg_shell_types + 0 },
|
||||||
|
{ "grab", "ou", xdg_shell_types + 22 },
|
||||||
|
{ "reposition", "3ou", xdg_shell_types + 24 },
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct wl_message xdg_popup_events[] = {
|
||||||
|
{ "configure", "iiii", xdg_shell_types + 0 },
|
||||||
|
{ "popup_done", "", xdg_shell_types + 0 },
|
||||||
|
{ "repositioned", "3u", xdg_shell_types + 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
WL_PRIVATE const struct wl_interface xdg_popup_interface = {
|
||||||
|
"xdg_popup", 3,
|
||||||
|
3, xdg_popup_requests,
|
||||||
|
3, xdg_popup_events,
|
||||||
|
};
|
||||||
|
|
672
src/wayland/wl.c
Normal file
672
src/wayland/wl.c
Normal file
@ -0,0 +1,672 @@
|
|||||||
|
#define _POSIX_C_SOURCE 200112L
|
||||||
|
#include "wl.h"
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <wayland-client.h>
|
||||||
|
#include <wayland-client-protocol.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <linux/input-event-codes.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "protocols/xdg-shell-client-header.h"
|
||||||
|
#include "protocols/xdg-shell.h"
|
||||||
|
#include "protocols/wlr-layer-shell-unstable-v1-client-header.h"
|
||||||
|
#include "protocols/wlr-layer-shell-unstable-v1.h"
|
||||||
|
#include "protocols/idle-client-header.h"
|
||||||
|
#include "protocols/idle.h"
|
||||||
|
#include "pool-buffer.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "../log.h"
|
||||||
|
#include "../settings.h"
|
||||||
|
#include "../queues.h"
|
||||||
|
#include "../input.h"
|
||||||
|
#include "libgwater-wayland.h"
|
||||||
|
|
||||||
|
struct window_wl {
|
||||||
|
cairo_surface_t *c_surface;
|
||||||
|
cairo_t * c_ctx;
|
||||||
|
|
||||||
|
GWaterWaylandSource *esrc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wl_ctx {
|
||||||
|
struct wl_display *display;
|
||||||
|
struct wl_registry *registry;
|
||||||
|
struct wl_compositor *compositor;
|
||||||
|
struct wl_shm *shm;
|
||||||
|
struct zwlr_layer_shell_v1 *layer_shell;
|
||||||
|
struct wl_seat *seat;
|
||||||
|
|
||||||
|
struct wl_list outputs;
|
||||||
|
|
||||||
|
struct wl_surface *surface;
|
||||||
|
struct dunst_output *surface_output;
|
||||||
|
struct zwlr_layer_surface_v1 *layer_surface;
|
||||||
|
struct dunst_output *layer_surface_output;
|
||||||
|
struct wl_callback *frame_callback;
|
||||||
|
struct org_kde_kwin_idle *idle_handler;
|
||||||
|
struct org_kde_kwin_idle_timeout *idle_timeout;
|
||||||
|
bool configured;
|
||||||
|
bool dirty;
|
||||||
|
bool is_idle;
|
||||||
|
bool has_idle_monitor;
|
||||||
|
|
||||||
|
struct {
|
||||||
|
struct wl_pointer *wl_pointer;
|
||||||
|
int32_t x, y;
|
||||||
|
} pointer;
|
||||||
|
|
||||||
|
struct dimensions cur_dim;
|
||||||
|
|
||||||
|
int32_t width, height;
|
||||||
|
struct pool_buffer buffers[2];
|
||||||
|
struct pool_buffer *current_buffer;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct dunst_output {
|
||||||
|
uint32_t global_name;
|
||||||
|
char *name;
|
||||||
|
struct wl_output *wl_output;
|
||||||
|
struct wl_list link;
|
||||||
|
|
||||||
|
uint32_t scale;
|
||||||
|
uint32_t subpixel; // TODO do something with it
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct wl_ctx ctx;
|
||||||
|
|
||||||
|
static void noop() {
|
||||||
|
// This space intentionally left blank
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_dirty();
|
||||||
|
|
||||||
|
static void output_handle_geometry(void *data, struct wl_output *wl_output,
|
||||||
|
int32_t x, int32_t y, int32_t phy_width, int32_t phy_height,
|
||||||
|
int32_t subpixel, const char *make, const char *model,
|
||||||
|
int32_t transform) {
|
||||||
|
//TODO
|
||||||
|
struct dunst_output *output = data;
|
||||||
|
output->subpixel = subpixel;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void output_handle_scale(void *data, struct wl_output *wl_output,
|
||||||
|
int32_t factor) {
|
||||||
|
struct dunst_output *output = data;
|
||||||
|
output->scale = factor;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_output_listener output_listener = {
|
||||||
|
.geometry = output_handle_geometry,
|
||||||
|
.mode = noop,
|
||||||
|
.done = noop,
|
||||||
|
.scale = output_handle_scale,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void create_output( struct wl_output *wl_output, uint32_t global_name) {
|
||||||
|
struct dunst_output *output = g_malloc0(sizeof(struct dunst_output));
|
||||||
|
if (output == NULL) {
|
||||||
|
LOG_E("allocation failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
static int number = 0;
|
||||||
|
LOG_I("New output found - id %i", number);
|
||||||
|
output->global_name = global_name;
|
||||||
|
output->wl_output = wl_output;
|
||||||
|
// TODO: Fix this
|
||||||
|
output->scale = 1;
|
||||||
|
wl_list_insert(&ctx.outputs, &output->link);
|
||||||
|
|
||||||
|
wl_output_set_user_data(wl_output, output);
|
||||||
|
wl_output_add_listener(wl_output, &output_listener, output);
|
||||||
|
number++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroy_output(struct dunst_output *output) {
|
||||||
|
if (ctx.surface_output == output) {
|
||||||
|
ctx.surface_output = NULL;
|
||||||
|
}
|
||||||
|
if (ctx.layer_surface_output == output) {
|
||||||
|
ctx.layer_surface_output = NULL;
|
||||||
|
}
|
||||||
|
wl_list_remove(&output->link);
|
||||||
|
wl_output_destroy(output->wl_output);
|
||||||
|
free(output->name);
|
||||||
|
free(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Snipped touch handling
|
||||||
|
static void pointer_handle_motion(void *data, struct wl_pointer *wl_pointer,
|
||||||
|
uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) {
|
||||||
|
ctx.pointer.x = wl_fixed_to_int(surface_x);
|
||||||
|
ctx.pointer.y = wl_fixed_to_int(surface_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pointer_handle_button(void *data, struct wl_pointer *wl_pointer,
|
||||||
|
uint32_t serial, uint32_t time, uint32_t button,
|
||||||
|
uint32_t button_state) {
|
||||||
|
input_handle_click(button, button_state, ctx.pointer.x, ctx.pointer.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_pointer_listener pointer_listener = {
|
||||||
|
.enter = noop,
|
||||||
|
.leave = noop,
|
||||||
|
.motion = pointer_handle_motion,
|
||||||
|
.button = pointer_handle_button,
|
||||||
|
.axis = noop,
|
||||||
|
};
|
||||||
|
|
||||||
|
// FIXME snipped touch listener
|
||||||
|
|
||||||
|
static void seat_handle_capabilities(void *data, struct wl_seat *wl_seat,
|
||||||
|
uint32_t capabilities) {
|
||||||
|
|
||||||
|
if (ctx.pointer.wl_pointer != NULL) {
|
||||||
|
wl_pointer_release(ctx.pointer.wl_pointer);
|
||||||
|
ctx.pointer.wl_pointer = NULL;
|
||||||
|
}
|
||||||
|
if (capabilities & WL_SEAT_CAPABILITY_POINTER) {
|
||||||
|
ctx.pointer.wl_pointer = wl_seat_get_pointer(wl_seat);
|
||||||
|
wl_pointer_add_listener(ctx.pointer.wl_pointer,
|
||||||
|
&pointer_listener, ctx.seat);
|
||||||
|
LOG_I("Adding pointer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_seat_listener seat_listener = {
|
||||||
|
.capabilities = seat_handle_capabilities,
|
||||||
|
.name = noop,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void surface_handle_enter(void *data, struct wl_surface *surface,
|
||||||
|
struct wl_output *wl_output) {
|
||||||
|
// Don't bother keeping a list of outputs, a layer surface can only be on
|
||||||
|
// one output a a time
|
||||||
|
ctx.surface_output = wl_output_get_user_data(wl_output);
|
||||||
|
set_dirty();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void surface_handle_leave(void *data, struct wl_surface *surface,
|
||||||
|
struct wl_output *wl_output) {
|
||||||
|
ctx.surface_output = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_surface_listener surface_listener = {
|
||||||
|
.enter = surface_handle_enter,
|
||||||
|
.leave = surface_handle_leave,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void schedule_frame_and_commit();
|
||||||
|
static void send_frame();
|
||||||
|
|
||||||
|
static void layer_surface_handle_configure(void *data,
|
||||||
|
struct zwlr_layer_surface_v1 *surface,
|
||||||
|
uint32_t serial, uint32_t width, uint32_t height) {
|
||||||
|
ctx.configured = true;
|
||||||
|
ctx.width = width;
|
||||||
|
ctx.height = height;
|
||||||
|
|
||||||
|
// not needed as it is set somewhere else
|
||||||
|
/* zwlr_layer_surface_v1_set_size(surface, width, height); */
|
||||||
|
zwlr_layer_surface_v1_ack_configure(surface, serial);
|
||||||
|
send_frame();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void layer_surface_handle_closed(void *data,
|
||||||
|
struct zwlr_layer_surface_v1 *surface) {
|
||||||
|
LOG_I("Destroying layer");
|
||||||
|
zwlr_layer_surface_v1_destroy(ctx.layer_surface);
|
||||||
|
ctx.layer_surface = NULL;
|
||||||
|
|
||||||
|
wl_surface_destroy(ctx.surface);
|
||||||
|
ctx.surface = NULL;
|
||||||
|
|
||||||
|
if (ctx.frame_callback) {
|
||||||
|
wl_callback_destroy(ctx.frame_callback);
|
||||||
|
ctx.frame_callback = NULL;
|
||||||
|
ctx.dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.configured) {
|
||||||
|
ctx.configured = false;
|
||||||
|
ctx.width = ctx.height = 0;
|
||||||
|
ctx.dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.dirty) {
|
||||||
|
schedule_frame_and_commit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct zwlr_layer_surface_v1_listener layer_surface_listener = {
|
||||||
|
.configure = layer_surface_handle_configure,
|
||||||
|
.closed = layer_surface_handle_closed,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static void idle_start (void *data, struct org_kde_kwin_idle_timeout *org_kde_kwin_idle_timeout) {
|
||||||
|
ctx.is_idle = true;
|
||||||
|
LOG_I("User went idle");
|
||||||
|
}
|
||||||
|
static void idle_stop (void *data, struct org_kde_kwin_idle_timeout *org_kde_kwin_idle_timeout) {
|
||||||
|
ctx.is_idle = false;
|
||||||
|
LOG_I("User isn't idle anymore");
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct org_kde_kwin_idle_timeout_listener idle_timeout_listener = {
|
||||||
|
.idle = idle_start,
|
||||||
|
.resumed = idle_stop,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void add_seat_to_idle_handler(struct wl_seat *seat) {
|
||||||
|
if (!ctx.idle_handler){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
uint32_t timeout_ms = settings.idle_threshold/1000;
|
||||||
|
ctx.idle_timeout = org_kde_kwin_idle_get_idle_timeout(ctx.idle_handler, seat, timeout_ms);
|
||||||
|
org_kde_kwin_idle_timeout_add_listener(ctx.idle_timeout, &idle_timeout_listener, 0);
|
||||||
|
ctx.has_idle_monitor = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_global(void *data, struct wl_registry *registry,
|
||||||
|
uint32_t name, const char *interface, uint32_t version) {
|
||||||
|
if (strcmp(interface, wl_compositor_interface.name) == 0) {
|
||||||
|
ctx.compositor = wl_registry_bind(registry, name,
|
||||||
|
&wl_compositor_interface, 4);
|
||||||
|
} else if (strcmp(interface, wl_shm_interface.name) == 0) {
|
||||||
|
ctx.shm = wl_registry_bind(registry, name,
|
||||||
|
&wl_shm_interface, 1);
|
||||||
|
} else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
|
||||||
|
ctx.layer_shell = wl_registry_bind(registry, name,
|
||||||
|
&zwlr_layer_shell_v1_interface, 1);
|
||||||
|
} else if (strcmp(interface, wl_seat_interface.name) == 0) {
|
||||||
|
ctx.seat = wl_registry_bind(registry, name, &wl_seat_interface, 3);
|
||||||
|
wl_seat_add_listener(ctx.seat, &seat_listener, ctx.seat);
|
||||||
|
add_seat_to_idle_handler(ctx.seat);
|
||||||
|
} else if (strcmp(interface, wl_output_interface.name) == 0) {
|
||||||
|
struct wl_output *output =
|
||||||
|
wl_registry_bind(registry, name, &wl_output_interface, 3);
|
||||||
|
create_output(output, name);
|
||||||
|
} else if (strcmp(interface, org_kde_kwin_idle_interface.name) == 0 &&
|
||||||
|
version >= ORG_KDE_KWIN_IDLE_TIMEOUT_IDLE_SINCE_VERSION) {
|
||||||
|
ctx.idle_handler = wl_registry_bind(registry, name, &org_kde_kwin_idle_interface, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handle_global_remove(void *data, struct wl_registry *registry,
|
||||||
|
uint32_t name) {
|
||||||
|
struct dunst_output *output, *tmp;
|
||||||
|
wl_list_for_each_safe(output, tmp, &ctx.outputs, link) {
|
||||||
|
if (output->global_name == name) {
|
||||||
|
destroy_output(output);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_registry_listener registry_listener = {
|
||||||
|
.global = handle_global,
|
||||||
|
.global_remove = handle_global_remove,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool init_wayland() {
|
||||||
|
wl_list_init(&ctx.outputs);
|
||||||
|
//wl_list_init(&ctx.seats);
|
||||||
|
|
||||||
|
ctx.display = wl_display_connect(NULL);
|
||||||
|
|
||||||
|
if (ctx.display == NULL) {
|
||||||
|
LOG_E("failed to create display");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.registry = wl_display_get_registry(ctx.display);
|
||||||
|
wl_registry_add_listener(ctx.registry, ®istry_listener, NULL);
|
||||||
|
wl_display_roundtrip(ctx.display);
|
||||||
|
|
||||||
|
if (ctx.compositor == NULL) {
|
||||||
|
LOG_E("compositor doesn't support wl_compositor");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ctx.shm == NULL) {
|
||||||
|
LOG_E("compositor doesn't support wl_shm");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ctx.layer_shell == NULL) {
|
||||||
|
LOG_E("compositor doesn't support zwlr_layer_shell_v1");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (ctx.seat == NULL) {
|
||||||
|
LOG_W("no seat was found, so dunst cannot see input");
|
||||||
|
} else {
|
||||||
|
if (ctx.idle_handler == NULL) {
|
||||||
|
LOG_I("compositor doesn't support org_kde_kwin_idle_interface");
|
||||||
|
}
|
||||||
|
else if (ctx.idle_timeout == NULL) {
|
||||||
|
// something went wrong in setting the timeout
|
||||||
|
LOG_W("couldn't set idle timeout");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void finish_wayland() {
|
||||||
|
if (ctx.layer_surface != NULL) {
|
||||||
|
zwlr_layer_surface_v1_destroy(ctx.layer_surface);
|
||||||
|
}
|
||||||
|
if (ctx.surface != NULL) {
|
||||||
|
wl_surface_destroy(ctx.surface);
|
||||||
|
}
|
||||||
|
finish_buffer(&ctx.buffers[0]);
|
||||||
|
finish_buffer(&ctx.buffers[1]);
|
||||||
|
|
||||||
|
struct dunst_output *output, *output_tmp;
|
||||||
|
wl_list_for_each_safe(output, output_tmp, &ctx.outputs, link) {
|
||||||
|
destroy_output(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctx.seat) {
|
||||||
|
wl_pointer_release(ctx.pointer.wl_pointer);
|
||||||
|
wl_seat_release(ctx.seat);
|
||||||
|
ctx.seat = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
zwlr_layer_shell_v1_destroy(ctx.layer_shell);
|
||||||
|
wl_compositor_destroy(ctx.compositor);
|
||||||
|
wl_shm_destroy(ctx.shm);
|
||||||
|
wl_registry_destroy(ctx.registry);
|
||||||
|
wl_display_disconnect(ctx.display);
|
||||||
|
|
||||||
|
org_kde_kwin_idle_destroy(ctx.idle_handler);
|
||||||
|
org_kde_kwin_idle_timeout_release(ctx.idle_timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct dunst_output *get_configured_output() {
|
||||||
|
struct dunst_output *output;
|
||||||
|
|
||||||
|
switch (settings.f_mode){
|
||||||
|
case FOLLOW_NONE: ; // this semicolon is neccesary
|
||||||
|
int n = 0;
|
||||||
|
int target_monitor = settings.monitor;
|
||||||
|
|
||||||
|
wl_list_for_each(output, &ctx.outputs, link) {
|
||||||
|
if (n == target_monitor)
|
||||||
|
return output;
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
LOG_W("Monitor %i doesn't exist, using focused monitor", settings.monitor);
|
||||||
|
return NULL;
|
||||||
|
case FOLLOW_MOUSE:
|
||||||
|
// fallthrough
|
||||||
|
case FOLLOW_KEYBOARD:
|
||||||
|
// fallthrough
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void schedule_frame_and_commit();
|
||||||
|
|
||||||
|
// Draw and commit a new frame.
|
||||||
|
static void send_frame() {
|
||||||
|
int scale = 1;
|
||||||
|
|
||||||
|
struct dunst_output *output = get_configured_output();
|
||||||
|
int height = ctx.cur_dim.h;
|
||||||
|
int width = ctx.cur_dim.w;
|
||||||
|
|
||||||
|
// There are two cases where we want to tear down the surface: zero
|
||||||
|
// notifications (height = 0) or moving between outputs.
|
||||||
|
if (height == 0 || ctx.layer_surface_output != output) {
|
||||||
|
if (ctx.layer_surface != NULL) {
|
||||||
|
zwlr_layer_surface_v1_destroy(ctx.layer_surface);
|
||||||
|
ctx.layer_surface = NULL;
|
||||||
|
}
|
||||||
|
if (ctx.surface != NULL) {
|
||||||
|
wl_surface_destroy(ctx.surface);
|
||||||
|
ctx.surface = NULL;
|
||||||
|
}
|
||||||
|
ctx.width = ctx.height = 0;
|
||||||
|
ctx.surface_output = NULL;
|
||||||
|
ctx.configured = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If there are no notifications, there's no point in recreating the
|
||||||
|
// surface right now.
|
||||||
|
if (height == 0) {
|
||||||
|
ctx.dirty = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we've made it here, there is something to draw. If the surface
|
||||||
|
// doesn't exist (this is the first notification, or we moved to a
|
||||||
|
// different output), we need to create it.
|
||||||
|
if (ctx.layer_surface == NULL) {
|
||||||
|
struct wl_output *wl_output = NULL;
|
||||||
|
ctx.layer_surface_output = output;
|
||||||
|
ctx.surface = wl_compositor_create_surface(ctx.compositor);
|
||||||
|
wl_surface_add_listener(ctx.surface, &surface_listener, NULL);
|
||||||
|
|
||||||
|
if (settings.frame_color)
|
||||||
|
ctx.layer_surface = zwlr_layer_shell_v1_get_layer_surface(
|
||||||
|
ctx.layer_shell, ctx.surface, wl_output,
|
||||||
|
settings.layer, "notifications");
|
||||||
|
zwlr_layer_surface_v1_add_listener(ctx.layer_surface,
|
||||||
|
&layer_surface_listener, NULL);
|
||||||
|
|
||||||
|
// Because we're creating a new surface, we aren't going to draw
|
||||||
|
// anything into it during this call. We don't know what size the
|
||||||
|
// surface will be until we've asked the compositor for what we want
|
||||||
|
// and it has responded with what it actually gave us. We also know
|
||||||
|
// that the height we would _like_ to draw (greater than zero, or we
|
||||||
|
// would have bailed already) is different from our ctx.height
|
||||||
|
// (which has to be zero here), so we can fall through to the next
|
||||||
|
// block to let it set the size for us.
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(ctx.layer_surface);
|
||||||
|
|
||||||
|
// We now want to resize the surface if it isn't the right size. If the
|
||||||
|
// surface is brand new, it doesn't even have a size yet. If it already
|
||||||
|
// exists, we might need to resize if the list of notifications has changed
|
||||||
|
// since the last time we drew.
|
||||||
|
if (ctx.height != height || ctx.width != width) {
|
||||||
|
struct dimensions dim = ctx.cur_dim;
|
||||||
|
// Set window size
|
||||||
|
LOG_D("Window dimensions %ix%i", dim.w, dim.h);
|
||||||
|
LOG_D("Window position %ix%i", dim.x, dim.y);
|
||||||
|
zwlr_layer_surface_v1_set_size(ctx.layer_surface,
|
||||||
|
dim.w, dim.h);
|
||||||
|
|
||||||
|
// TODO Do this only once
|
||||||
|
uint32_t anchor = 0;
|
||||||
|
if (settings.geometry.negative_x) {
|
||||||
|
anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT;
|
||||||
|
} else {
|
||||||
|
anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings.geometry.negative_y) {
|
||||||
|
anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM;
|
||||||
|
} else {
|
||||||
|
anchor |= ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Put the window at the right position
|
||||||
|
zwlr_layer_surface_v1_set_anchor(ctx.layer_surface,
|
||||||
|
anchor);
|
||||||
|
zwlr_layer_surface_v1_set_margin(ctx.layer_surface,
|
||||||
|
abs(settings.geometry.y), // top
|
||||||
|
abs(settings.geometry.x), // right
|
||||||
|
abs(settings.geometry.y), // bottom
|
||||||
|
abs(settings.geometry.x));// left
|
||||||
|
|
||||||
|
wl_surface_commit(ctx.surface);
|
||||||
|
|
||||||
|
// Now we're going to bail without drawing anything. This gives the
|
||||||
|
// compositor a chance to create the surface and tell us what size we
|
||||||
|
// were actually granted, which may be smaller than what we asked for
|
||||||
|
// depending on the screen size and layout of other layer surfaces.
|
||||||
|
// This information is provided in layer_surface_handle_configure,
|
||||||
|
// which will then call send_frame again. When that call happens, the
|
||||||
|
// layer surface will exist and the height will hopefully match what
|
||||||
|
// we asked for. That means we won't return here, and will actually
|
||||||
|
// draw into the surface down below.
|
||||||
|
// TODO: If the compositor doesn't send a configure with the size we
|
||||||
|
// requested, we'll enter an infinite loop. We need to keep track of
|
||||||
|
// the fact that a request was sent separately from what height we are.
|
||||||
|
wl_display_roundtrip(ctx.display);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(ctx.configured);
|
||||||
|
|
||||||
|
// Yay we can finally draw something!
|
||||||
|
wl_surface_set_buffer_scale(ctx.surface, scale);
|
||||||
|
wl_surface_damage_buffer(ctx.surface, 0, 0, INT32_MAX, INT32_MAX);
|
||||||
|
wl_surface_attach(ctx.surface, ctx.current_buffer->buffer, 0, 0);
|
||||||
|
ctx.current_buffer->busy = true;
|
||||||
|
|
||||||
|
// Schedule a frame in case the state becomes dirty again
|
||||||
|
schedule_frame_and_commit();
|
||||||
|
|
||||||
|
ctx.dirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void frame_handle_done(void *data, struct wl_callback *callback,
|
||||||
|
uint32_t time) {
|
||||||
|
wl_callback_destroy(ctx.frame_callback);
|
||||||
|
ctx.frame_callback = NULL;
|
||||||
|
|
||||||
|
// Only draw again if we need to
|
||||||
|
if (ctx.dirty) {
|
||||||
|
send_frame();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct wl_callback_listener frame_listener = {
|
||||||
|
.done = frame_handle_done,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void schedule_frame_and_commit() {
|
||||||
|
if (ctx.frame_callback) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ctx.surface == NULL) {
|
||||||
|
// We don't yet have a surface, create it immediately
|
||||||
|
send_frame();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ctx.frame_callback = wl_surface_frame(ctx.surface);
|
||||||
|
wl_callback_add_listener(ctx.frame_callback, &frame_listener, NULL);
|
||||||
|
wl_surface_commit(ctx.surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_dirty() {
|
||||||
|
if (ctx.dirty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ctx.dirty = true;
|
||||||
|
schedule_frame_and_commit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wl_init(void) {
|
||||||
|
init_wayland();
|
||||||
|
}
|
||||||
|
|
||||||
|
void wl_deinit(void) {
|
||||||
|
}
|
||||||
|
|
||||||
|
window wl_win_create(void) {
|
||||||
|
struct window_wl *win = g_malloc0(sizeof(struct window_wl));
|
||||||
|
|
||||||
|
win->esrc = g_water_wayland_source_new_for_display(NULL, ctx.display);
|
||||||
|
return win;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wl_win_destroy(window winptr) {
|
||||||
|
struct window_wl *win = (struct window_wl*)winptr;
|
||||||
|
|
||||||
|
g_water_wayland_source_free(win->esrc);
|
||||||
|
// FIXME: Dealloc everything
|
||||||
|
g_free(win);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wl_win_show(window win) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void wl_win_hide(window win) {
|
||||||
|
LOG_I("Wayland: Hiding window");
|
||||||
|
ctx.cur_dim.h = 0;
|
||||||
|
set_dirty();
|
||||||
|
wl_display_roundtrip(ctx.display);
|
||||||
|
}
|
||||||
|
|
||||||
|
void wl_display_surface(cairo_surface_t *srf, window winptr, const struct dimensions* dim) {
|
||||||
|
/* struct window_wl *win = (struct window_wl*)winptr; */
|
||||||
|
ctx.current_buffer = get_next_buffer(ctx.shm, ctx.buffers, dim->w, dim->h);
|
||||||
|
|
||||||
|
cairo_t *c = ctx.current_buffer->cairo;
|
||||||
|
cairo_save(c);
|
||||||
|
cairo_set_source_surface(c, srf, 0, 0);
|
||||||
|
cairo_rectangle(c, 0, 0, dim->w, dim->h);
|
||||||
|
cairo_fill(c);
|
||||||
|
cairo_restore(c);
|
||||||
|
|
||||||
|
ctx.cur_dim = *dim;
|
||||||
|
|
||||||
|
set_dirty();
|
||||||
|
wl_display_roundtrip(ctx.display);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wl_win_visible(window win) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
cairo_t* wl_win_get_context(window winptr) {
|
||||||
|
struct window_wl *win = (struct window_wl*)winptr;
|
||||||
|
ctx.current_buffer = get_next_buffer(ctx.shm, ctx.buffers, 500, 500);
|
||||||
|
win->c_surface = ctx.current_buffer->surface;
|
||||||
|
win->c_ctx = ctx.current_buffer->cairo;
|
||||||
|
return win->c_ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct screen_info* wl_get_active_screen(void) {
|
||||||
|
// TODO Screen size detection
|
||||||
|
static struct screen_info scr = {
|
||||||
|
.w = 1920,
|
||||||
|
.h = 1080,
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.id = 0,
|
||||||
|
.mmh = 500
|
||||||
|
};
|
||||||
|
return &scr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool wl_is_idle(void) {
|
||||||
|
LOG_I("Idle status queried: %i", ctx.is_idle);
|
||||||
|
// When the user doesn't have a seat, or their compositor doesn't support the idle
|
||||||
|
// protocol, we'll assume that they are not idle.
|
||||||
|
if (settings.idle_threshold == 0 || ctx.has_idle_monitor == false) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return ctx.is_idle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool wl_have_fullscreen_window(void) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
28
src/wayland/wl.h
Normal file
28
src/wayland/wl.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef DUNST_WL_H
|
||||||
|
#define DUNST_WL_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <cairo.h>
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
#include "../output.h"
|
||||||
|
|
||||||
|
void wl_init(void);
|
||||||
|
void wl_deinit(void);
|
||||||
|
|
||||||
|
window wl_win_create(void);
|
||||||
|
void wl_win_destroy(window);
|
||||||
|
|
||||||
|
void wl_win_show(window);
|
||||||
|
void wl_win_hide(window);
|
||||||
|
|
||||||
|
void wl_display_surface(cairo_surface_t *srf, window win, const struct dimensions*);
|
||||||
|
bool wl_win_visible(window);
|
||||||
|
cairo_t* wl_win_get_context(window);
|
||||||
|
|
||||||
|
const struct screen_info* wl_get_active_screen(void);
|
||||||
|
|
||||||
|
bool wl_is_idle(void);
|
||||||
|
bool wl_have_fullscreen_window(void);
|
||||||
|
#endif
|
||||||
|
/* vim: set ft=c tabstop=8 shiftwidth=8 expandtab textwidth=0: */
|
74
src/x11/x.c
74
src/x11/x.c
@ -19,6 +19,7 @@
|
|||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
#include <X11/Xresource.h>
|
#include <X11/Xresource.h>
|
||||||
#include <X11/Xutil.h>
|
#include <X11/Xutil.h>
|
||||||
|
#include <linux/input-event-codes.h>
|
||||||
|
|
||||||
#include "../dbus.h"
|
#include "../dbus.h"
|
||||||
#include "../draw.h"
|
#include "../draw.h"
|
||||||
@ -30,6 +31,7 @@
|
|||||||
#include "../queues.h"
|
#include "../queues.h"
|
||||||
#include "../settings.h"
|
#include "../settings.h"
|
||||||
#include "../utils.h"
|
#include "../utils.h"
|
||||||
|
#include "../input.h"
|
||||||
|
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
|
|
||||||
@ -403,62 +405,47 @@ bool x_is_idle(void)
|
|||||||
return xctx.screensaver_info->idle > settings.idle_threshold / 1000;
|
return xctx.screensaver_info->idle > settings.idle_threshold / 1000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert x button code to linux event code
|
||||||
|
* Returns 0 if button is not recognized.
|
||||||
|
*/
|
||||||
|
static unsigned int x_mouse_button_to_linux_event_code(unsigned int x_button)
|
||||||
|
{
|
||||||
|
switch (x_button) {
|
||||||
|
case Button1:
|
||||||
|
return BTN_LEFT;
|
||||||
|
case Button2:
|
||||||
|
return BTN_MIDDLE;
|
||||||
|
case Button3:
|
||||||
|
return BTN_RIGHT;
|
||||||
|
default:
|
||||||
|
LOG_W("Unsupported mouse button: '%d'", x_button);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* TODO move to x_mainloop_* */
|
/* TODO move to x_mainloop_* */
|
||||||
/*
|
/*
|
||||||
* Handle incoming mouse click events
|
* Handle incoming mouse click events
|
||||||
*/
|
*/
|
||||||
static void x_handle_click(XEvent ev)
|
static void x_handle_click(XEvent ev)
|
||||||
{
|
{
|
||||||
enum mouse_action *acts;
|
unsigned int linux_code = x_mouse_button_to_linux_event_code(ev.xbutton.button);
|
||||||
|
|
||||||
switch (ev.xbutton.button) {
|
if (linux_code == 0) {
|
||||||
case Button1:
|
|
||||||
acts = settings.mouse_left_click;
|
|
||||||
break;
|
|
||||||
case Button2:
|
|
||||||
acts = settings.mouse_middle_click;
|
|
||||||
break;
|
|
||||||
case Button3:
|
|
||||||
acts = settings.mouse_right_click;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG_W("Unsupported mouse button: '%d'", ev.xbutton.button);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; acts[i]; i++) {
|
bool button_state;
|
||||||
enum mouse_action act = acts[i];
|
if(ev.type == ButtonRelease) {
|
||||||
if (act == MOUSE_CLOSE_ALL) {
|
button_state = false; // button is up
|
||||||
queues_history_push_all();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (act == MOUSE_DO_ACTION || act == MOUSE_CLOSE_CURRENT) {
|
|
||||||
int y = settings.separator_height;
|
|
||||||
struct notification *n = NULL;
|
|
||||||
int first = true;
|
|
||||||
for (const GList *iter = queues_get_displayed(); iter;
|
|
||||||
iter = iter->next) {
|
|
||||||
n = iter->data;
|
|
||||||
if (ev.xbutton.y > y && ev.xbutton.y < y + n->displayed_height)
|
|
||||||
break;
|
|
||||||
|
|
||||||
y += n->displayed_height + settings.separator_height;
|
|
||||||
if (first)
|
|
||||||
y += settings.frame_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n) {
|
|
||||||
if (act == MOUSE_CLOSE_CURRENT) {
|
|
||||||
n->marked_for_closure = REASON_USER;
|
|
||||||
} else {
|
} else {
|
||||||
notification_do_action(n);
|
// this shouldn't happen, because this function
|
||||||
}
|
// is only called when it'a a ButtonRelease event
|
||||||
}
|
button_state = true; // button is down
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wake_up();
|
input_handle_click(linux_code, button_state, ev.xbutton.x, ev.xbutton.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void x_free(void)
|
void x_free(void)
|
||||||
@ -777,6 +764,7 @@ void x_win_show(window winptr)
|
|||||||
*/
|
*/
|
||||||
void x_win_hide(window winptr)
|
void x_win_hide(window winptr)
|
||||||
{
|
{
|
||||||
|
LOG_I("X11: Hiding window");
|
||||||
struct window_x11 *win = (struct window_x11*)winptr;
|
struct window_x11 *win = (struct window_x11*)winptr;
|
||||||
ASSERT_OR_RET(win->visible,);
|
ASSERT_OR_RET(win->visible,);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user