After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 766840 - gdk event loop needs redesign for Quartz
gdk event loop needs redesign for Quartz
Status: RESOLVED OBSOLETE
Product: gtk+
Classification: Platform
Component: Backend: Quartz
unspecified
Other Mac OS
: Normal enhancement
: ---
Assigned To: gtk-quartz maintainers
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2016-05-24 13:51 UTC by Paul Davis
Modified: 2018-04-15 00:12 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Paul Davis 2016-05-24 13:51:09 UTC
This is a placeholder bug report to track any work done to redesign and reimplement the GDK backend for Quartz.

The current design implements a "poll function" that calls this code to get the next event:

  event = [NSApp nextEventMatchingMask: NSAnyEventMask
	                     untilDate: limit_date
	                        inMode: NSDefaultRunLoopMode
                               dequeue: YES];

which is extremely different, semantically, from what the X11 and Windows backends do in their poll functions. 

This code actually causes the processes main CFRunLoop to make a pass through its update/redraw cycle, and it will keep doing that until it goes idle. If anything stops the main CFRunLoop from going idle, this call will never return, and gtk+/gdk/glib's own event loop will not run. What can stop it? Very slow drawing by code using CoreGraphics directly, for example.

The current design is baroque, necessitated by being from a time when CFRunLoops could not support CFRunLoopSources that described file descriptors. This hasn't been the case since OS X 10.5 (i.e. a long time ago). The use of a separate "select thread" hasn't been necessary since the introduction of file descriptor support, and it needs to go away.

The GDK/glib integration with CFRunLoop needs to be reimplemented to cast everything into CFRunLoop-related objects, and then just use a CFRunLoop directly. 

This is not a small task. There may be glib source types that are not easily convertible into CFRunLoopSources. 

If you, Dear Reader, have design ideas or notes on this, please leave them here so that when/if work begins, it can do so as fully informed as possible.
Comment 1 Kristian Rietveld 2016-05-24 14:07:51 UTC
You probably also want to consider the comments on Quartz main loop issues that can be found in bug 704374.
Comment 2 Sebastian Dröge (slomo) 2016-05-24 16:37:55 UTC
Also related to bug #741450
Comment 3 Paul Davis 2016-05-24 16:53:19 UTC
(In reply to Sebastian Dröge (slomo) from comment #2)
> Also related to bug #741450

I don't think the approach outlined there is the correct one (though it could work). I think that the right design is to make GMainContext have a CFRunLoop (the default GMainContext would use the default CFRunLoop). Each new GSource would also be a CFRunLoopSource. Adding a GSource to the GMainContext would actually just be a proxy for adding the corresponding CFRunLoopSource to the corresponding CFRunLoop. Running the GMainContext would just be running the CFRunLoop. There would be no back and forth between two different event loops, and no special technique to "hand control" back and forth. Running a GMainContext would be precisely equivalent to running a CFRunLoop. 

The hard part is that the glib API breaks out the internals of a GMainContext into many more parts than CFRunLoop does. We have the following API that may or may not map well onto CFRunLoop:

GMainContext * 	g_main_context_default ()
gboolean 	g_main_context_iteration ()
#define 	g_main_iteration()
gboolean 	g_main_context_pending ()
#define 	g_main_pending
GSource * 	g_main_context_find_source_by_id ()
GSource * 	g_main_context_find_source_by_user_data ()
GSource * 	g_main_context_find_source_by_funcs_user_data ()
void	 	g_main_context_wakeup ()
gboolean 	g_main_context_acquire ()
void	 	g_main_context_release ()
gboolean 	g_main_context_is_owner ()
gboolean 	g_main_context_wait ()
gboolean 	g_main_context_prepare ()
gint	 	g_main_context_query ()
gint	 	g_main_context_check ()
void	 	g_main_context_dispatch ()
void 		g_main_context_set_poll_func ()
GPollFunc 	g_main_context_get_poll_func ()
gint	 	(*GPollFunc) ()
void	 	g_main_context_add_poll ()
void	 	g_main_context_remove_poll ()
gint	 	g_main_depth ()
GSource * 	g_main_current_source ()
#define 	g_main_set_poll_func()
void	 	g_main_context_invoke ()
void	 	g_main_context_invoke_full ()
GMainContext * 	g_main_context_get_thread_default ()
GMainContext * 	g_main_context_ref_thread_default ()
void	 	g_main_context_push_thread_default ()
void	 	g_main_context_pop_thread_default ()

For any changes to be accepted as part of glib, every single one of these API entry points needs to have behaviour sufficiently identical to the current system. Notably, things like the wait/prepare/check/dispatch methods are going to be quite hard to "translate" into the Cocoa model.
Comment 4 Matthias Clasen 2018-02-10 05:17:34 UTC
We're moving to gitlab! As part of this move, we are moving bugs to NEEDINFO if they haven't seen activity in more than a year. If this issue is still important to you and still relevant with GTK+ 3.22 or master, please reopen it and we will migrate it to gitlab.
Comment 5 Matthias Clasen 2018-04-15 00:12:42 UTC
As announced a while ago, we are migrating to gitlab, and bugs that haven't seen activity in the last year or so will be not be migrated, but closed out in bugzilla.

If this bug is still relevant to you, you can open a new issue describing the symptoms and how to reproduce it with gtk 3.22.x or master in gitlab:

https://gitlab.gnome.org/GNOME/gtk/issues/new