* 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`
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.
* 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
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
The clipboard and primary selections previously used the same atom to
store TARGETS when queried for them by `handle_target_list`. When a
program requests both selections simultaneously, problems such as one
selection using the target list of the other, then deleting it and
requiring the second target to get the selection targets again could
occur. This was observed when using `wl-clip-persist` and could result
in selection desyncs.
This change gives a unique atom to each primary and clipboard selection
targets so they no longer compete over the same property. It also adds
updates to the `copy_from_x11` intergration to test for this issue.
These simple decorations will be rendered only when the host compositor doesn't
support server side decorations and the X11 window does not render its own
decorations.
Closes#31
The catch-all case of `handle_client_message` now logs the atom's name
instead of its opaque atom id.
`get_atom_name` now warns there was an error and returns a filler name.
Since most the use of `get_atom_name` is in logging, this makes those
logs easier to read.
The integration tests now use `formatted_timed_builder` logger
constructor, which should unify the look of logs between the integration
tests and the main binary.
Due to an oversight, if `XState` had both a valid primary selection
and a valid clipboard selection, `handle_selection_property_change`
would early return after `check_for_incr` determines the primary selection
existed but was not the recipient of the `PropertyNotifyEvent`, preventing
INCR events from ever reaching the clipboard. An addtion to the
`incr_copy_from_x11` integration test validates this fix.
Also fixed was a missing check in `WaylandSelection`'s `check_for_incr`
to confirm the property requesting more data is indeed the property the
selection is responsible for. I could not figure out how to write an
integration for this mistake, but it is obvious enough in hindsight.
Resolve Clippy's `too_many_arguments` lint on
`handle_selection_request` by removing the `success` and `refuse`
parameters and returning a bool indicating which needs to be run.
Use the helper functions defined last commit to simplify
`incr_copy_from_x11`
Reduce the `match` statement checking if the target is the TARGET
atom to an if statement. Although using `match` statements as
`if`/`else if`/`else` chains occur elsewhere, this one is both only 2
cases, and already of particular relevance to the current work.
Refactor `paste_impl` to be much easier to read. I did this code algebra
way back while investigating #142, but since I never figured that out,
the change has just been sitting in my stash.
refactor: simplify paste_data logic, some unnests
Since the connection handshake establishes the most data a request can
send, if the data length exceeds that limit, we can follow ICCCM 2.7.2
sending the INCR property and continuing to send data via PropertyNotify
events.
To test the changes, we create `XState::set_max_req_bytes` to forcefully
trigger the INCR mechanism in integration test runs with a constant,
substantially less amount of data.
I found an oversight where trying to transfer too much data (16 MiB
in my case) from a Wayland selection to an X window causes the X
connection to be unable to poll the event with a `ClosedReqLenExceed`
error.
To replicate, start `xwls`, use `wl-copy` to copy more data than the
`maximum-request-size` to the Wayland selection, then attempt to
transfer that selection to an X program. I found this easy to do
transferring a large, random `.bmp` file to Krita by creating its new
image from clipboard functionality.
This test replicates the observed behavior and obtains the same
panic, to be used as a starting point for implementing incremental
selections from Wayland to X.
xcb-util-cursor made another patch release to revert back to Rust 2021
edition, so we bump to that.
Also create a function, `timespec_from_millis` to make creating
`Timespec` for using in `poll` calls a lot more ergonomic.
Also includes some light refactoring of the popup flow in general
and trimming down some unused code.
I suspect this may cause some windows to unexpectedly become popups when they
otherwise shouldn't, but that's a bridge we'll cross when we get there.
Fixes#110 and #112.
Satellite will now force Xwayland to always render with the native
display resolution, and just scale surface sizes accordingly. As a result,
applications won't really respect DPI, but this can be adjusted through
the same means as with normal X11.
Part of #28.
Found a good way to avoid both an extra function to RunData and make calling `xwayland_exit_code` in other RunData types *less* prone to memory violations. Having a function with a non-empty default implementation being overridden by an empty implementation felt too awkward.
Seems some applications don't expect their popups to be unmapped without
their consent, so they make act strangely, but at least it doesn't
crash.
Fixes#117
Before, every time the clipboard selection changed, satellite would copy
everything on it and force itself to be the clipboard owner, regardless
of X11 or Wayland. Now, satellite is only the owner when the clipboard
owner comes from Wayland, and uses the XFixes extension to watch for
changes in clipboard ownership X11 side. Satellite also now avoids
copying all of the clipboard contents into memory every time, instead
copying directly on request. This is a pretty big change, but should
hopefully help make the clipboard more stable.
Also added some misc test cleanup/using helper functions where possible.
Using the XFixes extension may also end up being necessary for
implementing drag and drop, so it's good the infrastructure is there
now.