static void gtk_tearoff_menu_item_parent_set (GtkWidget *widget, GtkWidget *previous) { GtkTearoffMenuItem *tearoff_menu_item = GTK_TEAROFF_MENU_ITEM (widget); GtkTearoffMenuItemPrivate *priv = tearoff_menu_item->priv; GtkMenu *menu; GtkWidget *parent; parent = gtk_widget_get_parent (widget); menu = GTK_IS_MENU (parent) ? GTK_MENU (parent) : NULL; if (previous) g_signal_handlers_disconnect_by_func (previous, tearoff_state_changed, tearoff_menu_item); if (menu) { priv->torn_off = gtk_menu_get_tearoff_state (menu); g_signal_connect (menu, "notify::tearoff-state", G_CALLBACK (tearoff_state_changed), tearoff_menu_item); } }
static void gtk_tearoff_menu_item_get_preferred_height (GtkWidget *widget, gint *minimum, gint *natural) { GtkStyleContext *context; GtkBorder padding; GtkStateFlags state; GtkWidget *parent; guint border_width; context = gtk_widget_get_style_context (widget); state = gtk_widget_get_state_flags (widget); gtk_style_context_get_padding (context, state, &padding); border_width = gtk_container_get_border_width (GTK_CONTAINER (widget)); *minimum = *natural = (border_width * 2) + padding.top + padding.bottom; parent = gtk_widget_get_parent (widget); if (GTK_IS_MENU (parent) && gtk_menu_get_tearoff_state (GTK_MENU (parent))) { *minimum += ARROW_SIZE; *natural += ARROW_SIZE; } else { *minimum += padding.top + 4; *natural += padding.top + 4; } }
static void pipe_menu_recreate (GtkWidget *item, gchar *command) { gchar *stdout_for_cmd; gchar *cache_entries = g_object_get_data (G_OBJECT(item), "cached"); GtkWidget *submenu; submenu = gtk_menu_item_get_submenu (GTK_MENU_ITEM(item)); if (submenu) { if (strcmp (cache_entries, "yes") != 0) { gtk_widget_destroy (submenu); submenu = NULL; } } if (!submenu) { submenu = gtk_menu_new(); if (g_spawn_command_line_sync (parse_expand_tilde(command), &stdout_for_cmd, NULL, NULL, NULL)) { GError *error = NULL; DeskmenuObject *dm_object = g_object_get_data (G_OBJECT(item), "menu"); dm_object->current_menu = submenu; dm_object->make_from_pipe = TRUE; if (gtk_menu_get_tearoff_state (GTK_MENU(dm_object->menu))) { gtk_menu_shell_append (GTK_MENU_SHELL (dm_object->current_menu), gtk_tearoff_menu_item_new()); } GMarkupParseContext *context = g_markup_parse_context_new (&parser, 0, dm_object, NULL); g_markup_parse_context_parse (context, (const gchar *)stdout_for_cmd, strlen((const char *)stdout_for_cmd), &error); g_markup_parse_context_free (context); if (error) { g_print("%s", error->message); //spit out the message manually if (dm_object->current_item) { //force reset deskmenu_free_item(dm_object); } g_error_free (error); } g_free(stdout_for_cmd); dm_object->make_from_pipe = FALSE; } else { GtkWidget *empty_item = gtk_menu_item_new_with_label ("Unable to get output"); gtk_widget_set_sensitive (empty_item, FALSE); gtk_menu_shell_append (GTK_MENU_SHELL (submenu), empty_item); } gtk_widget_show_all(submenu); gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); } }
static void tearoff_state_changed (GtkMenu *menu, GParamSpec *pspec, gpointer data) { GtkTearoffMenuItem *tearoff_menu_item = GTK_TEAROFF_MENU_ITEM (data); tearoff_menu_item->torn_off = gtk_menu_get_tearoff_state (menu); }
static void gtk_tearoff_menu_item_activate (GtkMenuItem *menu_item) { GtkWidget *parent; parent = gtk_widget_get_parent (GTK_WIDGET (menu_item)); if (GTK_IS_MENU (parent)) { GtkMenu *menu = GTK_MENU (parent); gtk_widget_queue_resize (GTK_WIDGET (menu_item)); gtk_menu_set_tearoff_state (menu, !gtk_menu_get_tearoff_state (menu)); } }
int clip_GTK_MENUGETTEAROFFSTATE(ClipMachine * ClipMachineMemory) { C_widget *cmnu = _fetch_cw_arg(ClipMachineMemory); gboolean ret; CHECKCWID(cmnu, GTK_IS_MENU); ret = gtk_menu_get_tearoff_state(GTK_MENU(cmnu->widget)); _clip_retl(ClipMachineMemory, ret); return 0; err: return 1; }
static void cb_tearable_parent_changed (GtkWidget *tearable_menu, GtkWidget *old_parent, GOComboBox *combo) { GtkWidget *new_parent = gtk_widget_get_parent (tearable_menu); if (old_parent && combo->priv->tearoff_signal) { g_signal_handler_disconnect (old_parent, combo->priv->tearoff_signal); combo->priv->tearoff_signal = 0; } if (GTK_IS_MENU (new_parent)) { combo->priv->torn_off = gtk_menu_get_tearoff_state (GTK_MENU (new_parent)); combo->priv->tearoff_signal = g_signal_connect (new_parent, "notify::tearoff-state", G_CALLBACK (cb_tearoff_state_changed), combo); } }
/* This is a _horrible_ hack to have this here. This needs to be added to the * GTK+ menuing code in some manner. */ static void drag_end_menu_cb (GtkWidget *widget, GdkDragContext *context) { GtkWidget *xgrab_shell; GtkWidget *parent; /* Find the last viewable ancestor, and make an X grab on it */ parent = gtk_widget_get_parent (widget); xgrab_shell = NULL; /* FIXME: workaround for a possible gtk+ bug * See bugs #92085(gtk+) and #91184(panel) for details. */ g_object_set (widget, "has-tooltip", TRUE, NULL); while (parent) { gboolean viewable = TRUE; GtkWidget *tmp = parent; while (tmp) { if (!gtk_widget_get_mapped (tmp)) { viewable = FALSE; break; } tmp = gtk_widget_get_parent (tmp); } if (viewable) xgrab_shell = parent; #if GTK_CHECK_VERSION (3, 0, 0) parent = gtk_menu_shell_get_parent_shell (GTK_MENU_SHELL (parent)); #else parent = GTK_MENU_SHELL (parent)->parent_menu_shell; #endif } if (xgrab_shell && !gtk_menu_get_tearoff_state (GTK_MENU(xgrab_shell))) { GdkWindow *window = gtk_widget_get_window (xgrab_shell); GdkCursor *cursor = gdk_cursor_new (GDK_ARROW); if ((gdk_pointer_grab (window, TRUE, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK, NULL, cursor, GDK_CURRENT_TIME) == 0)) { if (gdk_keyboard_grab (window, TRUE, GDK_CURRENT_TIME) == 0) { /* FIXME fix for GTK3 */ #if !GTK_CHECK_VERSION (3, 0, 0) GTK_MENU_SHELL (xgrab_shell)->have_xgrab = TRUE; #endif } else { gdk_pointer_ungrab (GDK_CURRENT_TIME); } } gdk_cursor_unref (cursor); } }
static gboolean gtk_tearoff_menu_item_draw (GtkWidget *widget, cairo_t *cr) { GtkMenuItem *menu_item; GtkStateFlags state; GtkStyleContext *context; GtkBorder padding; gint x, y, width, height; gint right_max; guint border_width; GtkTextDirection direction; GtkWidget *parent; gdouble angle; menu_item = GTK_MENU_ITEM (widget); context = gtk_widget_get_style_context (widget); direction = gtk_widget_get_direction (widget); state = gtk_widget_get_state_flags (widget); border_width = gtk_container_get_border_width (GTK_CONTAINER (menu_item)); x = border_width; y = border_width; width = gtk_widget_get_allocated_width (widget) - border_width * 2; height = gtk_widget_get_allocated_height (widget) - border_width * 2; right_max = x + width; gtk_style_context_save (context); gtk_style_context_set_state (context, state); gtk_style_context_get_padding (context, state, &padding); if (state & GTK_STATE_FLAG_PRELIGHT) { gtk_render_background (context, cr, x, y, width, height); gtk_render_frame (context, cr, x, y, width, height); } parent = gtk_widget_get_parent (widget); if (GTK_IS_MENU (parent) && gtk_menu_get_tearoff_state (GTK_MENU (parent))) { gint arrow_x; if (menu_item->priv->toggle_size > ARROW_SIZE) { if (direction == GTK_TEXT_DIR_LTR) { arrow_x = x + (menu_item->priv->toggle_size - ARROW_SIZE)/2; angle = (3 * G_PI) / 2; } else { arrow_x = x + width - menu_item->priv->toggle_size + (menu_item->priv->toggle_size - ARROW_SIZE)/2; angle = G_PI / 2; } x += menu_item->priv->toggle_size + BORDER_SPACING; } else { if (direction == GTK_TEXT_DIR_LTR) { arrow_x = ARROW_SIZE / 2; angle = (3 * G_PI) / 2; } else { arrow_x = x + width - 2 * ARROW_SIZE + ARROW_SIZE / 2; angle = G_PI / 2; } x += 2 * ARROW_SIZE; } gtk_render_arrow (context, cr, angle, arrow_x, height / 2 - 5, ARROW_SIZE); } while (x < right_max) { gint x1, x2; if (direction == GTK_TEXT_DIR_LTR) { x1 = x; x2 = MIN (x + TEAR_LENGTH, right_max); } else { x1 = right_max - x; x2 = MAX (right_max - x - TEAR_LENGTH, 0); } gtk_render_line (context, cr, x1, y + (height - padding.bottom) / 2, x2, y + (height - padding.bottom) / 2); x += 2 * TEAR_LENGTH; } gtk_style_context_restore (context); return FALSE; }
/* This is a _horrible_ hack to have this here. This needs to be added to the * GTK+ menuing code in some manner. */ static void drag_end_menu_cb (GtkWidget *widget, GdkDragContext *context) { GtkWidget *xgrab_shell; GtkWidget *parent; /* Find the last viewable ancestor, and make an X grab on it */ parent = gtk_widget_get_parent (widget); xgrab_shell = NULL; /* FIXME: workaround for a possible gtk+ bug * See bugs #92085(gtk+) and #91184(panel) for details. */ g_object_set (widget, "has-tooltip", TRUE, NULL); while (parent) { gboolean viewable = TRUE; GtkWidget *tmp = parent; while (tmp) { if (!gtk_widget_get_mapped (tmp)) { viewable = FALSE; break; } tmp = gtk_widget_get_parent (tmp); } if (viewable) xgrab_shell = parent; parent = gtk_menu_shell_get_parent_shell (GTK_MENU_SHELL (parent)); } if (xgrab_shell && !gtk_menu_get_tearoff_state (GTK_MENU(xgrab_shell))) { gboolean status; GdkDisplay *display; GdkDevice *pointer; GdkDevice *keyboard; GdkDeviceManager *device_manager; GdkWindow *window = gtk_widget_get_window (xgrab_shell); GdkCursor *cursor = gdk_cursor_new (GDK_ARROW); display = gdk_window_get_display (window); device_manager = gdk_display_get_device_manager (display); pointer = gdk_device_manager_get_client_pointer (device_manager); keyboard = gdk_device_get_associated_device (pointer); /* FIXMEgpoo: Not sure if report to GDK_OWNERSHIP_WINDOW or GDK_OWNERSHIP_APPLICATION. Idem for the keyboard below */ status = gdk_device_grab (pointer, window, GDK_OWNERSHIP_WINDOW, TRUE, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK, cursor, GDK_CURRENT_TIME); if (!status) { if (gdk_device_grab (keyboard, window, GDK_OWNERSHIP_WINDOW, TRUE, GDK_KEY_PRESS | GDK_KEY_RELEASE, NULL, GDK_CURRENT_TIME) == GDK_GRAB_SUCCESS) { /* FIXMEgpoo: We need either accessors or a workaround to grab the focus */ #if 0 GTK_MENU_SHELL (xgrab_shell)->GSEAL(have_xgrab) = TRUE; #endif } else { gdk_device_ungrab (pointer, GDK_CURRENT_TIME); } } g_object_unref (cursor); } }
static void start_element (GMarkupParseContext *context, const gchar *element_name, const gchar **attr_names, const gchar **attr_values, gpointer user_data, GError **error) { DeskmenuObject *dm_object = user_data; DeskmenuElementType element_type; const gchar **ncursor = attr_names, **vcursor = attr_values; GtkWidget *item, *menu; gint w, h; element_type = GPOINTER_TO_INT (g_hash_table_lookup (element_hash, element_name)); if ((dm_object->menu && !dm_object->current_menu) || (!dm_object->menu && element_type != DESKMENU_ELEMENT_MENU)) { gint line_num, char_num; g_markup_parse_context_get_position (context, &line_num, &char_num); g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "Error on line %d char %d: Element '%s' declared outside of " "toplevel menu element", line_num, char_num, element_name); return; } switch (element_type) { case DESKMENU_ELEMENT_MENU: if (dm_object->current_item != NULL) { gint line_num, char_num; g_markup_parse_context_get_position (context, &line_num, &char_num); g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "Error on line %d char %d: Element 'menu' cannot be nested " "inside of an item element", line_num, char_num); return; } if (!dm_object->menu) { /*if (strcmp (*ncursor, "size") == 0) { deskmenu->w = g_strdup (*vcursor); deskmenu->h = g_strdup (*vcursor); } else { gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, deskmenu->w, deskmenu->h); }*/ dm_object->menu = gtk_menu_new (); g_object_set_data (G_OBJECT (dm_object->menu), "parent menu", NULL); dm_object->current_menu = dm_object->menu; } else { gchar *name = NULL; gchar *icon = NULL; gboolean name_exec = FALSE; gboolean icon_file = FALSE; while (*ncursor) { if (strcmp (*ncursor, "name") == 0) name = g_strdup (*vcursor); else if (strcmp (*ncursor, "icon") == 0) icon = g_strdup (*vcursor); else if ((strcmp (*ncursor, "mode") == 0) && (strcmp (*vcursor, "exec") == 0)) name_exec = TRUE; else if ((strcmp (*ncursor, "mode1") == 0) && (strcmp (*vcursor, "file") == 0)) icon_file = TRUE; else g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "Unknown attribute: %s", *ncursor); ncursor++; vcursor++; } if (name_exec) { GtkWidget *label; GHook *hook; item = gtk_image_menu_item_new (); label = gtk_label_new_with_mnemonic (NULL); gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); g_object_set_data (G_OBJECT (label), "exec", g_strdup (name)); gtk_container_add (GTK_CONTAINER (item), label); hook = g_hook_alloc (dm_object->show_hooks); hook->data = (gpointer) label; hook->func = (GHookFunc *) launcher_name_exec_update; g_hook_append (dm_object->show_hooks, hook); } else { if (name) item = gtk_image_menu_item_new_with_mnemonic (name); else item = gtk_image_menu_item_new_with_mnemonic (""); } if (icon) { if (icon_file) { gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM(item), gtk_image_new_from_pixbuf (gdk_pixbuf_new_from_file_at_size (parse_expand_tilde(icon), w, h, NULL))); } else { gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU)); } } gtk_menu_shell_append (GTK_MENU_SHELL (dm_object->current_menu), item); menu = gtk_menu_new (); g_object_set_data (G_OBJECT (menu), "parent menu", dm_object->current_menu); dm_object->current_menu = menu; gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), dm_object->current_menu); if (!dm_object->make_from_pipe) { GtkWidget *pin = gtk_tearoff_menu_item_new(); gtk_menu_shell_append (GTK_MENU_SHELL (dm_object->current_menu), pin); //add a pin menu item dm_object->pin_items = g_slist_prepend (dm_object->pin_items, pin); } else { if (gtk_menu_get_tearoff_state (GTK_MENU(dm_object->menu))) { GtkWidget *pin = gtk_tearoff_menu_item_new(); gtk_menu_shell_append (GTK_MENU_SHELL (dm_object->current_menu), pin); //add a pin menu item } } g_free (name); g_free (icon); } break; case DESKMENU_ELEMENT_SEPARATOR: if (dm_object->current_item != NULL) { gint line_num, char_num; g_markup_parse_context_get_position (context, &line_num, &char_num); g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "Error on line %d char %d: Element 'menu' cannot be nested " "inside of an item element", line_num, char_num); return; } else { gchar *name = NULL; gchar *icon = NULL; gboolean name_exec = FALSE; gboolean icon_file = FALSE; gboolean decorate = FALSE; gint w, h; item = gtk_separator_menu_item_new(); while (*ncursor) { if (strcmp (*ncursor, "name") == 0) { name = g_strdup (*vcursor); if (!decorate) { decorate = TRUE; } } else if (strcmp (*ncursor, "icon") == 0) { icon = g_strdup (*vcursor); if (!decorate) { decorate = TRUE; } } else if ((strcmp (*ncursor, "mode") == 0) && (strcmp (*vcursor, "exec") == 0)) name_exec = TRUE; else if ((strcmp (*ncursor, "mode1") == 0) && (strcmp (*vcursor, "file") == 0)) icon_file = TRUE; else g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "Unknown attribute: %s", *ncursor); ncursor++; vcursor++; } if (decorate) { GtkWidget *box = gtk_hbox_new (FALSE, 3); gtk_container_add (GTK_CONTAINER(item), GTK_WIDGET(box)); if (name_exec) { GtkWidget *label; GHook *hook; label = gtk_label_new_with_mnemonic (NULL); g_object_set_data (G_OBJECT (label), "exec", g_strdup (name)); gtk_box_pack_end (GTK_BOX(box), label, TRUE, FALSE, 0); hook = g_hook_alloc (dm_object->show_hooks); hook->data = (gpointer) label; hook->func = (GHookFunc *) launcher_name_exec_update; g_hook_append (dm_object->show_hooks, hook); } else { gtk_box_pack_end (GTK_BOX(box), gtk_label_new_with_mnemonic (name), TRUE, FALSE, 0); } if (icon) { GtkWidget *image; if (icon_file) { gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &w, &h); image = gtk_image_new_from_pixbuf (gdk_pixbuf_new_from_file_at_size (parse_expand_tilde(icon), w, h, NULL)); } else { image = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_MENU); } gtk_box_pack_start (GTK_BOX(box), image, FALSE, FALSE, 0); } gtk_widget_set_state (item, GTK_STATE_PRELIGHT); /*derive colors from menu hover*/ g_free (name); g_free (icon); } gtk_menu_shell_append (GTK_MENU_SHELL (dm_object->current_menu), item); } break; case DESKMENU_ELEMENT_ITEM: if (dm_object->current_item != NULL) { gint line_num, char_num; g_markup_parse_context_get_position (context, &line_num, &char_num); g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, "Error on line %d char %d: Element 'item' cannot be nested " "inside of another item element", line_num, char_num); return; } dm_object->current_item = g_slice_new0 (DeskmenuItem); while (*ncursor) { if (strcmp (*ncursor, "type") == 0) dm_object->current_item->type = GPOINTER_TO_INT (g_hash_table_lookup (item_hash, *vcursor)); else g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, "Unknown attribute: %s", *ncursor); ncursor++; vcursor++; } break; case DESKMENU_ELEMENT_NAME: while (*ncursor) { if ((strcmp (*ncursor, "mode") == 0) && (strcmp (*vcursor, "exec") == 0)) dm_object->current_item->name_exec = TRUE; ncursor++; vcursor++; } /* no break here to let it fall through */ case DESKMENU_ELEMENT_ICON: while (*ncursor) { if ((strcmp (*ncursor, "mode1") == 0) && (strcmp (*vcursor, "file") == 0)) dm_object->current_item->icon_file = TRUE; ncursor++; vcursor++; } /* no break here to let it fall through */ case DESKMENU_ELEMENT_VPICON: while (*ncursor) { if ((strcmp (*ncursor, "mode1") == 0) && (strcmp (*vcursor, "file") == 0)) dm_object->current_item->vpicon_file = TRUE; ncursor++; vcursor++; } /* no break here to let it fall through */ case DESKMENU_ELEMENT_COMMAND: while (*ncursor) { if ((strcmp (*ncursor, "mode2") == 0) && (strcmp (*vcursor, "pipe") == 0)) dm_object->current_item->command_pipe = TRUE; if (dm_object->current_item->command_pipe == TRUE && (strcmp (*ncursor, "cache") == 0) && (strcmp (*vcursor, "true") == 0)) dm_object->current_item->cache_output = TRUE; ncursor++; vcursor++; } /* no break here to let it fall through */ case DESKMENU_ELEMENT_WRAP: if (dm_object->current_item) dm_object->current_item->current_element = element_type; break; case DESKMENU_ELEMENT_THISVP: if (dm_object->current_item) dm_object->current_item->current_element = element_type; break; case DESKMENU_ELEMENT_MINIONLY: if (dm_object->current_item) dm_object->current_item->current_element = element_type; break; case DESKMENU_ELEMENT_QUANTITY: if (dm_object->current_item) dm_object->current_item->current_element = element_type; break; case DESKMENU_ELEMENT_SORT: if (dm_object->current_item) dm_object->current_item->current_element = element_type; break; case DESKMENU_ELEMENT_AGE: if (dm_object->current_item) dm_object->current_item->current_element = element_type; break; default: g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, "Unknown element: %s", element_name); break; } }
/* This is a _horrible_ hack to have this here. This needs to be added to the * GTK+ menuing code in some manner. */ static void drag_end_menu_cb (GtkWidget *widget, GdkDragContext *context) { GtkWidget *xgrab_shell; GtkWidget *parent; /* Find the last viewable ancestor, and make an X grab on it */ parent = gtk_widget_get_parent (widget); xgrab_shell = NULL; /* FIXME: workaround for a possible gtk+ bug * See bugs #92085(gtk+) and #91184(panel) for details. */ g_object_set (widget, "has-tooltip", TRUE, NULL); while (parent) { gboolean viewable = TRUE; GtkWidget *tmp = parent; while (tmp) { if (!gtk_widget_get_mapped (tmp)) { viewable = FALSE; break; } tmp = gtk_widget_get_parent (tmp); } if (viewable) xgrab_shell = parent; #if GTK_CHECK_VERSION (3, 0, 0) parent = gtk_menu_shell_get_parent_shell (GTK_MENU_SHELL (parent)); #else parent = GTK_MENU_SHELL (parent)->parent_menu_shell; #endif } #if GTK_CHECK_VERSION (3, 0, 0) if (xgrab_shell) #else if (xgrab_shell && !gtk_menu_get_tearoff_state (GTK_MENU(xgrab_shell))) #endif { #if GTK_CHECK_VERSION (3, 0, 0) gboolean status; GdkDisplay *display; GdkDevice *pointer; GdkDevice *keyboard; #if GTK_CHECK_VERSION(3, 20, 0) GdkSeat *seat; #else GdkDeviceManager *device_manager; #endif #endif GdkWindow *window = gtk_widget_get_window (xgrab_shell); GdkCursor *cursor = gdk_cursor_new_for_display (gdk_display_get_default (), GDK_ARROW); #if GTK_CHECK_VERSION (3, 0, 0) display = gdk_window_get_display (window); #if GTK_CHECK_VERSION(3, 20, 0) seat = gdk_display_get_default_seat (display); pointer = gdk_seat_get_pointer (seat); #else device_manager = gdk_display_get_device_manager (display); pointer = gdk_device_manager_get_client_pointer (device_manager); #endif keyboard = gdk_device_get_associated_device (pointer); /* FIXMEgpoo: Not sure if report to GDK_OWNERSHIP_WINDOW or GDK_OWNERSHIP_APPLICATION Idem for the keyboard below */ status = gdk_device_grab (pointer, window, GDK_OWNERSHIP_WINDOW, TRUE, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK, cursor, GDK_CURRENT_TIME); if (!status) { if (gdk_device_grab (keyboard, window, GDK_OWNERSHIP_WINDOW, TRUE, GDK_KEY_PRESS | GDK_KEY_RELEASE, NULL, GDK_CURRENT_TIME) == GDK_GRAB_SUCCESS) { #else if ((gdk_pointer_grab (window, TRUE, GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_ENTER_NOTIFY_MASK | GDK_LEAVE_NOTIFY_MASK | GDK_POINTER_MOTION_MASK, NULL, cursor, GDK_CURRENT_TIME) == 0)) { if (gdk_keyboard_grab (window, TRUE, GDK_CURRENT_TIME) == 0) { #endif /* FIXME fix for GTK3 */ #if !GTK_CHECK_VERSION (3, 0, 0) GTK_MENU_SHELL (xgrab_shell)->have_xgrab = TRUE; #endif } else { #if GTK_CHECK_VERSION (3, 0, 0) gdk_device_ungrab (pointer, GDK_CURRENT_TIME); } } g_object_unref (cursor); #else gdk_pointer_ungrab (GDK_CURRENT_TIME); } } gdk_cursor_unref (cursor); #endif } }
static void cb_tearoff_state_changed (GtkMenu *menu, G_GNUC_UNUSED GParamSpec *pspec, GOComboBox *combo) { combo->priv->torn_off = gtk_menu_get_tearoff_state (menu); }