Problem
If you have run the example How to set up an application to run in the system tray using GtkStatusIcon - Part 4 - display popup menu on right click? or How to set up an application to run in the system tray using GtkStatusIcon - Part 5 - make the tray icon blink?, you will have noticed that if you keep pressing the right-mouse button on the system tray icon without selecting any of the menu item, you will end up having many popup windows surrounding the tray icon.
Let's fix this in this article as shown below:
Solution
- Use a variable as a flag to let us know if there's any active popup window.
- If there's already a previous popup window, pop it down using the method GtkMenu::popdown() before displaying the new popup window.
Important Note: This only works for PHP-GTK2 compliled with gtk+ v2.10 and above. If you are using an older version, for linux, you may follow the step-by-step instructions to recompile php-gtk2 with gtk+ v2.10. For windows, please refer to How to install php gtk2 on windows? You may also want to take a look here to see some of the new exciting PHP-GTK2 Functionalities.
Sample Code
1 2 3 4 5 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 84 85 87 88 89 90 92 93 94 95 96 97 98 99 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | <?php // setup GTK main application $window = new GtkWindow(); $window->set_title($argv[0]); $window->set_size_request(400, 300); $window->connect('destroy', 'destroy'); $window->add($vbox = new GtkVBox()); $vbox->pack_start($hbox = new GtkHBox(), 0, 0); $hbox->set_size_request(-1, 2); // Create the top textview to display the conversation $buffer1 = new GtkTextBuffer(); $view1 = new GtkTextView(); $view1->set_buffer($buffer1); $view1->set_editable(false); $view1->modify_font(new PangoFontDescription("Arial 9")); $view1->set_wrap_mode(Gtk::WRAP_WORD); $scrolled_win1 = new GtkScrolledWindow(); $scrolled_win1->set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC); $frame1 = new GtkFrame(); $frame1->add($scrolled_win1); $vbox->pack_start($frame1, 0, 0); $scrolled_win1->add($view1); $scrolled_win1->set_size_request(400,200); $vbox->pack_start($hbox = new GtkHBox(), 0, 0); $hbox->set_size_request(-1, 1); // Create the bottom textview to type your message $buffer2 = new GtkTextBuffer(); $buffer2->set_text('type your message here'); $view2 = new GtkTextView(); $view2->set_buffer($buffer2); $view2->modify_font(new PangoFontDescription("Arial 9")); $view2->set_wrap_mode(Gtk::WRAP_WORD); $scrolled_win2 = new GtkScrolledWindow(); $scrolled_win2->set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC); $frame2 = new GtkFrame(); $frame2->add($scrolled_win2); $vbox->pack_start($frame2, 0, 0); $scrolled_win2->add($view2); $view2->connect('key-press-event', 'on_key_press', $view1, $buffer1, $view2, $buffer2); $scrolled_win2->set_size_request(400,80); $view2->grab_focus(); // setup system tray icon $statusicon = new GtkStatusIcon(); $statusicon->set_from_stock(Gtk::STOCK_NETWORK); $statusicon->set_tooltip('Left click to launch PHP-GTK Messenger'); $app_status = 0; $statusicon->connect('activate', 'on_activate'); $statusicon->connect('popup-menu', 'on_popup_menu'); $menu_popped_up = 0; // note 1 $popup_menu_ptr = null; // note 2 $window->hide_all(); Gtk::main(); function on_key_press($widget, $event, $view1, $buffer1, $view2, $buffer2) { if ($event->keyval==Gdk::KEY_Return) { if ($event->state & Gdk::SHIFT_MASK) return false; $input = $buffer2->get_text($buffer2->get_start_iter(), $buffer2->get_end_iter()); $iter = $buffer1->get_end_iter(); $buffer1->insert($iter, "You say: $input\n\n" ); $view1->scroll_to_mark($buffer1->get_insert(), 0); $buffer2->set_text(''); return true; } else { return false; } } function on_activate($statusicon) { global $window, $app_status, $view2; if ($app_status) { $statusicon->set_tooltip('Left click to launch PHP-GTK Messenger'); $window->hide_all(); $app_status = 0; } else { $statusicon->set_tooltip('Left click to hide PHP-GTK Messenger'); $window->show_all(); $view2->grab_focus(); $app_status = 1; } } function on_popup_menu($statusicon) { $menu_definition = array('Show','Hide', '<hr>', 'Connect','Disconnect','<hr>','Exit'); $menu = show_popup_menu($menu_definition); } // show popup menu function show_popup_menu($menu_definition) { global $popup_menu_ptr, $menu_popped_up; if ($menu_popped_up && $popup_menu_ptr!=null) { // note 3 $popup_menu_ptr->popdown(); // note 4 $menu_popped_up = 0; } $menu = new GtkMenu(); foreach($menu_definition as $menuitem_definition) { if ($menuitem_definition=='<hr>') { $menu->append(new GtkSeparatorMenuItem()); } else { $menu_item = new GtkMenuItem($menuitem_definition); $menu->append($menu_item); $menu_item->connect('activate', 'on_popup_menu_select'); } } global $statusicon; $popup_menu_ptr = $menu; $menu->show_all(); $menu->popup(); $menu_popped_up = 1; } // process popup menu item selection function on_popup_menu_select($menu_item) { global $window; $item = $menu_item->child->get_label(); echo "popup menu selected: $item\n"; switch($item) { case 'Show': $window->show_all(); break; case 'Hide': $window->hide_all(); break; case 'Exit': Gtk::main_quit(); break; } } ?> |
Output
As shown above.Explanation
The sample code above is an extension of How to set up an application to run in the system tray using GtkStatusIcon - Part 4 - display popup menu on right click?
What's new here:
- Kees track if there's any active popup window.
- Take note of the pointer to this popup window.
- Check if there are any previous popup window.
- Yes, let's pop it down!
Related Links
- How to set up an application to run in the system tray using GtkStatusIcon - Part 1?
- How to set up an application to run in the system tray using GtkStatusIcon - Part 2 - display GTK window on left click?
- How to set up an application to run in the system tray using GtkStatusIcon - Part 3 - display GTK app on left click?
- How to set up an application to run in the system tray using GtkStatusIcon - Part 4 - display popup menu on right click?
- How to set up an application to run in the system tray using GtkStatusIcon - Part 5 - make the tray icon blink?
- How to set up an application to run in the system tray using GtkStatusIcon - Part 6 - make the application blink?
Comments
This works great until you decide not to choose anything in the popup menu and click on the desktop or another window.
The menu just stays there.
The only way to close it is to choose a menu item or click on the main application window (which then takes two clicks to re-focus the window).
Any idea of how to make the popup go away if you click somewhere else outside of it without making a choice (like Show, Hide or Exit?
In PHP-GTK2, the popup menu is a modal window. In a modal window, it takes control over all other windows.
Don't think it's possible to change what you have in mind in the current PHP-GTK version.
Regards,
/kksou
I don't know if I just missed it the other day when I posted that or not, but the flow is now like this:
1) Right-click status icon -> menu pops up.
2) Click anywhere outside of it -> menu pops down (and the 'hide' and 'selection-done' signals are emitted).
3) Right-click status icon again -> menu pops up.
4) Click anywhere outside of it (desktop, another window, etc.. (except for actual PHP-GTK2 application window) -> nothing happens with the popup menu, just sits there (and NO signals are emitted at all). (Clicking the associated PHP-GTK2 application window closes the menu and emits signals).
Just a few mins ago, I finally gave up and decided to live with it the way it is, lol.
(I love all your examples on PHP-GTK2, they're excellent and have helped immensely)
(Had to do another reply for this - the comment limit says 1000, it kept saying it was too long)
RSS feed for comments to this post