It seems https://github.com/pop-os/cosmic-comp/pull/1638 caused an issue
in cosmic-workspaces, where if there are multiple toplevels, when
dragging a toplevel, the drag surface would appear in capture for other
toplevels.
For now, omit drag surface in toplevel capture without `draw_cursor`.
Though I guess ultimately we do want it for metadata cursor capture in
the portal, but not in cosmic-workspaces? Maybe the protocol needs some
additional option for this...
`CosmicMapped::cursor_positon` may have worked previously, but doesn't
now.
This is based on the code used for seperate cursor capture sessions.
Maybe this could be consolidated in some way.
But this seems to work. Including for rotated outputs.
This fixes two issues:
- The `area` passed to `to_buffer()` should match the dimensions of the
output/etc. being captured, rather than coming from the damage rect
size.
- The transform needs to be inverted.
Previously, rotated outputs could cause a crash
`xdg-desktop-portal-cosmic`, since the compositor was passing negative
coordinates in `damage`, and the client used the same in
`damage_buffer`. This was causing
https://github.com/pop-os/xdg-desktop-portal-cosmic/issues/165.
The portal crash no longer occurs, and logging in
xdg-desktop-portal-cosmic shows damage rects that match expectation
while moving the cursor over different corners of a workspace.
The `id` is defined to be sent only once, on creation of the handle or
later. And only for workspaces that are "likely to be stable across
multiple sessions".
Set we add an `id` initially for pinned workspaces, and add one when the
workspace is pinned.
The `id` is not supposed to be human readable, so we just use a random
value.
Adding anything else to this tuple is awkward; defining a simple struct
makes this cleaner.
This also adds a `sync` property, which will come in handy later.
Containing simply the same-named argument that was passed to
`submit_buffer`.
It doesn't seem like there's really a need to have `Err(_)` and `Ok(None)`.
`Err(_)` means the set exists for the output, but doesn't have the
appropriate workspace index. It's a bit odd that the set not even
existing becomes `Ok(None)`.
Instead, just return `Err(InvalidWorkspaceIndex)` in either case.
I hoped to split this up into multiple commits, but the api
changes to `shell/workspace.rs` were to invasive to feasibly do this.
Here is a rough list of changes:
- Fullscreen windows aren't mapped to other layers anymore
- This they need their own logic for:
- Sending frames
- Dmabuf Feedback
- Primary outputs
- On commit handlers
- cursor tests
- They get their own unmap/remap logic
- They get a new restore state similar to minimized windows
- Refactored the minimized window state to reuse as much as possible
here
- They need to be part of focus stacks, which means adjusting them
to a new type `FocusTarget` as they previously only handled
`CosmicMapped`.
- Various shell handlers (minimize, move, menu) now have dedicated
logic for fullscreen surfaces
- This was partially necessary due to relying on CosmicSurface now,
partially because they should've had their own logic from the
start. E.g. the context menu is now reflecting the fullscreen
state
- Fullscreen windows may be rendered behind other windows now, when they
loose focus.
- This needed changes to input handling / rendering
Similar to the change in https://github.com/pop-os/cosmic-comp/pull/780,
but also updates it to be a little clearer than just an uncommented `age
= 0` line.
Ideally we want some robust system to re-use the offscreen buffer (but
not allocate more buffers indefinitely if the client doesn't capture
with the same `wl_buffer`).
It seems previously, workspace migration due to output add could result in
a workspace being removed from a group, but not added to the new group
for existing clients, because the workspace group creation didn't happen
until `done`. And `send_workspace_to_client` didn't send
`workspace_enter` except when a workspace instance is newly created.
That logic worked with the old protocol, but now a workspace can be
moved to a different group.
Seems to fix the issue with workspaces disappearing from the workspaces
view in https://github.com/pop-os/cosmic-comp/issues/1470. I don't seem
to be able to reproduce the panel auto-hide issue, but have seen it in
the past. So it may or may not be prevented from happening now.
A solution for https://github.com/Smithay/smithay/issues/1714.
With this, the lock screen is able to get keyboard focus normally, but
focus then reverts to the XWayland grab surface. This can be tested with
the example client from the issue.
Adding a new variant of `KeyboardFocusTarget` is annoying. Maybe it
could map to a different variant of the enum. But it presumably needs to
handle any `wl_surface` XWayland uses. (Override redirect surfaces?
Subsurfaces?) This seems as good as anything for now.
Add more sophisticated code to handle the primary node disappearing.
Also overhaul the selection logic to respect our allow/deny-list and
prefer devices with built-in connectors before using the boot gpu.
This will also allow triggering a primary node switch at runtime
for debugging purposes in the future.
Previously, `Frame` was stored in KMS frame udata, but in some cases the
udata was dropped without a capture happening, and `Frame` did not
implement `Drop`, so `fail` was never sent.
Instead, rename `DropableFrame` to `Frame` and `Frame` to `FrameRef`, so
we can have a single instance of `Frame`, that will send `fail` on drop.
This guarantees either `.success` or `.fail` are send, as long as its
not leaked.
This seems to fix https://github.com/pop-os/cosmic-comp/issues/1305.
xdg-desktop-portal-cosmic prints an error, buy retries (as it should for
an `Unknown` error; though maybe there should be a retry limit) and the
session continues working.
(Not sure if it should be sending `failed`, or queing it with the next
frame so it can send `success` to the client, but this works and is
desirable as a failsafe anyway.)
`Session` and `CursorSession` are similiarly updated.
`.fail()`, `.success()`, and `.stop()` now consume
`Frame`/`Session`/`CursorSession`. So to stop a session, it is now
necessary to call `.remove_session()`, but then simply dropping with
send `.stop()`.
Factoring out some `Request::Capture` handling into a `capture_frame`
function seems to clean up error handling and such a bit.
Adds support for cosmic-workspace-v2 pin, unpin, move_after, and
move_before requests.
Both features need some work with workspaces span displays mode, so that
will need more fixes later.
We also want to generate a unique id for pinned workspaces to send in
the ext-workspace-v1 protocol. But that isn't a strict requirement for
anything. So I haven't yet fully implemented that. We'll also want to
persist other things, like workspace naming when that's added.
Overall, though, with separate workspaces per display, this is working
pretty well.
This is slightly simpler, if there's not some reason I'm missing to do
this as it was previously done. And in particular provides a cleaner
API (if we wanted to move this to Smithay; perhaps without the Cosmic
extension).
But it also should be more correct. Presumably if a client (unusually)
had multiple components with their own `ext_workspace_manager_v1`
instance, they should have their own queues, and
`ext_workspace_manager_v1::commit` should be independent.
Inevitably, there's a racy element to multiple components trying to
update the workspace state like this, but it should behave the same as
two clients with separate connections.
(This is different from `CompositorClientState`, since the commit queue
there is fundamentally tied to the client, and different components with
their own compositor instance way have related surfaces.)