* fix: cast ExitStatus to correct type, remove Boxes
Absolutely no clue why Past Me thought `usize` was the correct type
to convert `ExitStatus` from. Rust docs make it really clear it is a
`c_int` (i32) on Unix.
Past Me also decided both leaking memory with `Box::into_raw` then
unsoundly calling `Box::from_raw` on a pointer to a stack-allocated
array was smart. Dunno why. Loser did not even leave a safety comment
smh.
* fix: use `mem::size_of` to get size of `i32`
Replace `unwrap()` on the output scale query with conditional handling.
This prevents a panic when the last output is removed and the query
temporarily returns no results + add test to cover removing all outputs.
EWMH section 8.1 requires that compositing window managers take
ownership of `_NET_WM_CM_Sn` for each screen `n` they manage (in the
case of `satellite`, this is just screen 0).
The Avalonia UI toolkit needs this atom to be owned in order to
provide transparent window support. Resolves#376.
Previously, global output offset only moved outputs if they were in
negative coordinate space. Doing so guaranteed an output on the top-most
and left-most border of the screen. This commit offsets outputs to achieve
the same goal on outputs in positive coordinate space, which matches the
output placement of `xrandr`, a placement assumption made by Krita's
tablet tool logic.
The new definition of global output offset can be thought of as drawing
the smallest possible rectangle with contains every monitor, and moving
that bounding box to (0, 0).
Despawning the output when its global was removed proved to be
overzealous, as the Dispatch of `zxdg_output_v1` still needed it for
cleanup. Instead, only the `OutputScaleFactor` element is removed, and
every surface entity with an `OnOutput` referencing the removed output,
so scaling events sent to surfaces on non-existent outputs did not panic
or use the provided scale as if an output still existed for it.
All `GlobalRemove` events sent from the server are now handled by
recording them in a new clientside `vec` and passing the identifier
returned by `create_global` (now stored by a map in the state) to
`disable_global`. `handle_globals` (the top-level function) and
`handle_new_globals` (the `InnerServerState` member function) have
swapped names to better represent their new purposes.
This enables action to be taken when globals are removed. In this case,
the desired action is to forward output removal, so that the scaling
calculation does not account for disconnected monitors in its logic.
Resolves#351.
Most of the changes are heavily inspired by the structure of Niri's
flake.nix.
- add overlay
- add formatter for nix
- remove flake-parts
- use rust-overlay only for the dev shell. end users can set `inputs.rust-overlay.follows = ""` to skip downloading it.
- add rust-analyzer and rust-src extensions in the dev shell
- filter the source in order to reduce rebuilds
- support all Linux systems that the nixpkgs flake exposes
- override VERGEN_GIT_DESCRIBE to include the git rev as well
- remove `clangStdenv` from the dev shell. I'm not sure what purpose it served. If the intention was faster linking with lld, then it's not needed anymore, now that lld has become the default linker in rust 1.90.0.
Current wine versions (with yabridge) do not provide SKIP_TASKBAR atom
so current implementation does not work at all for yabridge.
Reason SKIP_TASKBAR check was introduced because there was a edge case
with PixelComposer which spawned as popup instead of top level window.
That app spawns now normally as toplevel with both old and current wine
versions so removing the SKIP_TASKBAR check makes yabridge popups work
for any wine version.
Note:
After extensive testing wine-staging and non staging verisons they
report atoms very differenly:
wine-staging 9.21 reports all atoms in NET_WM_STATE while non stage and
anything above that report only single atom there or non at all
* feat: forward requested command-line options
The CLI now forwards the `-ac`, `-audit`, `-auth`, `-core`,
`+extension`, `-extension`, `-glamor`, `-listen`, `-nolisten`, and `-verbose` flags
to `Xwayland`. In addition, command-line flags no longer require the
display to be the first parameter. Also the `-help` and `-version` flags
were added, which print the relevant message and return 0.
The match case structure should make it easier to add new arguments if
people have use for them. For example, I chose not to add the `-ld`,
`-lm`, and `-ls` flags since they are dependent on `Xwayland`'s
compile-time flags.
Previously, a `zwp_tablet_pad_v2` `Enter` event would attempt to
initialize the clientside tablet. Since initializing the clientside
tablet is the job of `zwp_tablet_seat_v2` `TabletAdded` event, it would
be already initialized, which triggers an `expect` in
`LateInitObjectKey::init`. To remedy this, the `Enter` event instead
checks for an initialized tablet before entering, and early returns
otherwise.
* Detect WM_HINTS popup (yabridge popups fix)
Many windows popups have:
WM_HINTS(WM_HINTS) Client accepts input or input focus: False
Which is a good indicator window SHOULD be a popup.
This is true for example on yabridge plugins and some other apps.
However toplevel windows have this property True. In order to
differentiate them we check if there are no decorations on the window
(client) and this property is False.
Its applied ONLY to _NET_WM_WINDOW_TYPE_NORMAL windows since its most
generic one that comes up.
This was tested across many apps: Reaper, Ardour, Godot, MaterialMaker,
PixelOver, PixelComposer, Steam, Steam games (both windowed and
fullscreen), Fusion 9, Unity and others I have.
There are no regression seen in any of tested apps and fixes yabridge
popups.
Additionally check if MOTIF has functions that should not be in popup
Combine wmhint popup check with skip_taskbar.
wmhint is only considered to be a popup if application has skip_taskbar
atom.
Fixed edgecases so far:
BattleNet spawning as popupp
PixelComposer spawning as popup
Notably, `xcb` 1.7.0 made `XidNew::new` no longer unsafe, so remove all
of the unsafe blocks wrapping `XidNew::new` calls. Most of these were
for creating fake windows in the unit tests, but a few were in `xstate`.
`set_title` would call `update_buffer` at the end of the function, even
if the bar was explicitly not supposed to be drawn (most commonly
because the window had been fullscreened). Since `set_title` is called
outside of the decorations file, a check here made the most sense.
Resolves#310.
Ardour uses UTILITY atom all over the place for toplevel windows:
Plugins, Dialogs etc
However it does not provide any MOTIF_HINTS at all.
WeChat however uses them for popups and also provides MOTIF_HINTS with
flags 0x2 indicating that only decorations are active. MaterialMaker
also follows what WeChat is doing for right click menus.
This fix assigns UTILITY as popup ONLY if MOTIF_HINTS are provided and
functions are not active.
Couple of apps like Godot mark their windows
(_NET_WM_WINDOW_TYPE_UTILITY) with override_redirect which makes them
popup by default. Potentionally is_popup can be overriden in case MOTIF
functions exists with so no_function_motif would be false.
This fix prefers override_redirect in case that scenario comes up.
Closes#294
Dragging a pop-up surface around regularly updates it via
`SurfaceEvents::xdg_event`. This called `XConnection::set_window_dims`,
which was enqueueing many `ConfigureRequest` events. These outdated
events would still be processed by XWayland and responded to with
`ConfigureNotify`, which updated the surface to an old position,
resulting in glitchy behavior.
This fix replaces the call of `set_window_dims` in `xdg_event`, instead
inserting the new position of the window into the ECS. Then, after all
Wayland events have been read, the pending position is popped from the ECS
and used to call `set_window_dims` for each window with it.
A solution to the issue posed in #314.
The `title_pixmap` function assumed if `title` was not empty, the returned
`glyphs` from `layout_title_glyphs` would also not be empty.
`layout_title_glyphs`, however, could break before a single insertion if
`max_width` was too small. Emacs, when using `emacsclient
--create-frame`, could call `title_pixmap` with a `max_width` of 1,
causing a panic. Closes#311.
Some wine apps expect WM_STATE to be updated when mapping/unmapping
windows. Unless handled properly wine app would timeout while waiting
for update state
Fixes#302
The brief period between a window being mapped and obtaining a surface
role did not respect pop-up reconfiguration. This adds a test for that,
along with a test that the toplevel's position cannot be reconfigured
after being mapped.
I triggered the unwrap in the `Motion` case while using the color picker
in Krita. If you hold down the mouse such that the color comparison
pop-up opens and flick to it, you can sometimes enter and motion on a
stale surface. Somewhat inconsistent to trigger.
I also removed the unwrap in the `Button` event since it is logically
equivalent to the other unwrap. A few logging statements also got
changed to give wl_surface details.