diff --git a/river/Cursor.zig b/river/Cursor.zig index 3769251..8d549f1 100644 --- a/river/Cursor.zig +++ b/river/Cursor.zig @@ -263,30 +263,26 @@ fn handleButton(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { } } - // If the found surface is an xdg toplevel surface, send keyboard - // focus to the view. - if (c.wlr_surface_is_xdg_surface(wlr_surface)) { - const wlr_xdg_surface = c.wlr_xdg_surface_from_wlr_surface(wlr_surface); - if (wlr_xdg_surface.*.role == .WLR_XDG_SURFACE_ROLE_TOPLEVEL) { - const view = util.voidCast(View, wlr_xdg_surface.*.data.?); - self.seat.focus(view); + // If the target surface has a view, give that view keyboard focus and + // perhaps enter move/resize mode. + if (View.fromWlrSurface(wlr_surface)) |view| { + self.seat.focus(view); - if (event.state == .WLR_BUTTON_PRESSED and self.pressed_count == 1) { - // If the button is pressed and the pointer modifier is - // active, enter cursor mode or close view and return. - const fullscreen = view.current.fullscreen or view.pending.fullscreen; - if (self.seat.pointer_modifier) { - switch (event.button) { - c.BTN_LEFT => if (!fullscreen) self.enterCursorMode(event, view, .move), - c.BTN_MIDDLE => view.close(), - c.BTN_RIGHT => if (!fullscreen) self.enterCursorMode(event, view, .resize), + if (event.state == .WLR_BUTTON_PRESSED and self.pressed_count == 1) { + // If the button is pressed and the pointer modifier is + // active, enter cursor mode or close view and return. + const fullscreen = view.current.fullscreen or view.pending.fullscreen; + if (self.seat.pointer_modifier) { + switch (event.button) { + c.BTN_LEFT => if (!fullscreen) self.enterCursorMode(event, view, .move), + c.BTN_MIDDLE => view.close(), + c.BTN_RIGHT => if (!fullscreen) self.enterCursorMode(event, view, .resize), - // TODO Some mice have additional buttons. These - // could also be bound to some useful action. - else => {}, - } - return; + // TODO Some mice have additional buttons. These + // could also be bound to some useful action. + else => {}, } + return; } } } diff --git a/river/View.zig b/river/View.zig index ab90976..2dd3cd3 100644 --- a/river/View.zig +++ b/river/View.zig @@ -293,6 +293,23 @@ pub fn getConstraints(self: Self) Constraints { }; } +/// Find and return the view corresponding to a given wlr_surface, if any +pub fn fromWlrSurface(wlr_surface: *c.wlr_surface) ?*Self { + if (c.wlr_surface_is_xdg_surface(wlr_surface)) { + const wlr_xdg_surface = c.wlr_xdg_surface_from_wlr_surface(wlr_surface); + if (wlr_xdg_surface.*.role == .WLR_XDG_SURFACE_ROLE_TOPLEVEL) { + return util.voidCast(Self, wlr_xdg_surface.*.data.?); + } + } + if (build_options.xwayland) { + if (c.wlr_surface_is_xwayland_surface(wlr_surface)) { + const wlr_xwayland_surface = c.wlr_xwayland_surface_from_wlr_surface(wlr_surface); + return util.voidCast(Self, wlr_xwayland_surface.*.data.?); + } + } + return null; +} + /// Called by the impl when the surface is ready to be displayed pub fn map(self: *Self) void { const root = self.output.root; diff --git a/river/XwaylandView.zig b/river/XwaylandView.zig index 130ecc5..7ae248b 100644 --- a/river/XwaylandView.zig +++ b/river/XwaylandView.zig @@ -57,8 +57,10 @@ pub fn init(self: *Self, view: *View, wlr_xwayland_surface: *c.wlr_xwayland_surf } pub fn needsConfigure(self: Self) bool { - return self.view.current.box.width != self.view.pending.box.width or - self.view.current.box.height != self.view.pending.box.height; + return self.wlr_xwayland_surface.x != self.view.pending.box.x or + self.wlr_xwayland_surface.y != self.view.pending.box.y or + self.wlr_xwayland_surface.width != self.view.pending.box.width or + self.wlr_xwayland_surface.height != self.view.pending.box.height; } /// Tell the client to take a new size @@ -195,7 +197,12 @@ fn handleCommit(listener: ?*c.wl_listener, data: ?*c_void) callconv(.C) void { // See comment in XwaylandView.configure() if (view.pending_serial != null) { - view.output.root.notifyConfigured(); + // If the view is part of the layout, notify the transaction code. If + // the view is floating or fullscreen apply the pending state immediately. view.pending_serial = null; + if (!view.pending.float and !view.pending.fullscreen) + view.output.root.notifyConfigured() + else + view.current = view.pending; } }