Could it be that TheClipboard object cannot be used with Threading on Linux?

Hello,
I’m trying to monitor the clipboard on ubuntu using the TheClipboard object.
Everything is ok when looping within the main thread but it fails
when using a different thread.
The different thread doesn’t do any gui related stuff, it just reads the clipboard and in
case of a change it calls the function to let the gui know about the changes.
But I do get weird results like App hungs, Messages like (the bolded ones)
[pid:15453 ] sys.version:2.7.12 (default, Nov 19 2016, 06:48:10)
[pid:15453 ] [GCC 5.4.0 20160609]
[pid:15453 ] wx.version():3.0.2.0 gtk2 (classic)
[pid:15453 ] platform.release():4.4.0-72-generic
[pid:15453 ] platform.linux_dist():(‘Ubuntu’, ‘16.04’, ‘xenial’)
[pid:15453 ]
[pid:15453 ] (clipboard_history.py:15453): Gdk-CRITICAL **: IA__gdk_window_get_origin: assertion ‘GDK_IS_WINDOW (window)’ failed
[pid:15453 ]
[pid:15453 ] (clipboard_history.py:15453): Gdk-CRITICAL **: IA__gdk_window_get_origin: assertion ‘GDK_IS_WINDOW (window)’ failed
[pid:15453 ] >>>>> self.read_clipboard()
[pid:15453 ] >>>>> IsSupported?
[pid:15453 ]
[pid:15453 ] (clipboard_history.py:15453): Gdk-CRITICAL **: IA__gdk_window_get_origin: assertion ‘GDK_IS_WINDOW (window)’ failed
[pid:15453 ] >>>>> opening TheClipboard
[pid:15453 ] >>>>> GetData
[pid:15453 ] [xcb] Unknown sequence number while processing queue
[pid:15453 ] [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[pid:15453 ] [xcb] Aborting, sorry about that.
[pid:15453 ] python: …/…/src/xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost’
failed.
[pid:15453 ] process ended

I tried using wx.CallAfter as well as using pub.sendMessage to announce the changes but the problem persists.

Is this a known issue?

Attached a little demo program.

Thank you
Claudia

clipboard_history.py (4.81 KB)

I didn't look at your code, but I've seen the X+threads errors
recently.

I attached a bit of code that has been working well for me. If
you try it and it works, let me know (evidence beyond my current
testing).

Probably obvious, but the fragment should go at/near top of imports,
before wx or anything using X.

Good luck,
Ed Hynan

threads.py-stub (1.81 KB)

···

On Tue, 11 Apr 2017, Claudia Frank wrote:

Hello,
I'm trying to monitor the clipboard on ubuntu using the TheClipboard object.
Everything is ok when looping within the main thread but it fails
when using a different thread.
The different thread doesn't do any gui related stuff, it just reads the clipboard and in
case of a change it calls the function to let the gui know about the changes.
But I do get weird results like App hungs, Messages like (the bolded ones)

[pid:15453 ] sys.version:2.7.12 (default, Nov 19 2016, 06:48:10)
[pid:15453 ] [GCC 5.4.0 20160609]
[pid:15453 ] wx.version():3.0.2.0 gtk2 (classic)
[pid:15453 ] platform.release():4.4.0-72-generic
[pid:15453 ] platform.linux_dist():('Ubuntu', '16.04', 'xenial')
[pid:15453 ]
[pid:15453 ] (clipboard_history.py:15453): Gdk-CRITICAL **: IA__gdk_window_get_origin: assertion 'GDK_IS_WINDOW (window)' failed
[pid:15453 ]
[pid:15453 ] (clipboard_history.py:15453): Gdk-CRITICAL **: IA__gdk_window_get_origin: assertion 'GDK_IS_WINDOW (window)' failed
[pid:15453 ] >>>>> self.read_clipboard()
[pid:15453 ] >>>>> IsSupported?
[pid:15453 ]
[pid:15453 ] (clipboard_history.py:15453): Gdk-CRITICAL **: IA__gdk_window_get_origin: assertion 'GDK_IS_WINDOW (window)' failed
[pid:15453 ] >>>>> opening TheClipboard
[pid:15453 ] >>>>> GetData
[pid:15453 ] [xcb] Unknown sequence number while processing queue
[pid:15453 ] [xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[pid:15453 ] [xcb] Aborting, sorry about that.
[pid:15453 ] python: ../../src/xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
[pid:15453 ] process ended

I tried using wx.CallAfter as well as using pub.sendMessage to announce the changes but the problem persists.

Is this a known issue?

Attached a little demo program.

Thank you
Claudia

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--

The late rebellion in Massachusetts has given more alarm than I think it
should have done. Calculate that one rebellion in 13 states in the course
of 11 years, is but one for each state in a century and a half. No country
should be so long without one.
-- Thomas Jefferson in letter to James Madison, 20 December 1787

I believe TheClipboard should be considered GUI functionality and you shouldn't call it from anything but the main thread.

Scott

···

On Tue, 11 Apr 2017, Claudia Frank wrote:

I'm trying to monitor the clipboard on ubuntu using the TheClipboard object.
Everything is ok when looping within the main thread but it fails
when using a different thread.
The different thread doesn't do any gui related stuff, it just reads the
clipboard and in
case of a change it calls the function to let the gui know about the
changes.
But I do get weird results like App hungs, Messages like (the bolded ones)

Agreed. Clipboard functionality is tightly integrated with the UI libraries on all the platforms.

-- Robin Dunn
Software Craftsman
···

http://wxPython.org

Hello Ed,

thank you very much for the hack.
From the tests I’ve done so far everything looks ok on my setup.
(and I definitively will do more tests and let you when finding an issue)

But from the responses from Scott Talbert and Robin Dunn
as well as the comments in the code you posted, I’m a bit concerned
that this could either break when updating OS/GTK or wxPython etc…
( I guess I also need to dig deeper into the X11 stuff for better understanding)

Nevertheless, very much appreciated and I can’t thank you enough.

Cheers
Claudia

Thank you, Scott and Robin
for your suggestions as well.

Is there a way to identify which parts of wx are considered not to be used in such a case?
I’m looking for a way to identify if this is either an issue about my programming or about my concept :wink:
Maybe something I should reread at https://wxpython.org/Phoenix/docs/html/index.html ?

Thank you
Claudia

Claudia Frank wrote:

Is there a way to identify which parts of wx are considered not to be
used in such a case?

Yes - consider the whole library to not have thread safety and coordinate access to it appropriately. To my knowledge there's no document which will describe the specific parts of wx that can and can't be used by secondary threads - such a document would be quite difficult to create because it often differs by platform. If you just assume that accessing any wx functionality from a secondary thread isn't allowed, your life will be a lot easier even if this means writing more code upfront.

Heres what the official wxWidgets documentation has to say about it:

> When writing a multi-threaded application, it is strongly recommended that no secondary threads call GUI functions. The design which uses one GUI thread and several worker threads which communicate with the main one using events is much more robust and will undoubtedly save you countless problems (example: under Win32 a thread can only access GDI objects such as pens, brushes, device contexts created by itself and not by the other threads).

From:
http://docs.wxwidgets.org/3.1.0/overview_thread.html

Alternatively, in this case, you could just access the clipboard using the native platform's facilities directly rather than going through wx. I know that on Win32 at least, monitoring clipboard changes is much more straight forward (and less error-prone) if you set up a clipboard listener through the Win32 API instead of trying to hack something together using wx. If cross-platform code is important to you, this might not be the best approach, but if you're writing something only for one platform or only for yourself, it might save you the headache.

···

--
James Scholes
http://twitter.com/JamesScholes

Hello Ed,

thank you very much for the hack.
From the tests I've done so far everything looks ok on my setup.
(and I definitively will do more tests and let you when finding an issue)

But from the responses from Scott Talbert and Robin Dunn
as well as the comments in the code you posted, I'm a bit concerned
that this could either break when updating OS/GTK or wxPython etc...

Please do listen to what Scott Talbert and Robin Dunn (and others) have
said; don't do anything with wx outside of the main thread except
use wx.PostEvent() -- so if another thread must trigger something
in wx, define an event type and post it to an event handler (that
runs in the main thread, of course) and let the handler take action.

The fragment I posted addresses an issue that is outside/beyond
wxPython/wxWidgets, or GTK, or Python -- the issue that applications
that use libX11 should call XInitThreads() if they are multithreaded.

Web search the '[xcb] ...' messages you saw and you'll soon find
that this is a frequent problem, and not an issue with wxPython/GTK
specifically.

In my case, using wxMediaCtrl, w/o that hack it is so unstable it's
unusable; with the hack I can bang on it hard -- that problem,
at least, is fixed.

( I guess I also need to dig deeper into the X11 stuff for better understanding)

Nevertheless, very much appreciated and I can't thank you enough.

You're welcome.

Cheers
Claudia

-Ed Hynan

···

On Wed, 12 Apr 2017, Claudia Frank wrote:

--

The late rebellion in Massachusetts has given more alarm than I think it
should have done. Calculate that one rebellion in 13 states in the course
of 11 years, is but one for each state in a century and a half. No country
should be so long without one.
-- Thomas Jefferson in letter to James Madison, 20 December 1787

Please do listen to what Scott Talbert and Robin Dunn (and others) have

said; don’t do anything with wx outside of the main thread except

use wx.PostEvent() – so if another thread must trigger something

in wx, define an event type and post it to an event handler (that

runs in the main thread, of course) and let the handler take action.

I certainly will.

The fragment I posted addresses an issue that is outside/beyond

wxPython/wxWidgets, or GTK, or Python – the issue that applications

that use libX11 should call XInitThreads() if they are multithreaded.

Web search the ‘[xcb] …’ messages you saw and you’ll soon find

that this is a frequent problem, and not an issue with wxPython/GTK

specifically.

I see, thank you for clarification.

Cheers
Claudia

Hello James,

thank you to you as well.
I do see, that supporting multiple platforms comes with
… don’t know how to say … drawbacks (not exactly but I guess you know what I mean.)
I wanted to avoid using ctypes because of the cross platform code.
Currently I’m running it only on my ubuntu machines but who knows maybe one day
it will run on different os.
I guess I will try using IdleEvent.

Thank you very much
Claudia

This note deserves comment, because it misplaces the blame. This is not a WX problem. The issue is the underlying operating systems. On Windows, you can do quite a lot of GUI stuff from other threads. On MacOS, you can do GUI stuff on bitmaps, as long as you protect it with locks. On Linux, NOTHING works from a secondary thread.

···

On Apr 12, 2017, at 7:30 AM, James Scholes <james@jls-radio.com> wrote:

Claudia Frank wrote:

Is there a way to identify which parts of wx are considered not to be
used in such a case?

Yes - consider the whole library to not have thread safety and
coordinate access to it appropriately.


Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

Tim Roberts wrote:

This note deserves comment, because it misplaces the blame. This is not a WX problem. The issue is the underlying operating systems.

I did point this out later in the same email, as well as quoting the official wxWidgets docs which say the same thing. But as wx is designed to be a cross-platform library, the end-result is often the same - wx cannot be considered to be thread-safe.

···

--
James Scholes
http://twitter.com/JamesScholes