quodlibet UI freeze in Unity after accessing its menu

Bug #717162 reported by al.cadd9
26
This bug affects 3 people
Affects Status Importance Assigned to Milestone
AppMenu GTK+
Invalid
Undecided
Unassigned
DBus Menu
Fix Released
High
Ted Gould
Unity
Invalid
Undecided
Unassigned
unity-2d
Invalid
High
Unassigned
libdbusmenu (Ubuntu)
Fix Released
High
Unassigned
Natty
Fix Released
High
Unassigned
unity (Ubuntu)
Invalid
High
Unassigned
Natty
Invalid
High
Unassigned

Bug Description

system info: Maverick 32bit in a virtualbox VM

Reproducibility: always

How to reproduce: in unity-2d, open quodlibet (in any way), then use the program menu, for example Music>Add a folder..., then return to the main UI and voilà, the UI is frozen.

Debug log: http://pastebin.com/QBbfSRtd

Additional info: the same freeze manifest itself with another program, deadbeef. I use the stable version from the ppa https://launchpad.net/~alexey-smirnov/+archive/deadbeef?field.series_filter=maverick

Tags: patch

Related branches

summary: - quodlibet UI freeze in unity-2d
+ quodlibet UI freeze in Unity 2D
Changed in unity-2d:
status: New → Confirmed
importance: Undecided → High
milestone: none → 3.8
Revision history for this message
Florian Boucault (fboucault) wrote : Re: quodlibet UI freeze in Unity 2D
Revision history for this message
Florian Boucault (fboucault) wrote :

This happens in Natty as well.

Revision history for this message
Florian Boucault (fboucault) wrote :

It only happens when unity-2d-panel is running and capturing quodlibet's menu.

Revision history for this message
Florian Boucault (fboucault) wrote :

It also happens in Unity proper.

Revision history for this message
Florian Boucault (fboucault) wrote :

At this point I suspect a bug in the way GTK exports its menus.

summary: - quodlibet UI freeze in Unity 2D
+ quodlibet UI freeze in Unity after accessing its menu
Changed in dbusmenu:
status: New → Confirmed
importance: Undecided → High
assignee: nobody → Ted Gould (ted)
Changed in unity:
status: New → Confirmed
Revision history for this message
Ted Gould (ted) wrote :

Dup'd in one from Lernid, which has problems with other dialogs. It seems that it could perhaps be dialogs that are connected to menu items?

Revision history for this message
Sebastien Bacher (seb128) wrote :

the bug submitter in the duplicate thinks "this is related to the use of dialog.run() in a signal handler from the indicator-appmenu -- on return from the signal handler gtk seems to stop running."

Revision history for this message
Ken VanDine (ken-vandine) wrote :

I stepped through quodlibet in the debugger, i noticed in the open_chooser function it did get the response from the file selection dialog and continued past that. But when it got to the end of that (open_chooser) function, it just kind of stopped. Maybe it the mainloop is getting confused somehow because of something happening in that file selection dialog.

Revision history for this message
John S. Gruber (jsjgruber) wrote :

import gtk

""" Either commenting out the following threads call, or disabling the global
appmenu, allows the program to run after using the First Menu's About and then
closing the resulting About dialog box.

The Second Menu's About dialog box, with its different call back routine, works irregardless. """

gtk.gdk.threads_init() # Without this line program works ok

window=gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_title("Our Window")
window.connect("delete-event", lambda x,y: gtk.main_quit() )
window.show()

def menuitem_response(string):
    about = gtk.AboutDialog()
    about.set_name("My About Dialog")
    response = about.run()
    about.destroy()

def menuitem2_response(string):
    about = gtk.AboutDialog()
    about.set_name("My About Dialog")
    about.connect("response", lambda x,y: x.destroy() )
    about.show()

about_item = gtk.MenuItem("About")
about_item.connect_object("activate", menuitem_response, "about")
about_item.show()

about_item2 = gtk.MenuItem("About")
about_item2.connect_object("activate", menuitem2_response, "about")
about_item2.show()

menu = gtk.Menu()
menu.append(about_item)

menu2 = gtk.Menu()
menu2.append(about_item2)

root_menu = gtk.MenuItem("First Top Menu")
root_menu.show()
root_menu.set_submenu(menu)

second_menu = gtk.MenuItem("Second Top Menu")
second_menu.show()
second_menu.set_submenu(menu2)

vbox = gtk.VBox(False, 0)
window.add(vbox)
vbox.show()

menubar=gtk.MenuBar()
vbox.pack_start(menubar, False, False, 0)
menubar.append(root_menu)
menubar.append(second_menu)
menubar.show()

gtk.main()

Revision history for this message
John S. Gruber (jsjgruber) wrote :

It seems to me that the problem is a gtk.gdk.thread_enter without a balancing gtk.gdk.thread_leave. See the following.

Revision history for this message
John S. Gruber (jsjgruber) wrote :

import gtk

""" Either commenting out the following threads call, or disabling the global
appmenu, allows the program to run after using the First Menu's About and then
closing the resulting About dialog box.

The Second Menu's About dialog box, with its different call back routine, works irregardless.

Including gtk.gdk.threads_leave() in the problematic call back routine also
works. The problem seems to be an unbalanced thread lock enter..leave """

gtk.gdk.threads_init() # Without this line program works ok

window=gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_title("Our Window")
window.connect("delete-event", lambda x,y: gtk.main_quit() )
window.show()

def menuitem_response(string):
    about = gtk.AboutDialog()
    about.set_name("My About Dialog")
    response = about.run()
    gtk.gdk.threads_leave() # <---------------------------------------------------------------------
    about.destroy()

def menuitem2_response(string):
    about = gtk.AboutDialog()
    about.set_name("My About Dialog")
    about.connect("response", lambda x,y: x.destroy() )
    about.show()

about_item = gtk.MenuItem("About")
about_item.connect_object("activate", menuitem_response, "about")
about_item.show()

about_item2 = gtk.MenuItem("About")
about_item2.connect_object("activate", menuitem2_response, "about")
about_item2.show()

menu = gtk.Menu()
menu.append(about_item)

menu2 = gtk.Menu()
menu2.append(about_item2)

root_menu = gtk.MenuItem("First Top Menu")
root_menu.show()
root_menu.set_submenu(menu)

second_menu = gtk.MenuItem("Second Top Menu")
second_menu.show()
second_menu.set_submenu(menu2)

vbox = gtk.VBox(False, 0)
window.add(vbox)
vbox.show()

menubar=gtk.MenuBar()
vbox.pack_start(menubar, False, False, 0)
menubar.append(root_menu)
menubar.append(second_menu)
menubar.show()

gtk.main()

Changed in unity (Ubuntu):
status: New → Confirmed
Changed in unity (Ubuntu):
importance: Undecided → High
Revision history for this message
Oleg Shparber (trollixx) wrote :

This bug origns from appmenu-gtk and affects multi-thread applications based on gthread.
To fix in bridge.c item_activated function should use gdk_threads_enter and gdk_threads_leave:

static void
item_activated (DbusmenuMenuitem *item, guint timestamp, gpointer user_data)
{
  GtkWidget *child;

  if (user_data != NULL)
    {
      child = (GtkWidget *)user_data;

      if (GTK_IS_MENU_ITEM (child))
        {
          gdk_threads_enter ();
          gtk_menu_item_activate (GTK_MENU_ITEM (child));
          gdk_threads_leave ();
        }
    }
}

Revision history for this message
John S. Gruber (jsjgruber) wrote :

Excellent job, Oleg.

I'm running Natty so I applied your fix to libdbusmenu-gtk/parser.c in package libdbusmenu. Unlike without the patch I can sucessfully dismiss the quodlibet and lernid help->about boxes (as well as the test program's above).

Revision history for this message
Oleg Shparber (trollixx) wrote :

Sorry, forgot to metion that in Natty this code was moved to libdbusmenu-gtk, I use Maverick for now.

Actually, without the fix this bug occurs when application blocks main GTK loop and creates its own, for example with gtk_dialog_run.

Thanks to waker (the deadbeef project lead) for finding out the root of the problem.

Revision history for this message
Mark Shuttleworth (sabdfl) wrote : Re: [Bug 717162] Re: quodlibet UI freeze in Unity after accessing its menu

Well done guys - will you flag the patch for Ted's attention?

Revision history for this message
Oleg Shparber (trollixx) wrote :
tags: added: patch
Ted Gould (ted)
Changed in dbusmenu:
status: Confirmed → Fix Committed
Changed in appmenu-gtk:
status: New → Invalid
Changed in unity:
status: Confirmed → Invalid
Changed in unity-2d:
status: Confirmed → Invalid
Changed in unity (Ubuntu Natty):
status: Confirmed → Invalid
Changed in libdbusmenu (Ubuntu Natty):
status: New → Confirmed
importance: Undecided → High
Ted Gould (ted)
Changed in dbusmenu:
milestone: none → 0.4.0
status: Fix Committed → Fix Released
Revision history for this message
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package libdbusmenu - 0.4.0-0ubuntu1

---------------
libdbusmenu (0.4.0-0ubuntu1) natty; urgency=low

  * New upstream release.
    * Protect from NULL variants by using iter_loop (LP: #737844)
    * Look for accellerators inside the labels as well
    * Protecting properties that are getting updated from an
      extra remove signal. (LP: #730925)
    * Enter and exit the GDK threads before calling GTK (LP: #717162)
 -- Ted Gould <email address hidden> Wed, 23 Mar 2011 14:56:24 -0500

Changed in libdbusmenu (Ubuntu Natty):
status: Confirmed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Duplicates of this bug

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.