示例#1
0
/* Specific "focus-out-event" handler for shortcut GtkEntry events */
static gboolean preferences_dialog_shortcut_focus_out_event(GtkWidget * widget, GdkEventFocus * event, gchar * s)
{
    guint key = 0;
    GdkModifierType mods = 0;
    const gchar * cur = gtk_entry_get_text(GTK_ENTRY(widget));
    GList * sib;

    if(g_strcmp0(s, cur) == 0)
        /* Nothing changed. */
        return FALSE;

    /* Look for dupplicate accelerator. */
    for(sib = gtk_container_get_children(GTK_CONTAINER(gtk_widget_get_parent(widget))); sib; sib = sib->next)
	if(GTK_IS_ENTRY(sib->data) && GTK_WIDGET(sib->data) != widget && !g_strcmp0(cur, gtk_entry_get_text(GTK_ENTRY(sib->data))))
	{
	    gtk_entry_set_text(GTK_ENTRY(widget), s);
	    return FALSE;
	}

    gtk_accelerator_parse(cur, &key, &mods);

    /* Make sure accelerator is valid. */
    if( ! (key == 0 && mods == 0) && gtk_accelerator_valid(key, mods))
    {
        g_free(s);
        s = g_strdup(cur);
    } else {
        gtk_entry_set_text(GTK_ENTRY(widget), s);
    }
    return FALSE;
}
示例#2
0
/**
 * dbusmenu_menuitem_property_set_shortcut:
 * @menuitem: The #DbusmenuMenuitem to set the shortcut on
 * @key: The keycode of the key to send
 * @modifier: A bitmask of modifiers used to activate the item
 * 
 * Takes the modifer described by @key and @modifier and places that into
 * the format sending across Dbus for shortcuts.
 * 
 * Return value: Whether it was successful at setting the property.
 */
gboolean
dbusmenu_menuitem_property_set_shortcut (DbusmenuMenuitem * menuitem, guint key, GdkModifierType modifier)
{
	g_return_val_if_fail(DBUSMENU_IS_MENUITEM(menuitem), FALSE);
	g_return_val_if_fail(gtk_accelerator_valid(key, modifier), FALSE);

	const gchar * keyname = gdk_keyval_name(key);
	g_return_val_if_fail(keyname != NULL, FALSE);

	GVariantBuilder builder;
	g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);

	if (modifier & GDK_CONTROL_MASK) {
		g_variant_builder_add(&builder, "s", DBUSMENU_MENUITEM_SHORTCUT_CONTROL);
	}
	if (modifier & GDK_MOD1_MASK) {
		g_variant_builder_add(&builder, "s", DBUSMENU_MENUITEM_SHORTCUT_ALT);
	}
	if (modifier & GDK_SHIFT_MASK) {
		g_variant_builder_add(&builder, "s", DBUSMENU_MENUITEM_SHORTCUT_SHIFT);
	}
	if (modifier & GDK_SUPER_MASK) {
		g_variant_builder_add(&builder, "s", DBUSMENU_MENUITEM_SHORTCUT_SUPER);
	}

	g_variant_builder_add(&builder, "s", keyname);

	GVariant * inside = g_variant_builder_end(&builder);
	g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
	g_variant_builder_add_value(&builder, inside);
	GVariant * outsidevariant = g_variant_builder_end(&builder);

	return dbusmenu_menuitem_property_set_variant(menuitem, DBUSMENU_MENUITEM_PROP_SHORTCUT, outsidevariant);
}
示例#3
0
void on_key_press_event(GtkWidget *self, GdkEventKey *event, gpointer v)
{
    KeyGrabButton* b = KEYGRAB_BUTTON(v);
    guint key;
    GdkModifierType mods = event->state & gtk_accelerator_get_default_mod_mask();

    if ((event->keyval == FcitxKey_Escape
            || event->keyval == FcitxKey_Return) && !mods) {
        if (event->keyval == FcitxKey_Escape)
            g_signal_emit_by_name(G_OBJECT(b), "changed", b->key, b->mods);
        end_key_grab(b);
        keygrab_button_set_key(b, 0, 0);
        return;
    }

    key = gdk_keyval_to_upper(event->keyval);
    if (key == FcitxKey_ISO_Left_Tab)
        key = FcitxKey_Tab;

    if (gtk_accelerator_valid(key, mods)
            || (key == FcitxKey_Tab && mods)) {
        keygrab_button_set_key(b, key, mods);
        end_key_grab(b);
        b->key = key;
        b->mods = mods;
        g_signal_emit_by_name(G_OBJECT(b), "changed", b->key, b->mods);
        return;
    }

    keygrab_button_set_key(b, key, mods);
}
示例#4
0
文件: snippets.c 项目: bqv/gummi-vim
void snippets_set_accelerator (GuSnippets* sc, gchar* config) {
    /* config has the form: Key,Accel_key,Name */
    GClosure* closure = NULL;
    GdkModifierType mod;
    guint keyval = 0;
    gchar** configs = g_strsplit (config, ",", 0);
    Tuple2* data = g_new0 (Tuple2, 1);
    Tuple2* closure_data = g_new0 (Tuple2, 1);

    /* Return if config does not contains accelerator */
    if (strlen (configs[1]) == 0) {
        g_strfreev (configs);
        return;
    }

    data->first = (gpointer)sc;
    data->second = (gpointer)g_strdup (configs[0]);


    closure = g_cclosure_new (G_CALLBACK (snippets_accel_cb), data, NULL);
    closure_data->first = (gpointer)data->second;
    closure_data->second = (gpointer)closure;

    sc->closure_data = g_list_append (sc->closure_data, closure_data);
    gtk_accelerator_parse (configs[1], &keyval, &mod);

    /* Return without connect if accel is not valid */
    if (!gtk_accelerator_valid (keyval, mod)) return;

    snippets_accel_connect (sc, keyval, mod, closure);
    g_strfreev (configs);
}
示例#5
0
void accel_group_remove_accelerator(ui::AccelGroup group, Accelerator accelerator ){
	if ( accelerator.key != 0 && gtk_accelerator_valid( accelerator.key, accelerator.modifiers ) ) {
		//globalOutputStream() << "global_accel_disconnect: " << makeQuoted(accelerator) << "\n";
		gtk_accel_group_disconnect_key( group, accelerator.key, accelerator.modifiers );
	}
	else
	{
		special_accelerators_remove( accelerator );
	}
}
示例#6
0
void accel_group_remove_accelerator(GtkAccelGroup* group, Accelerator accelerator)
{
  if(accelerator.key != 0 && gtk_accelerator_valid(accelerator.key, accelerator.modifiers))
  {
    gtk_accel_group_disconnect_key(group, accelerator.key, accelerator.modifiers);
  }
  else
  {
    special_accelerators_remove(accelerator);
  }
}
示例#7
0
GClosure* accel_group_add_accelerator(ui::AccelGroup group, Accelerator accelerator, const Callback<void()>& callback ){
	if ( accelerator.key != 0 && gtk_accelerator_valid( accelerator.key, accelerator.modifiers ) ) {
		//globalOutputStream() << "global_accel_connect: " << makeQuoted(accelerator) << "\n";
		GClosure* closure = create_cclosure( G_CALLBACK( accel_closure_callback ), callback );
		gtk_accel_group_connect( group, accelerator.key, accelerator.modifiers, GTK_ACCEL_VISIBLE, closure );
		return closure;
	}
	else
	{
		special_accelerators_add( accelerator, callback );
		return 0;
	}
}
示例#8
0
int
clip_GTK_ACCELERATORVALID(ClipMachine * ClipMachineMemory)
{
   guint     keyval = _clip_parni(ClipMachineMemory, 1);

   GdkModifierType modifiers = _clip_parni(ClipMachineMemory, 2);

   CHECKARG(1, NUMERIC_type_of_ClipVarType);
   CHECKARG(2, NUMERIC_type_of_ClipVarType);

   _clip_retl(ClipMachineMemory, gtk_accelerator_valid(keyval, modifiers));
   return 0;
 err:
   return 1;
}
示例#9
0
GClosure* accel_group_add_accelerator(GtkAccelGroup* group, Accelerator accelerator, const Callback& callback)
{
  if(accelerator.key != 0 && gtk_accelerator_valid(accelerator.key, accelerator.modifiers))
  {
    //globalOutputStream() << "adding accelerator: " << accelerator.key << " " << accelerator.modifiers << "\n";
    GClosure* closure = create_cclosure(G_CALLBACK(accel_closure_callback), callback);
    gtk_accel_group_connect(group, accelerator.key, accelerator.modifiers, GTK_ACCEL_VISIBLE, closure);
    return closure;
  }
  else
  {
    special_accelerators_add(accelerator, callback);
    return 0;
  }
}
示例#10
0
/**
 * dbusmenu_menuitem_property_set_shortcut_menuitem:
 * @menuitem: The #DbusmenuMenuitem to set the shortcut on
 * @gmi: A menu item to steal the shortcut off of
 * 
 * Takes the shortcut that is installed on a menu item and calls
 * #dbusmenu_menuitem_property_set_shortcut with it.  It also sets
 * up listeners to watch it change.
 * 
 * Return value: Whether it was successful at setting the property.
 */
gboolean
dbusmenu_menuitem_property_set_shortcut_menuitem (DbusmenuMenuitem * menuitem, const GtkMenuItem * gmi)
{
	g_return_val_if_fail(DBUSMENU_IS_MENUITEM(menuitem), FALSE);
	g_return_val_if_fail(GTK_IS_MENU_ITEM(gmi), FALSE);

	GClosure * closure = NULL;
        GtkWidget *label = gtk_bin_get_child(GTK_BIN (gmi));

        if (GTK_IS_ACCEL_LABEL (label))
          {
            g_object_get (label,
                          "accel-closure", &closure,
                          NULL);
          }

        if (closure == NULL) {
          /* As a fallback, check for a closure in the related menu item.  This
             actually happens with SWT menu items. */
          GList * closures = gtk_widget_list_accel_closures (GTK_WIDGET (gmi));
          if (closures == NULL)
            return FALSE;
          closure = closures->data;
          g_list_free (closures);
	}

	GtkAccelGroup * group = gtk_accel_group_from_accel_closure(closure);

	/* Apparently this is more common than I thought. */
	if (group == NULL) {
		return FALSE;
	}

	GtkAccelKey * key = gtk_accel_group_find(group, find_closure, closure);
	/* Again, not much we can do except complain loudly. */
	g_return_val_if_fail(key != NULL, FALSE);

        if (!gtk_accelerator_valid (key->accel_key, key->accel_mods))
            return FALSE;

	return dbusmenu_menuitem_property_set_shortcut(menuitem, key->accel_key, key->accel_mods);
}
示例#11
0
static gboolean
gimp_ui_manager_item_key_press (GtkWidget     *widget,
                                GdkEventKey   *kevent,
                                GimpUIManager *manager)
{
  gchar *help_id = NULL;

  while (! help_id)
    {
      GtkWidget *menu_item = GTK_MENU_SHELL (widget)->active_menu_item;

      if (! menu_item && GTK_IS_MENU (widget))
        {
          GtkWidget *parent = gtk_widget_get_parent (widget);
          GdkWindow *window = gtk_widget_get_window (parent);
          gint       x, y;

          gdk_window_get_pointer (window, &x, &y, NULL);
          menu_item = find_widget_under_pointer (window, &x, &y);

          if (menu_item && ! GTK_IS_MENU_ITEM (menu_item))
            {
              menu_item = gtk_widget_get_ancestor (menu_item,
                                                   GTK_TYPE_MENU_ITEM);

              if (! GTK_IS_MENU_ITEM (menu_item))
                menu_item = NULL;
            }
        }

      /*  first, get the help page from the item...
       */
      if (menu_item)
        {
          help_id = g_object_get_qdata (G_OBJECT (menu_item), GIMP_HELP_ID);

          if (help_id && ! strlen (help_id))
            help_id = NULL;
        }

      /*  ...then try the parent menu...
       */
      if (! help_id)
        {
          help_id = g_object_get_qdata (G_OBJECT (widget), GIMP_HELP_ID);

          if (help_id && ! strlen (help_id))
            help_id = NULL;
        }

      /*  ...finally try the menu's parent (if any)
       */
      if (! help_id)
        {
          menu_item = NULL;

          if (GTK_IS_MENU (widget))
            menu_item = gtk_menu_get_attach_widget (GTK_MENU (widget));

          if (! menu_item)
            break;

          widget = gtk_widget_get_parent (menu_item);

          if (! widget)
            break;
        }
    }

  /*  For any valid accelerator key except F1, continue with the
   *  standard GtkMenuShell callback and assign a new shortcut, but
   *  don't assign a shortcut to the help menu entries ...
   */
  if (kevent->keyval != GDK_KEY_F1)
    {
      if (help_id                                   &&
          gtk_accelerator_valid (kevent->keyval, 0) &&
          (strcmp (help_id, GIMP_HELP_HELP)         == 0 ||
           strcmp (help_id, GIMP_HELP_HELP_CONTEXT) == 0))
        {
          return TRUE;
        }

      return FALSE;
    }

  /*  ...finally, if F1 was pressed over any menu, show its help page...  */

  if (help_id)
    {
      gchar *help_domain = NULL;
      gchar *help_string = NULL;
      gchar *domain_separator;

      help_id = g_strdup (help_id);

      domain_separator = strchr (help_id, '?');

      if (domain_separator)
        {
          *domain_separator = '\0';

          help_domain = g_strdup (help_id);
          help_string = g_strdup (domain_separator + 1);
        }
      else
        {
          help_string = g_strdup (help_id);
        }

      gimp_help (manager->gimp, NULL, help_domain, help_string);

      g_free (help_domain);
      g_free (help_string);
      g_free (help_id);
    }

  return TRUE;
}
示例#12
0
static gboolean
grab_key_callback (GtkWidget            *widget,
                   GdkEventKey          *event,
                   GtkCellRendererAccel *accel)
{
  GdkModifierType accel_mods = 0;
  guint accel_key;
  gchar *path;
  gboolean edited;
  gboolean cleared;
  GdkModifierType consumed_modifiers;
  GdkDisplay *display;

  display = gtk_widget_get_display (widget);

  if (event->is_modifier)
    return TRUE;

  edited = FALSE;
  cleared = FALSE;

  gdk_keymap_translate_keyboard_state (gdk_keymap_get_for_display (display),
				       event->hardware_keycode,
                                       event->state,
                                       event->group,
				       NULL, NULL, NULL, &consumed_modifiers);

  accel_key = gdk_keyval_to_lower (event->keyval);
  if (accel_key == GDK_ISO_Left_Tab) 
    accel_key = GDK_Tab;

  accel_mods = event->state & gtk_accelerator_get_default_mod_mask ();

  /* Filter consumed modifiers 
   */
  if (accel->accel_mode == GTK_CELL_RENDERER_ACCEL_MODE_GTK)
    accel_mods &= ~consumed_modifiers;
  
  /* Put shift back if it changed the case of the key, not otherwise.
   */
  if (accel_key != event->keyval)
    accel_mods |= GDK_SHIFT_MASK;
    
  if (accel_mods == 0)
    {
      switch (event->keyval)
	{
	case GDK_Escape:
	  goto out; /* cancel */
	case GDK_BackSpace:
	  /* clear the accelerator on Backspace */
	  cleared = TRUE;
	  goto out;
	default:
	  break;
	}
    }

  if (accel->accel_mode == GTK_CELL_RENDERER_ACCEL_MODE_GTK)
    {
      if (!gtk_accelerator_valid (accel_key, accel_mods))
	{
	  gtk_widget_error_bell (widget);

	  return TRUE;
	}
    }

  edited = TRUE;

 out:
  gdk_display_keyboard_ungrab (display, event->time);
  gdk_display_pointer_ungrab (display, event->time);

  path = g_strdup (g_object_get_data (G_OBJECT (accel->edit_widget), "gtk-cell-renderer-text"));

  gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (accel->edit_widget));
  gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (accel->edit_widget));
  accel->edit_widget = NULL;
  accel->grab_widget = NULL;
  
  if (edited)
    g_signal_emit (accel, signals[ACCEL_EDITED], 0, path, 
		   accel_key, accel_mods, event->hardware_keycode);
  else if (cleared)
    g_signal_emit (accel, signals[ACCEL_CLEARED], 0, path);

  g_free (path);

  return TRUE;
}
static gboolean grab_key_callback(GtkWidget* widget, GdkEventKey* event, void* data)
{
	GdkModifierType accel_mods = 0;
	guint accel_keyval;
	EggCellRendererKeys *keys;
	char *path;
	gboolean edited;
	gboolean cleared;
	GdkModifierType consumed_modifiers;
	guint upper;
	GdkModifierType ignored_modifiers;

	keys = EGG_CELL_RENDERER_KEYS(data);

	if (is_modifier(event->hardware_keycode))
	{
		return TRUE;
	}

	edited = FALSE;
	cleared = FALSE;

	consumed_modifiers = 0;
	gdk_keymap_translate_keyboard_state(gdk_keymap_get_default(),
		event->hardware_keycode,
		event->state,
		event->group,
		NULL, NULL, NULL, &consumed_modifiers);

	upper = event->keyval;
	accel_keyval = gdk_keyval_to_lower(upper);

	if (accel_keyval == GDK_ISO_Left_Tab)
	{
		accel_keyval = GDK_Tab;
	}

	/* Put shift back if it changed the case of the key, not otherwise. */
	if (upper != accel_keyval && (consumed_modifiers & GDK_SHIFT_MASK))
	{
		consumed_modifiers &= ~(GDK_SHIFT_MASK);
	}

	egg_keymap_resolve_virtual_modifiers(gdk_keymap_get_default(),
		EGG_VIRTUAL_NUM_LOCK_MASK |
		EGG_VIRTUAL_SCROLL_LOCK_MASK |
		EGG_VIRTUAL_LOCK_MASK,
		&ignored_modifiers);

	/* http://bugzilla.gnome.org/show_bug.cgi?id=139605
	 * mouse keys should effect keybindings */
	ignored_modifiers |= GDK_BUTTON1_MASK |
		GDK_BUTTON2_MASK |
		GDK_BUTTON3_MASK |
		GDK_BUTTON4_MASK |
		GDK_BUTTON5_MASK;

	/* filter consumed/ignored modifiers */
	if (keys->accel_mode == EGG_CELL_RENDERER_KEYS_MODE_GTK)
	{
		accel_mods = event->state & GDK_MODIFIER_MASK & ~(consumed_modifiers | ignored_modifiers);
	}
	else if (keys->accel_mode == EGG_CELL_RENDERER_KEYS_MODE_X)
	{
		accel_mods = event->state & GDK_MODIFIER_MASK & ~(ignored_modifiers);
	}
	else
	{
		g_assert_not_reached();
	}

	if (accel_mods == 0 && accel_keyval == GDK_Escape)
	{
		goto out; /* cancel */
	}

	/* clear the accelerator on Backspace */
	if (accel_mods == 0 && accel_keyval == GDK_BackSpace)
	{
		cleared = TRUE;
		goto out;
	}

	if (keys->accel_mode == EGG_CELL_RENDERER_KEYS_MODE_GTK)
	{
		if (!gtk_accelerator_valid (accel_keyval, accel_mods))
		{
			accel_keyval = 0;
			accel_mods = 0;
		}
	}

	edited = TRUE;

	out:

	gdk_keyboard_ungrab(event->time);
	gdk_pointer_ungrab(event->time);

	path = g_strdup(g_object_get_data(G_OBJECT(keys->edit_widget), EGG_CELL_RENDERER_TEXT_PATH));

	gtk_cell_editable_editing_done(GTK_CELL_EDITABLE(keys->edit_widget));
	gtk_cell_editable_remove_widget(GTK_CELL_EDITABLE(keys->edit_widget));
	keys->edit_widget = NULL;
	keys->grab_widget = NULL;

	if (edited)
	{
		g_signal_emit_by_name(G_OBJECT(keys), "accel_edited", path, accel_keyval, accel_mods, event->hardware_keycode);
	}
	else if (cleared)
	{
		g_signal_emit_by_name(G_OBJECT(keys), "accel_cleared", path);
	}

	g_free (path);
	return TRUE;
}