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

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

0 Members and 3 Guests are viewing this topic.

Aster

  • Full Member
  • ***
  • Posts: 130
    • View Profile
Clipboard support on Linux: A few hiccups.
« on: October 03, 2014, 06:55:38 pm »
Hello all!

I've been spending the last few hours determined to get clipboard support working on Linux. You can check my progress here: https://github.com/Mischa-Alff/SFML/feature/clipboard
(NOTE: I won't push my current progress with support for X11 until it's finished. There's no point in making tiny little commits for every two lines of code)

I'm not 100% familiar with everything, so this is essentially all to the extend of my understanding. I might be wrong. God, I hope I'm wrong, but using X is a land of sadomasochism, and if I were wrong, it wouldn't be sadomasochism anymore.

The problems
  • To receive the clipboard's contents, you must request ownership of the clipboard, request its contents, and then wait for an event containing the property that points to the contents of the clipboard. (This is apparently to prevent uselessly sending data around all the time)
  • Once you've obtained ownership of the clipboard, you need to store its contents and send them to the next client who requests the data, until someone else requests ownership. (According to ICCCM sec. 2.6.1.3, you must request ownership to request contents, but not everyone follows ICCCM)

The potential solutions

Obviously, the only solution to the second one is to stick the selection sending code in the sf::WindowImplX11::processEvent function.

The solution to the first one is slightly more complex: Most software waits for a selection_notify_event in the getClipboard function, therefore driving the CPU up to 100% and sending all possible events to the event handler until it reaches a selection_*_event, then processing that event and returning the data sent in the event. The problem with this method is that it will completely block execution until it gets to the event it wants, which might be never.

References:


I'm looking for recommendations as to how I should proceed on this, what would be best for the API, and what would be best for the codebase.

Please don't reply with your ideal vision of how the clipboard API should be, without any real advice. I'm trying to solve a problem that has been plaguing me for hours, and I would like a constructive discussion on how this could be solved.

Other than that, any help is appreciated and much needed. SFML needs clipboard support.
Thanks!

« Last Edit: October 06, 2014, 06:07:06 pm by Aster »

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Re: Clipboard support on Linux: A few hiccups.
« Reply #1 on: October 03, 2014, 07:10:24 pm »
No suggestion, but a question: Will this be different/easier with XCB?

Aster

  • Full Member
  • ***
  • Posts: 130
    • View Profile
Re: Clipboard support on Linux: A few hiccups.
« Reply #2 on: October 03, 2014, 07:17:18 pm »
No suggestion, but a question: Will this be different/easier with XCB?

This is exactly the same procedure with XCB as with Xlib. The code only changes in a few places.

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Clipboard support on Linux: A few hiccups.
« Reply #3 on: October 04, 2014, 08:30:43 pm »
So from talking on IRC to help me understand this better. I would suggest the following model.

  • SFML requests and holds ownership until another application requests it.
  • When SFML has lost ownership and the user requests contents we return our cached version. (eliminates a busy wait that kills the CPU)
  • When ownership is lost SFML will put a request out again to receive ownership again.
  • Once ownership is received SFML will cache the current contents.
  • When the user requests SFML to set the contents SFML will set its own internal cache and the actual content if it has ownership - if SFML doesn't have ownership it will set an internal flag to update the actual content next time it receives ownership.
« Last Edit: October 04, 2014, 08:32:16 pm by zsbzsb »
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

Aster

  • Full Member
  • ***
  • Posts: 130
    • View Profile
Re: Clipboard support on Linux: A few hiccups.
« Reply #4 on: October 04, 2014, 09:56:34 pm »
After much more research and after a good night's sleep:
  • You don't need to own the clipboard to request data. (You shouldn't own the clipboard to request data, since you'd be requesting the data from the owner: yourself)
  • You need to own the clipboard to set its contents.
  • If the owner of the clipboard no longer exists, the contents of the clipboard disappear.
  • Ownership of the clipboard should be kept until someone else requests it. Then the burden of Mighty Clipboard Data Holder is lifted.
I'm pretty sure whoever designed this stuff was way over Ballmer Peak.

I'll add more as I go.

Juhani

  • Newbie
  • *
  • Posts: 28
    • View Profile
Re: Clipboard support on Linux: A few hiccups.
« Reply #5 on: October 05, 2014, 07:46:59 am »
Yea, I think I read somewhere that on Linux no data is actually copied to the clipboard, so I imagine that when data is requested, a pointer is provided to it in the Mighty Clipboard Data Holder's memory.

So, to provide identical behavior on all platforms, SFML must itself keep a copy of the clipboard contents when it's owned by SFML on Linux.

Aster

  • Full Member
  • ***
  • Posts: 130
    • View Profile
Re: Clipboard support on Linux: A few hiccups.
« Reply #6 on: October 05, 2014, 08:42:29 pm »
Woo! It's working! It's finally working!

I'm just cleaning up my code and commenting it all, then I'll put it up on GitHub for testing.

Aster

  • Full Member
  • ***
  • Posts: 130
    • View Profile
Re: Clipboard support on Linux: A few hiccups.
« Reply #7 on: October 05, 2014, 09:00:00 pm »
Okay, I pushed my work to Git: https://github.com/Mischa-Alff/SFML/tree/feature/clipboard

Any criticism is appreciated.
Any testing is appreciated.
Be sure to checkout the feature/clipboard branch!

Cheers!

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Re: Clipboard support on Linux: A few hiccups.
« Reply #8 on: October 06, 2014, 02:33:21 am »
Hey Aster,

I reviewed your commits and mostly directly left comments at GitHub. I've got a question regarding the X11 implementation though.

As far as I understood, you enter an event loop in getClipboard and wait for the proper message from X with the requested information (selection owner notify). Isn't there a way to subscribe to general clipboard events, handle them in the main window's event loop by caching the content, and only work with that cache in getClipboard?

The current implementation adds a lot of redundant code and one issue I can see is that we have to take a lot of attention not to forget event stuff that's present in the "main" event loop.

The Win32 implementation and the example look good so far for me, nice work. :) (Except source code format etc, see comments @ GitHub.)

Aster

  • Full Member
  • ***
  • Posts: 130
    • View Profile
Re: Clipboard support on Linux: A few hiccups.
« Reply #9 on: October 06, 2014, 07:04:00 am »
As far as I understood, you enter an event loop in getClipboard and wait for the proper message from X with the requested information (selection owner notify). Isn't there a way to subscribe to general clipboard events, handle them in the main window's event loop by caching the content, and only work with that cache in getClipboard?

Thanks for the review!

There's no such thing as "general clipboard events", you can only get these events if you request them. We could either request the contents on every call to processEvents (overhead), and have the function be semi-asynchronous (getClipboard will request that the cache is updated and return the cache, but not the new clipboard contents). The problem is that if the contents are requested too often, then you'll lock up whichever program owns the clipboard. (So if you're doing a test program at 5000FPS, X11 will probably die.)

The current implementation adds a lot of redundant code and one issue I can see is that we have to take a lot of attention not to forget event stuff that's present in the "main" event loop.

Yes! A solution is to modify WindowImplX11::processEvents() and give it the possibility to process all the events until a specific event. Or something like that. I'm new to contributing to SFML, so I didn't want to move too much code around.

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Re: Clipboard support on Linux: A few hiccups.
« Reply #10 on: October 06, 2014, 09:16:55 am »
Periodic requests don't sound like a solution indeed. God, X11 is the most annoying thing I've seen in my whole life.

Quote
Yes! A solution is to modify WindowImplX11::processEvents() and give it the possibility to process all the events until a specific event
That would definitely be a cleaner approach, i.e. the ability to wait for a specific event. This would require to have an internal event queue, though. I've almost implemented something like that for the key repeat workaround, but didn't have to in the end.

If nobody else has a good idea of working around the asynchronous clipboard stuff, I'd say let's give it a try. What do the other SFML team people say?

wintertime

  • Sr. Member
  • ****
  • Posts: 255
    • View Profile
Re: Clipboard support on Linux: A few hiccups.
« Reply #11 on: October 06, 2014, 03:17:00 pm »
I think the least intrusive way would be to not hide the asynchronous nature of the clipboard.
- Have a RefreshClipboard method that just requests to set a variable in the class that handles events, if no request is already started.
- When the variable is set in that way the event handler requests the clipboard contents once, then remembers the status of the request.
- Then if more events are received later in the normal flow of the program they are additionally checked for if the clipboard contents are there, if yes it is remembered and so it can stop checking for more clipboard events.
- The user calls some GetClipboard method, this can return either "not ready" so that the user can check on next frame again, or it can give access to the data when its there.

That way no events need to be discarded or hold back and the program can continue without getting unresponsive from delays.
Maybe the 2 methods could be even combined and rerequests ignored until the data is there, if that looks like its easier to use.
On other OS it could just give success at first try if thats possible there.

Tank

  • SFML Team
  • Hero Member
  • *****
  • Posts: 1486
    • View Profile
    • Blog
    • Email
Re: Clipboard support on Linux: A few hiccups.
« Reply #12 on: October 06, 2014, 04:30:00 pm »
If you want to keep the asynchronous nature (which is only asynchronous on Linux IIRC), then you'd probably want to introduce a new SFML event that carries the proper clipboard information.

Because calling getClipboard() until there's data "ready" feels really weird.

Aster

  • Full Member
  • ***
  • Posts: 130
    • View Profile
Re: Clipboard support on Linux: A few hiccups.
« Reply #13 on: October 06, 2014, 06:09:56 pm »
I think creating a new event is fairly un-intuitive, when all the other libraries simply have get/setClipboard functions that are synchronous.

Plus this would only be worth it on Linux, since, as Tank said, other OSes all have synchronous clipboard management.

Juhani

  • Newbie
  • *
  • Posts: 28
    • View Profile
Re: Clipboard support on Linux: A few hiccups.
« Reply #14 on: October 06, 2014, 07:34:06 pm »
Typically the clipboard is accessed when the computer user wants to copy/paste text from 1 program to another. A ~0.5 sec busy wait would be hardly noticeable.