Bug 474686 - Setting a value to Clipboard via a button in an unfocused window does not work.
Summary: Setting a value to Clipboard via a button in an unfocused window does not work.
Status: RESOLVED FIXED
Alias: None
Product: kwin
Classification: Plasma
Component: wayland-generic (show other bugs)
Version: unspecified
Platform: Other Linux
: NOR normal
Target Milestone: ---
Assignee: KWin default assignee
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-09-19 09:30 UTC by zhangtingan@uniontech.com
Modified: 2024-06-04 09:00 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments
demo (3.40 KB, application/x-7z-compressed)
2023-09-21 07:39 UTC, zhangtingan@uniontech.com
Details

Note You need to log in before you can comment on or make changes to this bug.
Description zhangtingan@uniontech.com 2023-09-19 09:30:11 UTC
SUMMARY
***
I noticed that in Wayland protocol, when I perform a copy operation in a program, the protocol performs some data operations through `SetSelection` function.But when I set `Qt::WindowDoesNotAcceptFocus` via Qt in this program and write data via `setText` operation in `QClipboard`, the function `updateSelection` in Wayland will not send the `setSelection` signal. I found that the following code is causing the signal not to be sent.
`*globalKeyboard.focus.surface->client() == dataDevice->client()`.

***


STEPS TO REPRODUCE
1. Create a Qt window, set the `Qt::WindowDoesNotAcceptFocus` property
2. Create a button in which the button function is to set a value to the QClipboard
3. Clicked the button and found it impossible to paste in other apps

OBSERVED RESULT
Write values cannot be pasted by other applications

EXPECTED RESULT
Write values that can be pasted by other applications

may i ask why this judgment is necessary, and if I want my app to write clipboard data without getting focus, is there an alternative way I can do it?
SOFTWARE/OS VERSIONS
Linux/KDE Plasma: 
(available in About System)
KDE Plasma Version: 
KDE Frameworks Version: 
Qt Version: 5.11.3

ADDITIONAL INFORMATION
Comment 1 Vlad Zahorodnii 2023-09-20 06:51:50 UTC
It's a lazy way to determine that the passed serial is valid. Only focused client is going to have a serial that can be used to set the selection.

> Create a Qt window, set the `Qt::WindowDoesNotAcceptFocus` property

As far as I know, an xdg_toplevel cannot influence whether it should accept focus or not. It can only change the input shape, but it's controlled by a different flag.
Comment 2 zhangtingan@uniontech.com 2023-09-20 07:54:34 UTC
(In reply to Vlad Zahorodnii from comment #1)
> It's a lazy way to determine that the passed serial is valid. Only focused
> client is going to have a serial that can be used to set the selection.
> 
> > Create a Qt window, set the `Qt::WindowDoesNotAcceptFocus` property
> 
> As far as I know, an xdg_toplevel cannot influence whether it should accept
> focus or not. It can only change the input shape, but it's controlled by a
> different flag.

yes, i found that `Only focusedclient is going to have a serial that can be used to set the selection`.
But I don't really understand what you mean by this, so let me describe my problem in detail.

I have written a program through which I want to click a button to enter data for another application.

The way it works now is: create a window set the `Qt::WindowStaysOnTopHint |Qt::WindowDoesNotAcceptFocus` property so that the window stays on top and the input focus is retained in the other program, then click the button and via `QClipboard->setText` put the data into the `selection` in the system by `QClipboard->setText`. However, I find that the following code in `kwayland` does not work at this point.

`QObject::connect(dataDevice, &DataDeviceInterface::selectionChanged, q, [this, dataDevice]], [this, dataDevice]].
        [this, dataDevice] {
            if(keys.focus.surface && dataDevice && dataDevice->client() == keys.focus.surface->client()) {
                updateSelection(dataDevice->selection(), true);
            }
        }
    );`

When I call `setText` in my Qt app, `setSelection` is called in wayland, which then triggers Kwayland's callback function, but at this point, the source of the data is the program I've written, but keys.focus.surface is another app, causing the selection not to be updated.

Maybe the kwin in my system has been modified, resulting in a difference from the original design.

I will also try to test this on a native KDE system, and if necessary, I'll attach a demo I've written!
Comment 3 zhangtingan@uniontech.com 2023-09-21 07:39:36 UTC
Created attachment 161774 [details]
demo

Run the demo, let the input focus on any application, click the button in the demo, it will output an "ok" at the other application's focus. But it won't actually
Comment 4 David Edmundson 2024-06-04 09:00:26 UTC
Kwin now allows any app to change clipboard without focus.