* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
/*
#include "gtkbindings.h"
#include "gtkkeyhash.h"
#include "gtklabel.h"
-#include "gtkmainprivate.h"
+#include "gtkmain.h"
#include "gtkmarshalers.h"
#include "gtkmenubar.h"
#include "gtkmenuitemprivate.h"
#include "gtkmenushellprivate.h"
#include "gtkmenuprivate.h"
#include "gtkmnemonichash.h"
-#include "gtktearoffmenuitem.h"
#include "gtkwindow.h"
#include "gtkprivate.h"
+#include "gtkmain.h"
#include "gtkintl.h"
#include "gtktypebuiltins.h"
+#include "deprecated/gtktearoffmenuitem.h"
+
+#include "a11y/gtkmenushellaccessible.h"
+
+
#define MENU_SHELL_TIMEOUT 500
#define PACK_DIRECTION(m) \
CANCEL,
CYCLE_FOCUS,
MOVE_SELECTED,
+ INSERT,
LAST_SIGNAL
};
G_TYPE_BOOLEAN, 1,
G_TYPE_INT);
+ /**
+ * GtkMenuShell::insert:
+ * @menu_shell: the object on which the signal is emitted
+ * @child: the #GtkMenuItem that is being inserted
+ * @position: the position at which the insert occurs
+ *
+ * The ::insert signal is emitted when a new #GtkMenuItem is added to
+ * a #GtkMenuShell. A separate signal is used instead of
+ * GtkContainer::add because of the need for an additional position
+ * parameter.
+ *
+ * The inverse of this signal is the GtkContainer::removed signal.
+ *
+ * Since: 3.2
+ **/
+ menu_shell_signals[INSERT] =
+ g_signal_new (I_("insert"),
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GtkMenuShellClass, insert),
+ NULL, NULL,
+ _gtk_marshal_VOID__OBJECT_INT,
+ G_TYPE_NONE, 2, GTK_TYPE_WIDGET, G_TYPE_INT);
+
+
binding_set = gtk_binding_set_by_class (klass);
gtk_binding_entry_add_signal (binding_set,
GDK_KEY_Escape, 0,
TRUE,
GTK_PARAM_READWRITE));
+ gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_MENU_SHELL_ACCESSIBLE);
+
g_type_class_add_private (object_class, sizeof (GtkMenuShellPrivate));
}
GtkWidget *child,
gint position)
{
- GtkMenuShellClass *class;
-
g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell));
g_return_if_fail (GTK_IS_MENU_ITEM (child));
- class = GTK_MENU_SHELL_GET_CLASS (menu_shell);
-
- if (class->insert)
- class->insert (menu_shell, child, position);
+ g_signal_emit (menu_shell, menu_shell_signals[INSERT], 0, child, position);
}
static void
{
g_return_if_fail (GTK_IS_MENU_SHELL (menu_shell));
- g_signal_emit (menu_shell, menu_shell_signals[DEACTIVATE], 0);
+ if (menu_shell->priv->active)
+ g_signal_emit (menu_shell, menu_shell_signals[DEACTIVATE], 0);
}
static void
window = gdk_window_new (gtk_widget_get_parent_window (widget),
&attributes, attributes_mask);
gtk_widget_set_window (widget, window);
- gdk_window_set_user_data (window, widget);
+ gtk_widget_register_window (widget, window);
context = gtk_widget_get_style_context (widget);
gtk_style_context_set_background (context, window);
}
-void
-_gtk_menu_shell_activate (GtkMenuShell *menu_shell)
+static void
+gtk_menu_shell_activate (GtkMenuShell *menu_shell)
{
GtkMenuShellPrivate *priv = menu_shell->priv;
gtk_widget_get_parent (menu_item) == widget &&
menu_item != priv->active_menu_item)
{
- _gtk_menu_shell_activate (menu_shell);
+ gtk_menu_shell_activate (menu_shell);
priv->button = event->button;
if (GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement == GTK_TOP_BOTTOM)
if (!gtk_widget_get_visible (GTK_MENU_ITEM (menu_item)->priv->submenu))
{
- gboolean touchscreen_mode;
+ GdkDevice *source_device;
- g_object_get (gtk_widget_get_settings (widget),
- "gtk-touchscreen-mode", &touchscreen_mode,
- NULL);
+ source_device = gdk_event_get_source_device ((GdkEvent *) event);
- if (touchscreen_mode)
+ if (gdk_device_get_source (source_device) == GDK_SOURCE_TOUCHSCREEN)
_gtk_menu_item_popup_submenu (menu_item, TRUE);
}
}
GdkEventCrossing *event)
{
if (event->mode == GDK_CROSSING_GTK_GRAB ||
- event->mode == GDK_CROSSING_GTK_GRAB ||
+ event->mode == GDK_CROSSING_GTK_UNGRAB ||
event->mode == GDK_CROSSING_STATE_CHANGED)
return TRUE;
if (priv->active)
{
-
priv->button = 0;
priv->active = FALSE;
priv->activate_time = 0;
return;
}
+ gtk_menu_shell_activate (menu_shell);
+
priv->active_menu_item = menu_item;
if (pack_dir == GTK_PACK_DIRECTION_TTB || pack_dir == GTK_PACK_DIRECTION_BTT)
_gtk_menu_item_set_placement (GTK_MENU_ITEM (priv->active_menu_item),
GtkMenuShellPrivate *priv = menu_shell->priv;
GtkMenuShell *parent_menu_shell = NULL;
gboolean had_selection;
- gboolean touchscreen_mode;
priv->in_unselectable_item = FALSE;
had_selection = priv->active_menu_item != NULL;
- g_object_get (gtk_widget_get_settings (GTK_WIDGET (menu_shell)),
- "gtk-touchscreen-mode", &touchscreen_mode,
- NULL);
-
if (priv->parent_menu_shell)
parent_menu_shell = GTK_MENU_SHELL (priv->parent_menu_shell);
switch (direction)
{
case GTK_MENU_DIR_PARENT:
- if (touchscreen_mode &&
- priv->active_menu_item &&
- GTK_MENU_ITEM (priv->active_menu_item)->priv->submenu &&
- gtk_widget_get_visible (GTK_MENU_ITEM (priv->active_menu_item)->priv->submenu))
- {
- /* if we are on a menu item that has an open submenu but the
- * focus is not in that submenu (e.g. because it's empty or
- * has only insensitive items), close that submenu instead of
- * running into the code below which would close *this* menu.
- */
- _gtk_menu_item_popdown_submenu (priv->active_menu_item);
- _gtk_menu_shell_update_mnemonics (menu_shell);
- }
- else if (parent_menu_shell)
+ if (parent_menu_shell)
{
- if (touchscreen_mode)
- {
- /* close menu when returning from submenu. */
- _gtk_menu_item_popdown_submenu (GTK_MENU (menu_shell)->priv->parent_menu_item);
- _gtk_menu_shell_update_mnemonics (parent_menu_shell);
- break;
- }
-
if (GTK_MENU_SHELL_GET_CLASS (parent_menu_shell)->submenu_placement ==
GTK_MENU_SHELL_GET_CLASS (menu_shell)->submenu_placement)
gtk_menu_shell_deselect (menu_shell);
gtk_real_menu_shell_cycle_focus (GtkMenuShell *menu_shell,
GtkDirectionType dir)
{
- GtkMenuShellPrivate *priv = menu_shell->priv;
-
while (menu_shell && !GTK_IS_MENU_BAR (menu_shell))
{
- if (priv->parent_menu_shell)
- menu_shell = GTK_MENU_SHELL (priv->parent_menu_shell);
+ if (menu_shell->priv->parent_menu_shell)
+ menu_shell = GTK_MENU_SHELL (menu_shell->priv->parent_menu_shell);
else
menu_shell = NULL;
}
event->group);
if (entries)
- result = _gtk_mnemonic_hash_activate (mnemonic_hash,
- GPOINTER_TO_UINT (entries->data));
+ {
+ result = _gtk_mnemonic_hash_activate (mnemonic_hash,
+ GPOINTER_TO_UINT (entries->data));
+ g_slist_free (entries);
+ }
return result;
}
*
* Gets the currently selected item.
*
- * Returns: the currently selected item
+ * Returns: (transfer none): the currently selected item
*
* Since: 3.0
*/
* The parent menu shell of a submenu is the #GtkMenu or #GtkMenuBar
* from which it was opened up.
*
- * Returns: the parent #GtkMenuShell
+ * Returns: (transfer none): the parent #GtkMenuShell
*
* Since: 3.0
*/