Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Clipboard support on Linux: A few hiccups.  (Read 88077 times)

0 Members and 6 Guests are viewing this topic.

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Re: Clipboard support on Linux: A few hiccups.
« Reply #15 on: October 06, 2014, 07:46:07 pm »
I see it like you, the delay (if it's noticeable at all...) is alright, and the functions to set and get the clipboard content are much more intuitive and work as expected.

I'd like to take a look at a clipboard manager though. I wonder if they periodically poll or wait for specific events. Will read some source code later.

If changing the event pump is avoidable, I'd like to suggest such a solution.

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Re: Clipboard support on Linux: A few hiccups.
« Reply #16 on: October 07, 2014, 09:03:25 am »
I've checked some clipboard managers and SDL. The clipboard managers use GUI toolkit functions, like from GTK or Qt, so that's abstracted. SDL does poll.

So I guess the only sane solution is to add an event queue and wait for the clipboard reply. :(

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Clipboard support on Linux: A few hiccups.
« Reply #17 on: October 07, 2014, 09:38:43 am »
I checked Qt, it does a blocking polling too.
Laurent Gomila - SFML developer

Aster

  • Full Member
  • ***
  • Posts: 130
    • View Profile
Re: Clipboard support on Linux: A few hiccups.
« Reply #18 on: October 08, 2014, 04:48:52 pm »
Theoretically, getting the clipboard is quite fast, as long as the selection owner has a quick response (which is not guaranteed). This is why the current implementation on X11 has a 1-second time limit, and if that isn't met, it returns the cache.

Getting the clipboard is totally possible in a static function etc. It's setting the clipboard in a static function that's nearly impossible. Since you can't give ownership of the selection to another window, you're stuck with it and the requirement to send its contents to anybody who requests them, until someone else requests ownership. Either we could make the setClipboard function forking, like xclip does, and thus spawning an entire thread just for the sake of responding to events (until we get a SelectionClear event), or we could make it blocking and have the program wait an undetermined amount of time until the hidden window's ownership of the clipboard has been lifted.

As for performance, I don't know about you, but I easily laugh and criticize software when simple things such as clipboard usage make the whole thing lock up for even half a second. It shouldn't happen, and it doesn't have to happen, either. And if we're talking about a game, which should run at 30/60/120 FPS, having the framerate drop to 10 or 20 FPS (stutter) because the game used the clipboard is pretty bad.


I ran some tests, in microseconds (us), with 1000000 samples, on my i7 4770 (per call):
Code: [Select]
Times (min, max, avg): Get Clipboard (6, 36462, 90), Set Clipboard (15, 198679, 215).
The current method thus doesn't seem to pose a performance issue.


Juhani

  • Newbie
  • *
  • Posts: 28
    • View Profile
Re: Clipboard support on Linux: A few hiccups.
« Reply #19 on: October 08, 2014, 10:13:04 pm »
I think spawning a new thread for handling the clipboard window is the lesser evil of these two. Clipboard ownership probably won't be requested until the user tries to copy something in another program, so a blocking setter would cause the program hang until the user gives up and starts doing something else. Requiring the user to copy something in another application to make the program responsive again is bad.

With a blocking setter, the programmer would have to create a new thread anyway just for calling the setter in order to keep the app responsive.

Aster

  • Full Member
  • ***
  • Posts: 130
    • View Profile
Re: Clipboard support on Linux: A few hiccups.
« Reply #20 on: October 08, 2014, 10:19:26 pm »
I think spawning a new thread for handling the clipboard window is the lesser evil of these two.  Clipboard ownership probably won't be requested until the user tries to copy something in another program, so a blocking setter would cause the program hang until the user gives up and starts doing something else. Requiring the user to copy something in another application to make the program responsive again is bad.

I only suggested it as a potential solution to show how ridiculous a potential solution would be. There is no real, simple solution to this, and the kinds of workarounds I suggested are purely to reinforce this point.

If somehow dedicating a thread to the clipboard of all things seems sane to everyone, then that's the method we'll go with, but I think that's utterly insane and a waste of resources.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Clipboard support on Linux: A few hiccups.
« Reply #21 on: October 08, 2014, 10:38:55 pm »
Is there a possibility to check in a non-blocking call whether the clipboard is ready?

If so, an asynchronous (but single-threaded) algorithm would still be possible: setClipboard() just issues the order and caches the text. In regular intervals (probably in a window event loop), the clipboard is checked for availability, and set if available.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Juhani

  • Newbie
  • *
  • Posts: 28
    • View Profile
Re: Clipboard support on Linux: A few hiccups.
« Reply #22 on: October 08, 2014, 10:43:30 pm »
The problem is that SFML must also send the clipboard contents to other applications when they request it.

Aster

  • Full Member
  • ***
  • Posts: 130
    • View Profile
Re: Clipboard support on Linux: A few hiccups.
« Reply #23 on: October 09, 2014, 07:57:22 am »
Is there a possibility to check in a non-blocking call whether the clipboard is ready?

If so, an asynchronous (but single-threaded) algorithm would still be possible: setClipboard() just issues the order and caches the text. In regular intervals (probably in a window event loop), the clipboard is checked for availability, and set if available.

That's what's being done right now. This means a non-static member function, and apparently that's wrong and makes for a horrible API. If not for this, the implementation on X11 is finished. Setting the clipboard doesn't require any event loops, it's just that to set the clipboard, you must own the clipboard, and if you own the clipboard, you need to respond to people requesting the clipboard's contents. The clipboard is thus always available, since all you're doing when you set it is taking ownership and setting your cache. No waiting involved.

Take a look at https://github.com/Mischa-Alff/SFML/blob/feature/clipboard/src/SFML/Window/Unix/WindowImplX11.cpp#L589
There's no waiting in there. All the clipboard-ownership burden stuff is in WindowImplX11::processEvent(); https://github.com/Mischa-Alff/SFML/blob/feature/clipboard/src/SFML/Window/Unix/WindowImplX11.cpp#L1352
And thus that code gets a chance to be run at regular intervals, which is what is needed.


The problem is that SFML must also send the clipboard contents to other applications when they request it.

Can you at least try to contribute to the discussion if you're going to post?

Juhani

  • Newbie
  • *
  • Posts: 28
    • View Profile
Re: Clipboard support on Linux: A few hiccups.
« Reply #24 on: October 09, 2014, 01:32:29 pm »
A member function would be OK to me. After all, if you don't have a window, then where would the user paste the clipboard contents? or whence would he copy to clipboard?

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Clipboard support on Linux: A few hiccups.
« Reply #25 on: October 09, 2014, 06:04:36 pm »
A window member function is not ideal for the reasons outlined in the pull request: having a window is an platform-dependent implementation-detail resulting from X11's questionable design. As a SFML user, it does not make sense to associate the clipboard with a window (what if none or multiple ones are available?). I also find it standing to reason to have a separate sf::Clipboard class.

What I meant is a sf::Clipboard::setText() function, sorry for not being clear. You say it takes time to set the clipboard's contents because one first has to get ownership of it, right? What I meant is that you don't immediately do that, but somewhere in the background. Is it not possible to get ownership of the window in a non-blocking way (i.e. asynchronously by requesting it and checking later whether we've already gotten it)?

Has somebody already measured how severe this delay is in practice?

In case a thread and a hacked window is the only possibility: there's still no need to impose that overhead on every SFML application. All that stuff could be lazily initialized upon first clipboard usage.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Clipboard support on Linux: A few hiccups.
« Reply #26 on: October 09, 2014, 06:07:10 pm »
And to incorporate Tank's post on GitHub:
Quote from: Tank
I think it's absolutely alright to put the event handling code in processEvent. Normal GUI applications are built around a message pump that does exactly that all the time. And since processEvent is something that gets closest to such a message pump, we should use it.

So my proposal is:
  • For getting contents, run an event handler for max. 1 second and put unhandled events to a new internal queue, so that they can be processed later in processEvents.
  • For setting contents, do the X11 selection request work and respond to content requests in processEvents.
  • Use an internal and invisible window to handle the clipboard stuff and use static clipboard functions. To be honest, I don't like this very much, but it indeed seems like to be the best solution to workaround X11's stupid design decisions.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Juhani

  • Newbie
  • *
  • Posts: 28
    • View Profile
Re: Clipboard support on Linux: A few hiccups.
« Reply #27 on: October 09, 2014, 10:05:36 pm »
Aside from possible performance issues and simpler implementation, I know nothing that would favour the member function, but I don't believe that it would cause any problems either.

I claim that there is a window if the application needs clipboard access. Here's my rationale:

1. An application doesn't need clipboard access if the user isn't copy/pasting something.
2. The user can't copy/paste if there isn't a window to copy/paste from/to.
----------------------------------------------------------------------------------------------------------
Therefore, the application doesn't need clipboard access if there isn't a window.
Which is to say, applying transposition, that there is a window if the application needs clipboard access.
If you disagree with this, then which is the premise you disagree with?

As for the case with multiple windows, the window would be decided by the user when calling the member function, even
*this
.

Aster

  • Full Member
  • ***
  • Posts: 130
    • View Profile
Re: Clipboard support on Linux: A few hiccups.
« Reply #28 on: October 09, 2014, 10:33:52 pm »
What I meant is a sf::Clipboard::setText() function, sorry for not being clear. You say it takes time to set the clipboard's contents because one first has to get ownership of it, right? What I meant is that you don't immediately do that, but somewhere in the background. Is it not possible to get ownership of the window in a non-blocking way (i.e. asynchronously by requesting it and checking later whether we've already gotten it)?

Has somebody already measured how severe this delay is in practice?

I'm sorry for not being clear, too. Here's my attempt at being clear:

X11 has a thing called selections. There are three notable ones: PRIMARY, SECONDARY and CLIPBOARD. Most modern applications use the CLIPBOARD selection.

To obtain, or get the contents of the CLIPBOARD selection, you must request a conversion to the desired format to the X server, which forwards that request to whoever owns the clipboard. Then, whoever owns the clipboard checks if it's even possible to convert the selection to the requested format, and essentially responds directly to the requestor by sending them an event that contains information on the conversion as well as where to get the requested data. This response is usually very quick, so you can expect to receive it in less than one second and almost never miss it.

To set the contents of the CLIPBOARD selection, you must request ownership of the selection. This is immediate, as the X server does not wait for approval from the current owner to do this. You then update your cached contents of the clipboard, and you're done.

Actually, I lied. You're not done. You're the owner of the clipboard.
Once you own the clipboard, you need to respond to all incoming events requesting a conversion (remember what I mentioned about getting the contents? We're the ones doing the conversion now). This is the main reason for which the function can't be blocking. These events need to be processed often enough that the requestor doesn't lock up waiting for the CLIPBOARD selection's contents (Google Chrome tabs will do this). This is being done in the processEvent function as of writing this.

There are no issues with performance with the current implementation, just look at the benchmarks I did.

The API we're using is completely fine. SDL and GLFW use it, and nobody has ever complained. Yes, sf::Clipboard::setString() would be nice, but it's pushing things a lot and seriously not worth the effort just because someone isn't happy with SFML's API being exactly the same as its competitors'.
« Last Edit: October 10, 2014, 05:20:56 pm by Aster »

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Re: Clipboard support on Linux: A few hiccups.
« Reply #29 on: October 10, 2014, 08:48:46 am »
Quote
Yes, sf::Clipboard::setString() would be nice, but it's pushing things a lot and seriously not worth the effort just because someone isn't happy with SFML's API being exactly the same as its competitors'.
GLFW indeed does it like that, but SDL doesn't.

However, the static functions are indeed tricky. What comes into my mind at first is using an invisible window. The problem with that is: Where and when do you handle X's clipboard events, in case an application requests the content? You can't process that in another window, because it won't receive them (if there's a way to do that, it would greatly help).

Without a lot of hacks and code, it's probably not possible to avoid using a member function in sf::Window.

(And to be honest: The more I think about it, X's design isn't as bad as I thought; the conversion is very flexible and the non-blocking part will allow heavy conversion operations without blocking the target application.)

 

anything