Compare commits

..

7 Commits

Author SHA1 Message Date
14a5609dae
Merge branch 'master' of https://codeberg.org/river/river 2024-07-07 22:30:06 -07:00
Isaac Freund
4232d6b99f
layer-shell: fix on_demand keyboard focus
Currently keyboard focus is stolen from layer surfaces with
on_demand keyboard interactivity any time Root.applyPending() is called.

This commit fixes the behavior to only steal focus when explicitly
focusing a different window/layer surface.
2024-07-02 15:03:22 +02:00
Isaac Freund
ec16f1c375
XdgPopup: send configure after initial commit
Currently we send the first configure for xdg popups before the popup
has made its initial commit. This is incorrect according to the protocol
and may confuse clients.
2024-07-01 12:55:35 +02:00
Isaac Freund
a80e0f7322
Output: fix Wayland backend support
The wlroots Wayland backend does not support gamma LUT application and
will currently fail to render anything if river commits a gamma LUT.

To fix this, test the state when applying a gamma LUT and fall back to a
state with no gamma LUT set if that fails.

This problem was revealed by 2e09b66 which flags gamma as dirty on all
outputs when they are enabled.
2024-07-01 12:27:16 +02:00
Isaac Freund
0997fde28e
docs: tweak repology link wording in readme 2024-06-30 12:12:00 +02:00
Isaac Freund
ae7f4b8fcb
Xwayland: fix unsound cast
The X11 protocol uses 16 bit integers for width/height but we use
32 bit integers everywhere else in river. Make sure that values outside
the range of a 16 bit integer don't cause river to crash with an
assertion failure.

I think that coordinates outside the range of a 16 bit integer could
theoretically be reasonable with tiled high resolution displays in the
future. I doubt they ever get used in practice today but at the same
time we can't allow an errant layout generator to crash river.
2024-06-25 12:24:25 +02:00
Isaac Freund
2e09b66963
Output: flag gamma as dirty on enable
We can end up with stale gamma settings if we don't re-check the
current gamma settings for the output on enable.
2024-06-24 19:29:19 +02:00
7 changed files with 42 additions and 19 deletions

View File

@ -7,7 +7,7 @@
River is a dynamic tiling Wayland compositor with flexible runtime
configuration.
Install from your [package manager](https://repology.org/project/river/versions) —
Check [packaging status](https://repology.org/project/river/versions) —
Join us at [#river](https://web.libera.chat/?channels=#river) on irc.libera.chat —
Read our man pages, [wiki](https://codeberg.org/river/wiki), and
[Code of Conduct](CODE_OF_CONDUCT.md)

View File

@ -12,8 +12,8 @@
.hash = "1220687c8c47a48ba285d26a05600f8700d37fc637e223ced3aa8324f3650bf52242",
},
.@"zig-wlroots" = .{
.url = "https://codeberg.org/ifreund/zig-wlroots/archive/v0.17.1.tar.gz",
.hash = "1220c65ab884c236cc950b564c70f6cd04046d86485ee76e0cde886cef7438021b4f",
.url = "https://codeberg.org/ifreund/zig-wlroots/archive/084736cd92364b5fa7d8161611d085ce272fa707.tar.gz",
.hash = "12208383c1cf42e9b932b90f68cd4f378582cf966355a6377fd8f913852e7bc2d7c6",
},
.@"zig-xkbcommon" = .{
.url = "https://codeberg.org/ifreund/zig-xkbcommon/archive/v0.2.0.tar.gz",

View File

@ -474,6 +474,7 @@ pub fn applyState(output: *Output, state: *wlr.Output.State) error{CommitFailed}
fn handleEnableDisable(output: *Output) void {
output.updateLockRenderStateOnEnableDisable();
output.gamma_dirty = true;
if (output.wlr_output.enabled) {
// Add the output to root.active_outputs and the output layout if it has not
@ -539,18 +540,23 @@ fn renderAndCommit(output: *Output, scene_output: *wlr.SceneOutput) !void {
var state = wlr.Output.State.init();
defer state.finish();
if (server.root.gamma_control_manager.getControl(output.wlr_output)) |control| {
log.info("applying gamma settings from client", .{});
if (!control.apply(&state)) return error.OutOfMemory;
} else {
log.info("clearing gamma settings from client", .{});
const control = server.root.gamma_control_manager.getControl(output.wlr_output);
if (!wlr.GammaControlV1.apply(control, &state)) return error.OutOfMemory;
if (!output.wlr_output.testState(&state)) {
wlr.GammaControlV1.sendFailedAndDestroy(control);
state.clearGammaLut();
// If the backend does not support gamma LUTs it will reject any
// state with the gamma LUT committed bit set even if the state
// has a null LUT. The wayland backend for example has this behavior.
state.committed.gamma_lut = false;
}
if (!scene_output.buildState(&state, null)) return error.CommitFailed;
if (!output.wlr_output.commitState(&state)) return error.CommitFailed;
// TODO(wlroots) remove this rotate() call when updating to wlroots 0.18
scene_output.damage_ring.rotate();
output.gamma_dirty = false;
} else {

View File

@ -897,6 +897,7 @@ fn handlePowerManagerSetMode(
}
output.updateLockRenderStateOnEnableDisable();
output.gamma_dirty = true;
}
fn handleSetGamma(

View File

@ -165,14 +165,21 @@ pub fn focus(seat: *Seat, _target: ?*View) void {
// Views may not receive focus while locked.
if (server.lock_manager.state != .unlocked) return;
// While a layer surface is exclusively focused, views may not receive focus
// A layer surface with exclusive focus will prevent any view from gaining
// focus if it is on the top or overlay layer. Otherwise, only steal focus
// from a focused layer surface if there is an explicit target view.
if (seat.focused == .layer) {
const wlr_layer_surface = seat.focused.layer.wlr_layer_surface;
assert(wlr_layer_surface.surface.mapped);
if (wlr_layer_surface.current.keyboard_interactive == .exclusive and
(wlr_layer_surface.current.layer == .top or wlr_layer_surface.current.layer == .overlay))
{
return;
switch (wlr_layer_surface.current.keyboard_interactive) {
.none => {},
.exclusive => switch (wlr_layer_surface.current.layer) {
.top, .overlay => return,
.bottom, .background => if (target == null) return,
_ => {},
},
.on_demand => if (target == null) return,
_ => {},
}
}

View File

@ -35,6 +35,7 @@ root: *wlr.SceneTree,
tree: *wlr.SceneTree,
destroy: wl.Listener(void) = wl.Listener(void).init(handleDestroy),
commit: wl.Listener(*wlr.Surface) = wl.Listener(*wlr.Surface).init(handleCommit),
new_popup: wl.Listener(*wlr.XdgPopup) = wl.Listener(*wlr.XdgPopup).init(handleNewPopup),
reposition: wl.Listener(void) = wl.Listener(void).init(handleReposition),
@ -54,22 +55,30 @@ pub fn create(
};
wlr_xdg_popup.base.events.destroy.add(&xdg_popup.destroy);
wlr_xdg_popup.base.surface.events.commit.add(&xdg_popup.commit);
wlr_xdg_popup.base.events.new_popup.add(&xdg_popup.new_popup);
wlr_xdg_popup.events.reposition.add(&xdg_popup.reposition);
handleReposition(&xdg_popup.reposition);
}
fn handleDestroy(listener: *wl.Listener(void)) void {
const xdg_popup: *XdgPopup = @fieldParentPtr("destroy", listener);
xdg_popup.destroy.link.remove();
xdg_popup.commit.link.remove();
xdg_popup.new_popup.link.remove();
xdg_popup.reposition.link.remove();
util.gpa.destroy(xdg_popup);
}
fn handleCommit(listener: *wl.Listener(*wlr.Surface), _: *wlr.Surface) void {
const xdg_popup: *XdgPopup = @fieldParentPtr("commit", listener);
if (xdg_popup.wlr_xdg_popup.base.initial_commit) {
handleReposition(&xdg_popup.reposition);
}
}
fn handleNewPopup(listener: *wl.Listener(*wlr.XdgPopup), wlr_xdg_popup: *wlr.XdgPopup) void {
const xdg_popup: *XdgPopup = @fieldParentPtr("new_popup", listener);

View File

@ -106,10 +106,10 @@ pub fn configure(xwayland_view: XwaylandView) bool {
}
xwayland_view.xwayland_surface.configure(
@intCast(inflight.box.x + output_box.x),
@intCast(inflight.box.y + output_box.y),
@intCast(inflight.box.width),
@intCast(inflight.box.height),
math.lossyCast(i16, inflight.box.x + output_box.x),
math.lossyCast(i16, inflight.box.y + output_box.y),
math.lossyCast(u16, inflight.box.width),
math.lossyCast(u16, inflight.box.height),
);
xwayland_view.setActivated(inflight.focus != 0);