Merge branch 'xdg-activation'

Closes #487
This commit is contained in:
Daniel Eklöf 2021-05-14 14:23:19 +02:00
commit 92e517ae34
No known key found for this signature in database
GPG key ID: 5BBD4992C116573F
7 changed files with 130 additions and 17 deletions

View file

@ -14,7 +14,7 @@ before_script:
- apk add ttf-hack font-noto-emoji
debug-x64:
image: alpine:latest
image: alpine:edge
stage: build
script:
- mkdir -p bld/debug
@ -27,7 +27,7 @@ debug-x64:
junit: bld/debug/meson-logs/testlog.junit.xml
release-x64:
image: alpine:latest
image: alpine:edge
stage: build
script:
- mkdir -p bld/release
@ -40,7 +40,7 @@ release-x64:
junit: bld/release/meson-logs/testlog.junit.xml
debug-x86:
image: i386/alpine:latest
image: i386/alpine:edge
stage: build
script:
- mkdir -p bld/debug
@ -53,7 +53,7 @@ debug-x86:
junit: bld/debug/meson-logs/testlog.junit.xml
release-x86:
image: i386/alpine:latest
image: i386/alpine:edge
stage: build
script:
- mkdir -p bld/release
@ -66,7 +66,7 @@ release-x86:
junit: bld/release/meson-logs/testlog.junit.xml
codespell:
image: alpine:latest
image: alpine:edge
stage: build
script:
- apk add python3

View file

@ -43,6 +43,9 @@
(https://codeberg.org/dnkl/foot/pulls/483)
* Support for setting the full 256 color palette in foot.ini
(https://codeberg.org/dnkl/foot/issues/489)
* XDG activation support, will be used by `[bell].urgent` when
available (falling back to coloring the window margins red when
unavailable) (https://codeberg.org/dnkl/foot/issues/487).
### Changed

View file

@ -88,7 +88,7 @@ wscanner_prog = find_program(
wl_proto_headers = []
wl_proto_src = []
foreach prot : [
wl_proto_xml = [
wayland_protocols_datadir + '/stable/xdg-shell/xdg-shell.xml',
wayland_protocols_datadir + '/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml',
wayland_protocols_datadir + '/unstable/xdg-output/xdg-output-unstable-v1.xml',
@ -97,6 +97,12 @@ foreach prot : [
wayland_protocols_datadir + '/unstable/text-input/text-input-unstable-v3.xml',
]
if wayland_protocols.version().version_compare('>=1.21')
add_project_arguments('-DHAVE_XDG_ACTIVATION', language: 'c')
wl_proto_xml += [wayland_protocols_datadir + '/staging/xdg-activation/xdg-activation-v1.xml']
endif
foreach prot : wl_proto_xml
wl_proto_headers += custom_target(
prot.underscorify() + '-client-header',
output: '@BASENAME@.h',

View file

@ -81,6 +81,7 @@ wayl_win_init(struct terminal *term)
}
void wayl_win_destroy(struct wl_window *win) {}
bool wayl_win_set_urgent(struct wl_window *win) { return true; }
bool
spawn(struct reaper *reaper, const char *cwd, char *const argv[],

View file

@ -2632,16 +2632,24 @@ term_bell(struct terminal *term)
if (!term->kbd_focus) {
if (term->conf->bell.urgent) {
/* There's no 'urgency' hint in Wayland - we just paint the
* margins red */
term->render.urgency = true;
term_damage_margins(term);
if (!wayl_win_set_urgent(term->window)) {
/*
* Urgency (xdg-activation) is relatively new in
* Wayland. Fallback to our old, faked, urgency -
* rendering our window margins in red
*/
term->render.urgency = true;
term_damage_margins(term);
}
}
if (term->conf->bell.notify)
notify_notify(term, "Bell", "Bell in terminal");
}
if ((term->conf->bell.command.argv != NULL) && (!term->kbd_focus || term->conf->bell.command_focused)) {
if ((term->conf->bell.command.argv != NULL) &&
(!term->kbd_focus || term->conf->bell.command_focused))
{
int devnull = open("/dev/null", O_RDONLY);
spawn(term->reaper, NULL, term->conf->bell.command.argv, devnull, -1, -1);

View file

@ -12,13 +12,9 @@
#include <wayland-client.h>
#include <wayland-cursor.h>
#include <xdg-shell.h>
#include <xkbcommon/xkbcommon-compose.h>
#include <tllist.h>
#include <xdg-output-unstable-v1.h>
#include <xdg-decoration-unstable-v1.h>
#include <text-input-unstable-v3.h>
#define LOG_MODULE "wayland"
#define LOG_ENABLE_DBG 0
@ -630,7 +626,7 @@ xdg_toplevel_close(void *data, struct xdg_toplevel *xdg_toplevel)
static const struct xdg_toplevel_listener xdg_toplevel_listener = {
.configure = &xdg_toplevel_configure,
.close = &xdg_toplevel_close,
/*.close = */&xdg_toplevel_close, /* epoll-shim defines a macro close... */
};
static void
@ -989,6 +985,17 @@ handle_global(void *data, struct wl_registry *registry,
}
}
#if defined(HAVE_XDG_ACTIVATION)
else if (strcmp(interface, xdg_activation_v1_interface.name) == 0) {
const uint32_t required = 1;
if (!verify_iface_version(interface, version, required))
return;
wayl->xdg_activation = wl_registry_bind(
wayl->registry, name, &xdg_activation_v1_interface, required);
}
#endif
#if defined(FOOT_IME_ENABLED) && FOOT_IME_ENABLED
else if (strcmp(interface, zwp_text_input_manager_v3_interface.name) == 0) {
const uint32_t required = 1;
@ -1187,6 +1194,16 @@ wayl_init(const struct config *conf, struct fdm *fdm)
if (wayl->primary_selection_device_manager == NULL)
LOG_WARN("no primary selection available");
#if defined(HAVE_XDG_ACTIVATION)
if (wayl->xdg_activation == NULL && conf->bell.urgent) {
#else
if (conf->bell.urgent) {
#endif
LOG_WARN(
"no XDG activation support; "
"bell.urgent will fall back to coloring the window margins red");
}
if (conf->presentation_timings && wayl->presentation == NULL) {
LOG_ERR("presentation time interface not implemented by compositor");
goto out;
@ -1275,6 +1292,10 @@ wayl_destroy(struct wayland *wayl)
zwp_text_input_manager_v3_destroy(wayl->text_input_manager);
#endif
#if defined(HAVE_XDG_ACTIVATION)
if (wayl->xdg_activation != NULL)
xdg_activation_v1_destroy(wayl->xdg_activation);
#endif
if (wayl->xdg_output_manager != NULL)
zxdg_output_manager_v1_destroy(wayl->xdg_output_manager);
if (wayl->shell != NULL)
@ -1452,6 +1473,10 @@ wayl_win_destroy(struct wl_window *win)
wayl_win_subsurface_destroy(&win->scrollback_indicator);
wayl_win_subsurface_destroy(&win->render_timer);
#if defined(HAVE_XDG_ACTIVATION)
if (win->xdg_activation_token != NULL)
xdg_activation_token_v1_destroy(win->xdg_activation_token);
#endif
if (win->frame_callback != NULL)
wl_callback_destroy(win->frame_callback);
if (win->xdg_toplevel_decoration != NULL)
@ -1573,6 +1598,58 @@ wayl_roundtrip(struct wayland *wayl)
wayl_flush(wayl);
}
#if defined(HAVE_XDG_ACTIVATION)
static void
activation_token_done(void *data, struct xdg_activation_token_v1 *xdg_token,
const char *token)
{
struct wl_window *win = data;
struct wayland *wayl = win->term->wl;
LOG_DBG("activation token: %s", token);
xdg_activation_v1_activate(wayl->xdg_activation, token, win->surface);
xassert(win->xdg_activation_token == xdg_token);
xdg_activation_token_v1_destroy(xdg_token);
win->xdg_activation_token = NULL;
}
static const struct xdg_activation_token_v1_listener activation_token_listener = {
.done = &activation_token_done,
};
#endif /* HAVE_XDG_ACTIVATION */
bool
wayl_win_set_urgent(struct wl_window *win)
{
#if defined(HAVE_XDG_ACTIVATION)
struct wayland *wayl = win->term->wl;
if (wayl->xdg_activation == NULL)
return false;
if (win->xdg_activation_token != NULL)
return true;
struct xdg_activation_token_v1 *token =
xdg_activation_v1_get_activation_token(wayl->xdg_activation);
if (token == NULL) {
LOG_ERR("failed to retrieve XDG activation token");
return false;
}
xdg_activation_token_v1_add_listener(token, &activation_token_listener, win);
xdg_activation_token_v1_set_surface(token, win->surface);
xdg_activation_token_v1_commit(token);
win->xdg_activation_token = token;
return true;
#else
return false;
#endif
}
bool
wayl_win_subsurface_new_with_custom_parent(
struct wl_window *win, struct wl_surface *parent,

View file

@ -8,8 +8,17 @@
#include <wayland-client.h>
#include <xkbcommon/xkbcommon.h>
#include <primary-selection-unstable-v1.h>
/* Wayland protocols */
#include <presentation-time.h>
#include <primary-selection-unstable-v1.h>
#include <text-input-unstable-v3.h>
#include <xdg-decoration-unstable-v1.h>
#include <xdg-output-unstable-v1.h>
#include <xdg-shell.h>
#if defined(HAVE_XDG_ACTIVATION)
#include <xdg-activation-v1.h>
#endif
#include <tllist.h>
@ -377,6 +386,9 @@ struct wl_window {
struct wl_surface *surface;
struct xdg_surface *xdg_surface;
struct xdg_toplevel *xdg_toplevel;
#if defined(HAVE_XDG_ACTIVATION)
struct xdg_activation_token_v1 *xdg_activation_token;
#endif
struct zxdg_toplevel_decoration_v1 *xdg_toplevel_decoration;
@ -444,6 +456,10 @@ struct wayland {
struct wl_data_device_manager *data_device_manager;
struct zwp_primary_selection_device_manager_v1 *primary_selection_device_manager;
#if defined(HAVE_XDG_ACTIVATION)
struct xdg_activation_v1 *xdg_activation;
#endif
struct wp_presentation *presentation;
uint32_t presentation_clock_id;
@ -469,6 +485,8 @@ void wayl_roundtrip(struct wayland *wayl);
struct wl_window *wayl_win_init(struct terminal *term);
void wayl_win_destroy(struct wl_window *win);
bool wayl_win_set_urgent(struct wl_window *win);
bool wayl_win_subsurface_new(
struct wl_window *win, struct wl_surf_subsurf *surf);
bool wayl_win_subsurface_new_with_custom_parent(