Compare commits
12 Commits
slice-list
...
widget-cla
Author | SHA1 | Date | |
---|---|---|---|
|
07364bc597 | ||
|
8634082fe3 | ||
|
f4f09d15a8 | ||
|
c173b54195 | ||
|
7d7e592183 | ||
|
615e5a7575 | ||
|
e01fa6234e | ||
|
2ecf4b3049 | ||
|
b1650d5988 | ||
|
259c264fd0 | ||
|
859595d1cd | ||
|
e06cdcdf16 |
@@ -258,9 +258,11 @@
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Actions are added to their relevant scope (application or
|
||||
window) either using the GActionMap interface, or by using
|
||||
gtk_widget_insert_action_group().
|
||||
Actions are added to their relevant scope (application,
|
||||
window or widget) either using the GActionMap interface,
|
||||
or by using gtk_widget_insert_action_group(). Actions that
|
||||
will be the same for all instances of a widget class can
|
||||
be added globally using gtk_widget_class_install_action().
|
||||
</para>
|
||||
|
||||
</refsect2>
|
||||
@@ -317,8 +319,8 @@
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Another of obtaining widgets that are connected to actions is
|
||||
to create a menu using a GMenu menu model. GMenu provides an
|
||||
Another way of obtaining widgets that are connected to actions
|
||||
is to create a menu using a GMenu menu model. GMenu provides an
|
||||
abstract way to describe typical menus: nested groups of items
|
||||
where each item can have a label, and icon, and an action.
|
||||
</para>
|
||||
@@ -364,6 +366,25 @@
|
||||
(typically a GtkWindow, GtkDialog or GtkPopover)
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>clipboard.cut, clipboard.copy, clipboard.paste</term>
|
||||
<listitem><para>Clipboard operations on entries, text view
|
||||
and labels, typically used in the context menu
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>selection.delete, selection.select-all</term>
|
||||
<listitem><para>Selection operations on entries, text view
|
||||
and labels
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term>color.select, color.customize</term>
|
||||
<listitem><para>Operations on colors in GtkColorChooserWidget.
|
||||
These actions are unusual in that they have the non-trivial
|
||||
parameter type (dddd).
|
||||
</para></listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</para>
|
||||
|
||||
@@ -371,3 +392,4 @@
|
||||
|
||||
</refsect1>
|
||||
</refentry>
|
||||
</varlistentry>
|
||||
|
@@ -4549,10 +4549,6 @@ gtk_widget_get_opacity
|
||||
gtk_widget_set_opacity
|
||||
gtk_widget_get_overflow
|
||||
gtk_widget_set_overflow
|
||||
gtk_widget_insert_action_group
|
||||
gtk_widget_list_action_prefixes
|
||||
gtk_widget_activate_action
|
||||
gtk_widget_activate_default
|
||||
gtk_widget_measure
|
||||
gtk_widget_snapshot_child
|
||||
gtk_widget_get_next_sibling
|
||||
@@ -4629,6 +4625,19 @@ gtk_widget_class_set_connect_func
|
||||
gtk_widget_observe_children
|
||||
gtk_widget_observe_controllers
|
||||
|
||||
<SUBSECTION Actions>
|
||||
gtk_widget_insert_action_group
|
||||
gtk_widget_activate_action
|
||||
gtk_widget_activate_default
|
||||
GtkWidgetActionActivateFunc
|
||||
GtkWidgetActionSetStateFunc
|
||||
GtkWidgetActionGetStateFunc
|
||||
gtk_widget_class_install_action
|
||||
gtk_widget_class_install_stateful_action
|
||||
gtk_widget_notify_class_action_enabled
|
||||
gtk_widget_notify_class_action_state
|
||||
gtk_widget_class_bind_action
|
||||
|
||||
<SUBSECTION Standard>
|
||||
GTK_WIDGET
|
||||
GTK_IS_WIDGET
|
||||
|
@@ -72,6 +72,8 @@ struct _GtkActionMuxer
|
||||
GtkActionMuxer *parent;
|
||||
|
||||
GtkWidget *widget;
|
||||
GPtrArray *widget_actions;
|
||||
gboolean *widget_actions_enabled;
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GtkActionMuxer, gtk_action_muxer, G_TYPE_OBJECT,
|
||||
@@ -83,6 +85,7 @@ enum
|
||||
PROP_0,
|
||||
PROP_PARENT,
|
||||
PROP_WIDGET,
|
||||
PROP_WIDGET_ACTIONS,
|
||||
NUM_PROPERTIES
|
||||
};
|
||||
|
||||
@@ -108,7 +111,7 @@ typedef struct
|
||||
static void
|
||||
gtk_action_muxer_append_group_actions (const char *prefix,
|
||||
Group *group,
|
||||
GArray *actions)
|
||||
GHashTable *actions)
|
||||
{
|
||||
gchar **group_actions;
|
||||
gchar **action;
|
||||
@@ -116,10 +119,8 @@ gtk_action_muxer_append_group_actions (const char *prefix,
|
||||
group_actions = g_action_group_list_actions (group->group);
|
||||
for (action = group_actions; *action; action++)
|
||||
{
|
||||
gchar *fullname;
|
||||
|
||||
fullname = g_strconcat (prefix, ".", *action, NULL);
|
||||
g_array_append_val (actions, fullname);
|
||||
char *name = g_strconcat (prefix, ".", *action, NULL);
|
||||
g_hash_table_add (actions, name);
|
||||
}
|
||||
|
||||
g_strfreev (group_actions);
|
||||
@@ -129,9 +130,11 @@ static gchar **
|
||||
gtk_action_muxer_list_actions (GActionGroup *action_group)
|
||||
{
|
||||
GtkActionMuxer *muxer = GTK_ACTION_MUXER (action_group);
|
||||
GArray *actions;
|
||||
GHashTable *actions;
|
||||
char **keys;
|
||||
|
||||
actions = g_array_new (TRUE, FALSE, sizeof (gchar *));
|
||||
actions = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
g_free, NULL);
|
||||
|
||||
for ( ; muxer != NULL; muxer = muxer->parent)
|
||||
{
|
||||
@@ -139,12 +142,28 @@ gtk_action_muxer_list_actions (GActionGroup *action_group)
|
||||
const char *prefix;
|
||||
Group *group;
|
||||
|
||||
if (muxer->widget_actions)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < muxer->widget_actions->len; i++)
|
||||
{
|
||||
GtkWidgetAction *action = g_ptr_array_index (muxer->widget_actions, i);
|
||||
g_hash_table_add (actions, g_strdup (action->name));
|
||||
}
|
||||
}
|
||||
|
||||
g_hash_table_iter_init (&iter, muxer->groups);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *)&prefix, (gpointer *)&group))
|
||||
gtk_action_muxer_append_group_actions (prefix, group, actions);
|
||||
}
|
||||
|
||||
return (gchar **)(void *) g_array_free (actions, FALSE);
|
||||
keys = (char **)g_hash_table_get_keys_as_array (actions, NULL);
|
||||
|
||||
g_hash_table_steal_all (actions);
|
||||
g_hash_table_unref (actions);
|
||||
|
||||
return (char **)keys;
|
||||
}
|
||||
|
||||
static Group *
|
||||
@@ -183,7 +202,7 @@ gtk_action_muxer_find (GtkActionMuxer *muxer,
|
||||
return group->group;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gtk_action_muxer_action_enabled_changed (GtkActionMuxer *muxer,
|
||||
const gchar *action_name,
|
||||
gboolean enabled)
|
||||
@@ -191,6 +210,19 @@ gtk_action_muxer_action_enabled_changed (GtkActionMuxer *muxer,
|
||||
Action *action;
|
||||
GSList *node;
|
||||
|
||||
if (muxer->widget_actions)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < muxer->widget_actions->len; i++)
|
||||
{
|
||||
GtkWidgetAction *a = g_ptr_array_index (muxer->widget_actions, i);
|
||||
if (strcmp (a->name, action_name) == 0)
|
||||
{
|
||||
muxer->widget_actions_enabled[i] = enabled;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
action = g_hash_table_lookup (muxer->observed_actions, action_name);
|
||||
for (node = action ? action->watchers : NULL; node; node = node->next)
|
||||
gtk_action_observer_action_enabled_changed (node->data, GTK_ACTION_OBSERVABLE (muxer), action_name, enabled);
|
||||
@@ -223,7 +255,7 @@ gtk_action_muxer_parent_action_enabled_changed (GActionGroup *action_group,
|
||||
gtk_action_muxer_action_enabled_changed (muxer, action_name, enabled);
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
gtk_action_muxer_action_state_changed (GtkActionMuxer *muxer,
|
||||
const gchar *action_name,
|
||||
GVariant *state)
|
||||
@@ -401,6 +433,46 @@ gtk_action_muxer_query_action (GActionGroup *action_group,
|
||||
Group *group;
|
||||
const gchar *unprefixed_name;
|
||||
|
||||
if (muxer->widget_actions)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < muxer->widget_actions->len; i++)
|
||||
{
|
||||
GtkWidgetAction *action = g_ptr_array_index (muxer->widget_actions, i);
|
||||
if (strcmp (action->name, action_name) == 0)
|
||||
{
|
||||
if (enabled)
|
||||
*enabled = muxer->widget_actions_enabled[i];
|
||||
if (parameter_type)
|
||||
*parameter_type = action->parameter_type;
|
||||
|
||||
if (state_hint)
|
||||
*state_hint = NULL;
|
||||
if (state_type)
|
||||
*state_type = NULL;
|
||||
if (state)
|
||||
*state = NULL;
|
||||
|
||||
if (action->get_state)
|
||||
{
|
||||
GVariant *s;
|
||||
|
||||
s = g_variant_ref_sink (action->get_state (muxer->widget, action->name));
|
||||
|
||||
if (state_type)
|
||||
*state_type = g_variant_get_type (s);
|
||||
if (state)
|
||||
*state = g_variant_ref (s);
|
||||
|
||||
g_variant_unref (s);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group = gtk_action_muxer_find_group (muxer, action_name, &unprefixed_name);
|
||||
|
||||
if (group)
|
||||
@@ -424,6 +496,22 @@ gtk_action_muxer_activate_action (GActionGroup *action_group,
|
||||
Group *group;
|
||||
const gchar *unprefixed_name;
|
||||
|
||||
if (muxer->widget_actions)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < muxer->widget_actions->len; i++)
|
||||
{
|
||||
GtkWidgetAction *action = g_ptr_array_index (muxer->widget_actions, i);
|
||||
if (strcmp (action->name, action_name) == 0)
|
||||
{
|
||||
action->activate (muxer->widget, action->name, parameter);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group = gtk_action_muxer_find_group (muxer, action_name, &unprefixed_name);
|
||||
|
||||
if (group)
|
||||
@@ -441,6 +529,23 @@ gtk_action_muxer_change_action_state (GActionGroup *action_group,
|
||||
Group *group;
|
||||
const gchar *unprefixed_name;
|
||||
|
||||
if (muxer->widget_actions)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < muxer->widget_actions->len; i++)
|
||||
{
|
||||
GtkWidgetAction *action = g_ptr_array_index (muxer->widget_actions, i);
|
||||
if (strcmp (action->name, action_name) == 0)
|
||||
{
|
||||
if (action->set_state)
|
||||
action->set_state (muxer->widget, action->name, state);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group = gtk_action_muxer_find_group (muxer, action_name, &unprefixed_name);
|
||||
|
||||
if (group)
|
||||
@@ -600,6 +705,10 @@ gtk_action_muxer_get_property (GObject *object,
|
||||
g_value_set_object (value, muxer->widget);
|
||||
break;
|
||||
|
||||
case PROP_WIDGET_ACTIONS:
|
||||
g_value_set_boxed (value, muxer->widget_actions);
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
@@ -623,6 +732,18 @@ gtk_action_muxer_set_property (GObject *object,
|
||||
muxer->widget = g_value_get_object (value);
|
||||
break;
|
||||
|
||||
case PROP_WIDGET_ACTIONS:
|
||||
muxer->widget_actions = g_value_get_boxed (value);
|
||||
if (muxer->widget_actions)
|
||||
{
|
||||
int i;
|
||||
|
||||
muxer->widget_actions_enabled = g_new (gboolean, muxer->widget_actions->len);
|
||||
for (i = 0; i < muxer->widget_actions->len; i++)
|
||||
muxer->widget_actions_enabled[i] = TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
|
||||
}
|
||||
@@ -683,6 +804,13 @@ gtk_action_muxer_class_init (GObjectClass *class)
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
properties[PROP_WIDGET_ACTIONS] = g_param_spec_boxed ("widget-actions", "Widget actions",
|
||||
"Widget actions",
|
||||
G_TYPE_PTR_ARRAY,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT_ONLY |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties (class, NUM_PROPERTIES, properties);
|
||||
}
|
||||
|
||||
@@ -791,14 +919,17 @@ gtk_action_muxer_lookup (GtkActionMuxer *muxer,
|
||||
/*< private >
|
||||
* gtk_action_muxer_new:
|
||||
* @widget: the widget to which the muxer belongs
|
||||
* @actions: widget actions
|
||||
*
|
||||
* Creates a new #GtkActionMuxer.
|
||||
*/
|
||||
GtkActionMuxer *
|
||||
gtk_action_muxer_new (GtkWidget *widget)
|
||||
gtk_action_muxer_new (GtkWidget *widget,
|
||||
GPtrArray *actions)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_ACTION_MUXER,
|
||||
"widget", widget,
|
||||
"widget-actions", actions,
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
@@ -31,10 +31,21 @@ G_BEGIN_DECLS
|
||||
#define GTK_IS_ACTION_MUXER(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
|
||||
GTK_TYPE_ACTION_MUXER))
|
||||
|
||||
typedef struct {
|
||||
char *name;
|
||||
|
||||
GVariantType *parameter_type;
|
||||
|
||||
GtkWidgetActionActivateFunc activate;
|
||||
GtkWidgetActionSetStateFunc set_state;
|
||||
GtkWidgetActionGetStateFunc get_state;
|
||||
} GtkWidgetAction;
|
||||
|
||||
typedef struct _GtkActionMuxer GtkActionMuxer;
|
||||
|
||||
GType gtk_action_muxer_get_type (void);
|
||||
GtkActionMuxer * gtk_action_muxer_new (GtkWidget *widget);
|
||||
GtkActionMuxer * gtk_action_muxer_new (GtkWidget *widget,
|
||||
GPtrArray *actions);
|
||||
|
||||
void gtk_action_muxer_insert (GtkActionMuxer *muxer,
|
||||
const gchar *prefix,
|
||||
@@ -59,6 +70,16 @@ void gtk_action_muxer_set_primary_accel (GtkActi
|
||||
const gchar * gtk_action_muxer_get_primary_accel (GtkActionMuxer *muxer,
|
||||
const gchar *action_and_target);
|
||||
|
||||
void
|
||||
gtk_action_muxer_action_enabled_changed (GtkActionMuxer *muxer,
|
||||
const char *action_name,
|
||||
gboolean enabled);
|
||||
void
|
||||
gtk_action_muxer_action_state_changed (GtkActionMuxer *muxer,
|
||||
const gchar *action_name,
|
||||
GVariant *state);
|
||||
|
||||
|
||||
/* No better place for these... */
|
||||
gchar * gtk_print_action_and_target (const gchar *action_namespace,
|
||||
const gchar *action_name,
|
||||
|
@@ -394,7 +394,7 @@ gtk_application_init (GtkApplication *application)
|
||||
{
|
||||
GtkApplicationPrivate *priv = gtk_application_get_instance_private (application);
|
||||
|
||||
priv->muxer = gtk_action_muxer_new (NULL);
|
||||
priv->muxer = gtk_action_muxer_new (NULL, NULL);
|
||||
|
||||
priv->accels = gtk_application_accels_new ();
|
||||
}
|
||||
|
@@ -90,8 +90,6 @@ struct _GtkColorChooserWidgetPrivate
|
||||
gboolean has_default_palette;
|
||||
|
||||
GSettings *settings;
|
||||
|
||||
GActionMap *context_actions;
|
||||
};
|
||||
|
||||
enum
|
||||
@@ -493,11 +491,11 @@ add_default_palette (GtkColorChooserWidget *cc)
|
||||
}
|
||||
|
||||
static void
|
||||
customize_color (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_color_chooser_widget_activate_color_customize (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkColorChooserWidget *cc = user_data;
|
||||
GtkColorChooserWidget *cc = GTK_COLOR_CHOOSER_WIDGET (widget);
|
||||
GtkColorChooserWidgetPrivate *priv = gtk_color_chooser_widget_get_instance_private (cc);
|
||||
GdkRGBA color;
|
||||
|
||||
@@ -511,11 +509,11 @@ customize_color (GSimpleAction *action,
|
||||
}
|
||||
|
||||
static void
|
||||
select_color (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_color_chooser_widget_activate_color_select (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkColorChooserWidget *cc = user_data;
|
||||
GtkColorChooserWidget *cc = GTK_COLOR_CHOOSER_WIDGET (widget);
|
||||
GdkRGBA color;
|
||||
|
||||
g_variant_get (parameter, "(dddd)", &color.red, &color.green, &color.blue, &color.alpha);
|
||||
@@ -523,26 +521,6 @@ select_color (GSimpleAction *action,
|
||||
_gtk_color_chooser_color_activated (GTK_COLOR_CHOOSER (cc), &color);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_color_chooser_widget_add_context_actions (GtkColorChooserWidget *cc)
|
||||
{
|
||||
GtkColorChooserWidgetPrivate *priv = gtk_color_chooser_widget_get_instance_private (cc);
|
||||
|
||||
GActionEntry entries[] = {
|
||||
{ "select", select_color, "(dddd)", NULL, NULL },
|
||||
{ "customize", customize_color, "(dddd)", NULL, NULL },
|
||||
};
|
||||
|
||||
GSimpleActionGroup *actions = g_simple_action_group_new ();
|
||||
|
||||
priv->context_actions = G_ACTION_MAP (actions);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), cc);
|
||||
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (cc), "color", G_ACTION_GROUP (actions));
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_color_chooser_widget_init (GtkColorChooserWidget *cc)
|
||||
{
|
||||
@@ -634,8 +612,6 @@ gtk_color_chooser_widget_init (GtkColorChooserWidget *cc)
|
||||
priv->size_group = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
|
||||
gtk_size_group_add_widget (priv->size_group, priv->palette);
|
||||
gtk_size_group_add_widget (priv->size_group, box);
|
||||
|
||||
gtk_color_chooser_widget_add_context_actions (cc);
|
||||
}
|
||||
|
||||
/* GObject implementation {{{1 */
|
||||
@@ -736,6 +712,13 @@ gtk_color_chooser_widget_class_init (GtkColorChooserWidgetClass *class)
|
||||
FALSE, GTK_PARAM_READWRITE));
|
||||
|
||||
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), I_("colorchooser"));
|
||||
|
||||
gtk_widget_class_install_stateful_action (GTK_WIDGET_CLASS (class), "color.select",
|
||||
gtk_color_chooser_widget_activate_color_select,
|
||||
"(dddd)", NULL, NULL);
|
||||
gtk_widget_class_install_stateful_action (GTK_WIDGET_CLASS (class), "color.customize",
|
||||
gtk_color_chooser_widget_activate_color_customize,
|
||||
"(dddd)", NULL, NULL);
|
||||
}
|
||||
|
||||
/* GtkColorChooser implementation {{{1 */
|
||||
|
199
gtk/gtklabel.c
199
gtk/gtklabel.c
@@ -285,7 +285,6 @@ struct _GtkLabelPrivate
|
||||
PangoAttrList *markup_attrs;
|
||||
PangoLayout *layout;
|
||||
|
||||
GActionMap *context_actions;
|
||||
GtkWidget *popup_menu;
|
||||
GMenuModel *extra_menu;
|
||||
|
||||
@@ -575,8 +574,25 @@ static void gtk_label_drag_gesture_update (GtkGestureDrag *gesture,
|
||||
gdouble offset_y,
|
||||
GtkLabel *label);
|
||||
|
||||
static void gtk_label_add_context_actions (GtkLabel *label);
|
||||
static void gtk_label_update_clipboard_actions (GtkLabel *label);
|
||||
/* Actions */
|
||||
|
||||
static void gtk_label_activate_clipboard_copy (GtkWidget *label,
|
||||
const char *name,
|
||||
GVariant *parameter);
|
||||
static void gtk_label_activate_selection_select_all (GtkWidget *label,
|
||||
const char *name,
|
||||
GVariant *parameter);
|
||||
static void gtk_label_activate_link_open (GtkWidget *label,
|
||||
const char *name,
|
||||
GVariant *parameter);
|
||||
static void gtk_label_activate_link_copy (GtkWidget *label,
|
||||
const char *name,
|
||||
GVariant *parameter);
|
||||
static void gtk_label_nop (GtkWidget *label,
|
||||
const char *name,
|
||||
GVariant *parameter);
|
||||
|
||||
static void gtk_label_update_actions (GtkLabel *label);
|
||||
|
||||
static GtkSizeRequestMode gtk_label_get_request_mode (GtkWidget *widget);
|
||||
static void gtk_label_measure (GtkWidget *widget,
|
||||
@@ -1143,6 +1159,21 @@ gtk_label_class_init (GtkLabelClass *class)
|
||||
quark_mnemonics_visible_connected = g_quark_from_static_string ("gtk-label-mnemonics-visible-connected");
|
||||
quark_gtk_signal = g_quark_from_static_string ("gtk-signal");
|
||||
quark_link = g_quark_from_static_string ("link");
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.cut",
|
||||
gtk_label_nop);
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.copy",
|
||||
gtk_label_activate_clipboard_copy);
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.paste",
|
||||
gtk_label_nop);
|
||||
gtk_widget_class_install_action (widget_class, "selection.delete",
|
||||
gtk_label_nop);
|
||||
gtk_widget_class_install_action (widget_class, "selection.select-all",
|
||||
gtk_label_activate_selection_select_all);
|
||||
gtk_widget_class_install_action (widget_class, "link.open",
|
||||
gtk_label_activate_link_open);
|
||||
gtk_widget_class_install_action (widget_class, "link.copy",
|
||||
gtk_label_activate_link_copy);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1330,8 +1361,6 @@ gtk_label_init (GtkLabel *label)
|
||||
priv->mnemonic_window = NULL;
|
||||
|
||||
priv->mnemonics_visible = TRUE;
|
||||
|
||||
gtk_label_add_context_actions (label);
|
||||
}
|
||||
|
||||
|
||||
@@ -3205,7 +3234,6 @@ gtk_label_finalize (GObject *object)
|
||||
gtk_label_clear_links (label);
|
||||
g_free (priv->select_info);
|
||||
|
||||
g_clear_object (&priv->context_actions);
|
||||
g_clear_pointer (&priv->popup_menu, gtk_widget_unparent);
|
||||
g_clear_object (&priv->extra_menu);
|
||||
|
||||
@@ -4854,6 +4882,8 @@ gtk_label_update_active_link (GtkWidget *widget,
|
||||
gtk_widget_queue_draw (widget);
|
||||
}
|
||||
}
|
||||
|
||||
gtk_label_update_actions (label);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5295,6 +5325,8 @@ gtk_label_select_region_index (GtkLabel *label,
|
||||
}
|
||||
}
|
||||
|
||||
gtk_label_update_actions (label);
|
||||
|
||||
gtk_widget_queue_draw (GTK_WIDGET (label));
|
||||
|
||||
g_object_thaw_notify (G_OBJECT (label));
|
||||
@@ -5968,24 +6000,24 @@ gtk_label_select_all (GtkLabel *label)
|
||||
}
|
||||
|
||||
static void
|
||||
open_link_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_label_activate_link_open (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (user_data);
|
||||
GtkLabel *label = GTK_LABEL (widget);
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
GtkLabelLink *link = priv->select_info->context_link;
|
||||
GtkLabelLink *link = priv->select_info->context_link;
|
||||
|
||||
if (link)
|
||||
emit_activate_link (label, link);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_link_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_label_activate_link_copy (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (user_data);
|
||||
GtkLabel *label = GTK_LABEL (widget);
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
GtkLabelLink *link = priv->select_info->context_link;
|
||||
|
||||
@@ -5993,101 +6025,60 @@ copy_link_activated (GSimpleAction *action,
|
||||
{
|
||||
GdkClipboard *clipboard;
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (label));
|
||||
clipboard = gtk_widget_get_clipboard (widget);
|
||||
gdk_clipboard_set_text (clipboard, link->uri);
|
||||
}
|
||||
else
|
||||
g_print ("no link ?!\n");
|
||||
}
|
||||
|
||||
static void
|
||||
copy_clipboard_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_label_activate_clipboard_copy (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
g_signal_emit_by_name (user_data, "copy-clipboard");
|
||||
g_signal_emit_by_name (widget, "copy-clipboard");
|
||||
}
|
||||
|
||||
static void
|
||||
select_all_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_label_activate_selection_select_all (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
gtk_label_select_all (GTK_LABEL (user_data));
|
||||
gtk_label_select_all (GTK_LABEL (widget));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_update_clipboard_actions (GtkLabel *label)
|
||||
gtk_label_nop (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_update_actions (GtkLabel *label)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (label);
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
gboolean have_selection = FALSE;
|
||||
GAction *action;
|
||||
|
||||
if (priv->select_info)
|
||||
have_selection = priv->select_info->selection_anchor != priv->select_info->selection_end;
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "copy-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), have_selection);
|
||||
action = g_action_map_lookup_action (priv->context_actions, "select-all");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), gtk_label_get_selectable (label));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_label_update_link_actions (GtkLabel *label)
|
||||
{
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
gboolean have_selection = FALSE;
|
||||
GAction *action;
|
||||
gboolean has_selection;
|
||||
GtkLabelLink *link;
|
||||
|
||||
have_selection = priv->select_info->selection_anchor != priv->select_info->selection_end;
|
||||
if (priv->select_info)
|
||||
has_selection = priv->select_info->selection_anchor != priv->select_info->selection_end;
|
||||
else
|
||||
has_selection = FALSE;
|
||||
|
||||
if (priv->select_info->link_clicked)
|
||||
link = priv->select_info->active_link;
|
||||
else
|
||||
link = gtk_label_get_focus_link (label);
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "open-link");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), !have_selection && link);
|
||||
action = g_action_map_lookup_action (priv->context_actions, "copy-link");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), !have_selection && link);
|
||||
}
|
||||
gtk_widget_notify_class_action_enabled (widget, "clipboard.copy", has_selection);
|
||||
gtk_widget_notify_class_action_enabled (widget, "selection.select-all",
|
||||
gtk_label_get_selectable (label));
|
||||
|
||||
static void
|
||||
gtk_label_add_context_actions (GtkLabel *label)
|
||||
{
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
|
||||
GActionEntry entries[] = {
|
||||
{ "cut-clipboard", NULL, NULL, NULL, NULL },
|
||||
{ "copy-clipboard", copy_clipboard_activated, NULL, NULL, NULL },
|
||||
{ "paste-clipboard", NULL, NULL, NULL, NULL },
|
||||
{ "delete-selection", NULL, NULL, NULL, NULL },
|
||||
{ "select-all", select_all_activated, NULL, NULL, NULL },
|
||||
{ "open-link", open_link_activated, NULL, NULL, NULL },
|
||||
{ "copy-link", copy_link_activated, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
GSimpleActionGroup *actions = g_simple_action_group_new ();
|
||||
GAction *action;
|
||||
|
||||
priv->context_actions = G_ACTION_MAP (actions);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), label);
|
||||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "cut-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "copy-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "paste-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "delete-selection");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "select-all");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "open-link");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "copy-link");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (label), "context", G_ACTION_GROUP (actions));
|
||||
gtk_widget_notify_class_action_enabled (widget, "link.open", !has_selection && link);
|
||||
gtk_widget_notify_class_action_enabled (widget, "link.copy", !has_selection && link);
|
||||
}
|
||||
|
||||
static GMenuModel *
|
||||
@@ -6100,24 +6091,24 @@ gtk_label_get_menu_model (GtkLabel *label)
|
||||
menu = g_menu_new ();
|
||||
|
||||
section = g_menu_new ();
|
||||
g_menu_append (section, _("Cu_t"), "context.cut-clipboard");
|
||||
g_menu_append (section, _("_Copy"), "context.copy-clipboard");
|
||||
g_menu_append (section, _("_Paste"), "context.paste-clipboard");
|
||||
g_menu_append (section, _("_Delete"), "context.delete-selection");
|
||||
g_menu_append (section, _("Cu_t"), "clipboard.cut");
|
||||
g_menu_append (section, _("_Copy"), "clipboard.copy");
|
||||
g_menu_append (section, _("_Paste"), "clipboard.paste");
|
||||
g_menu_append (section, _("_Delete"), "selection.delete");
|
||||
g_menu_append_section (menu, NULL, G_MENU_MODEL (section));
|
||||
g_object_unref (section);
|
||||
|
||||
section = g_menu_new ();
|
||||
g_menu_append (section, _("Select _All"), "context.select-all");
|
||||
g_menu_append (section, _("Select _All"), "selection.select-all");
|
||||
g_menu_append_section (menu, NULL, G_MENU_MODEL (section));
|
||||
g_object_unref (section);
|
||||
|
||||
section = g_menu_new ();
|
||||
item = g_menu_item_new (_("_Open Link"), "context.open-link");
|
||||
item = g_menu_item_new (_("_Open Link"), "link.open");
|
||||
g_menu_item_set_attribute (item, "hidden-when", "s", "action-disabled");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
item = g_menu_item_new (_("Copy _Link Address"), "context.copy-link");
|
||||
item = g_menu_item_new (_("Copy _Link Address"), "link.copy");
|
||||
g_menu_item_set_attribute (item, "hidden-when", "s", "action-disabled");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
@@ -6137,8 +6128,15 @@ gtk_label_do_popup (GtkLabel *label,
|
||||
{
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
|
||||
gtk_label_update_clipboard_actions (label);
|
||||
gtk_label_update_link_actions (label);
|
||||
if (!priv->select_info)
|
||||
return;
|
||||
|
||||
if (priv->select_info->link_clicked)
|
||||
priv->select_info->context_link = priv->select_info->active_link;
|
||||
else
|
||||
priv->select_info->context_link = gtk_label_get_focus_link (label);
|
||||
|
||||
gtk_label_update_actions (label);
|
||||
|
||||
if (!priv->popup_menu)
|
||||
{
|
||||
@@ -6169,15 +6167,6 @@ static gboolean
|
||||
gtk_label_popup_menu (GtkWidget *widget)
|
||||
{
|
||||
GtkLabel *label = GTK_LABEL (widget);
|
||||
GtkLabelPrivate *priv = gtk_label_get_instance_private (label);
|
||||
|
||||
if (!priv->select_info)
|
||||
return FALSE;
|
||||
|
||||
if (priv->select_info->link_clicked)
|
||||
priv->select_info->context_link = priv->select_info->active_link;
|
||||
else
|
||||
priv->select_info->context_link = gtk_label_get_focus_link (label);
|
||||
|
||||
gtk_label_do_popup (label, -1, -1);
|
||||
return TRUE;
|
||||
|
@@ -96,7 +96,6 @@ struct _GtkLinkButtonPrivate
|
||||
|
||||
gboolean visited;
|
||||
|
||||
GActionMap *context_actions;
|
||||
GtkWidget *popup_menu;
|
||||
};
|
||||
|
||||
@@ -152,6 +151,17 @@ static guint link_signals[LAST_SIGNAL] = { 0, };
|
||||
|
||||
G_DEFINE_TYPE_WITH_PRIVATE (GtkLinkButton, gtk_link_button, GTK_TYPE_BUTTON)
|
||||
|
||||
static void
|
||||
gtk_link_button_activate_clipboard_copy (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkLinkButton *link_button = GTK_LINK_BUTTON (widget);
|
||||
GtkLinkButtonPrivate *priv = gtk_link_button_get_instance_private (link_button);
|
||||
|
||||
gdk_clipboard_set_text (gtk_widget_get_clipboard (widget), priv->uri);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_link_button_class_init (GtkLinkButtonClass *klass)
|
||||
{
|
||||
@@ -221,28 +231,9 @@ gtk_link_button_class_init (GtkLinkButtonClass *klass)
|
||||
|
||||
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_LINK_BUTTON_ACCESSIBLE);
|
||||
gtk_widget_class_set_css_name (widget_class, I_("button"));
|
||||
}
|
||||
|
||||
static void copy_activate_cb (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data);
|
||||
|
||||
static void
|
||||
gtk_link_button_add_context_actions (GtkLinkButton *link_button)
|
||||
{
|
||||
GtkLinkButtonPrivate *priv = gtk_link_button_get_instance_private (link_button);
|
||||
|
||||
GActionEntry entries[] = {
|
||||
{ "copy-clipboard", copy_activate_cb, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
GSimpleActionGroup *actions = g_simple_action_group_new ();
|
||||
|
||||
priv->context_actions = G_ACTION_MAP (actions);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), link_button);
|
||||
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (link_button), "context", G_ACTION_GROUP (actions));
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.copy",
|
||||
gtk_link_button_activate_clipboard_copy);
|
||||
}
|
||||
|
||||
static GMenuModel *
|
||||
@@ -298,7 +289,6 @@ gtk_link_button_init (GtkLinkButton *link_button)
|
||||
gtk_style_context_add_class (context, "link");
|
||||
|
||||
gtk_widget_set_cursor_from_name (GTK_WIDGET (link_button), "pointer");
|
||||
gtk_link_button_add_context_actions (link_button);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -309,7 +299,6 @@ gtk_link_button_finalize (GObject *object)
|
||||
|
||||
g_free (priv->uri);
|
||||
|
||||
g_clear_object (&priv->context_actions);
|
||||
g_clear_pointer (&priv->popup_menu, gtk_widget_unparent);
|
||||
|
||||
G_OBJECT_CLASS (gtk_link_button_parent_class)->finalize (object);
|
||||
@@ -360,18 +349,6 @@ gtk_link_button_set_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
copy_activate_cb (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkLinkButton *link_button = user_data;
|
||||
GtkLinkButtonPrivate *priv = gtk_link_button_get_instance_private (link_button);
|
||||
|
||||
gdk_clipboard_set_text (gtk_widget_get_clipboard (GTK_WIDGET (link_button)),
|
||||
priv->uri);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_link_button_do_popup (GtkLinkButton *link_button,
|
||||
double x,
|
||||
|
@@ -110,20 +110,30 @@ focus_changed (GtkWidget *widget)
|
||||
|
||||
static void
|
||||
gtk_password_entry_toggle_peek (GtkPasswordEntry *entry)
|
||||
{
|
||||
GtkPasswordEntryPrivate *priv = gtk_password_entry_get_instance_private (entry);
|
||||
gboolean visibility;
|
||||
|
||||
visibility = gtk_text_get_visibility (GTK_TEXT (priv->entry));
|
||||
gtk_text_set_visibility (GTK_TEXT (priv->entry), !visibility);
|
||||
}
|
||||
|
||||
static void
|
||||
visibility_toggled (GObject *object,
|
||||
GParamSpec *pspec,
|
||||
GtkPasswordEntry *entry)
|
||||
{
|
||||
GtkPasswordEntryPrivate *priv = gtk_password_entry_get_instance_private (entry);
|
||||
|
||||
if (gtk_text_get_visibility (GTK_TEXT (priv->entry)))
|
||||
{
|
||||
gtk_text_set_visibility (GTK_TEXT (priv->entry), FALSE);
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (priv->peek_icon), "eye-not-looking-symbolic");
|
||||
gtk_widget_set_tooltip_text (priv->peek_icon, _("Show text"));
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (priv->peek_icon), "eye-open-negative-filled-symbolic");
|
||||
gtk_widget_set_tooltip_text (priv->peek_icon, _("Hide text"));
|
||||
}
|
||||
else
|
||||
{
|
||||
gtk_text_set_visibility (GTK_TEXT (priv->entry), TRUE);
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (priv->peek_icon), "eye-open-negative-filled-symbolic");
|
||||
gtk_widget_set_tooltip_text (priv->peek_icon, _("Hide text"));
|
||||
gtk_image_set_from_icon_name (GTK_IMAGE (priv->peek_icon), "eye-not-looking-symbolic");
|
||||
gtk_widget_set_tooltip_text (priv->peek_icon, _("Show text"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -482,11 +492,18 @@ gtk_password_entry_set_show_peek_icon (GtkPasswordEntry *entry,
|
||||
g_signal_connect_swapped (press, "released",
|
||||
G_CALLBACK (gtk_password_entry_toggle_peek), entry);
|
||||
gtk_widget_add_controller (priv->peek_icon, GTK_EVENT_CONTROLLER (press));
|
||||
|
||||
g_signal_connect (priv->entry, "notify::visibility",
|
||||
G_CALLBACK (visibility_toggled), entry);
|
||||
visibility_toggled (G_OBJECT (priv->entry), NULL, entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
g_clear_pointer (&priv->peek_icon, gtk_widget_unparent);
|
||||
gtk_text_set_visibility (GTK_TEXT (priv->entry), FALSE);
|
||||
g_signal_handlers_disconnect_by_func (priv->entry,
|
||||
visibility_toggled,
|
||||
entry);
|
||||
}
|
||||
|
||||
keymap_state_changed (priv->keymap, GTK_WIDGET (entry));
|
||||
@@ -532,13 +549,17 @@ gtk_password_entry_set_extra_menu (GtkPasswordEntry *entry,
|
||||
|
||||
g_return_if_fail (GTK_IS_PASSWORD_ENTRY (entry));
|
||||
|
||||
if (!g_set_object (&priv->extra_menu, model))
|
||||
return;
|
||||
/* bypass this check for the initial call from init */
|
||||
if (priv->extra_menu)
|
||||
{
|
||||
if (!g_set_object (&priv->extra_menu, model))
|
||||
return;
|
||||
}
|
||||
|
||||
menu = g_menu_new ();
|
||||
|
||||
section = g_menu_new ();
|
||||
item = g_menu_item_new (_("_Show Text"), "context.toggle-visibility");
|
||||
item = g_menu_item_new (_("_Show Text"), "misc.toggle-visibility");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "eye-not-looking-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
|
267
gtk/gtktext.c
267
gtk/gtktext.c
@@ -68,6 +68,7 @@
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkwindow.h"
|
||||
#include "gtknative.h"
|
||||
#include "gtkactionmuxerprivate.h"
|
||||
|
||||
#include "a11y/gtktextaccessible.h"
|
||||
|
||||
@@ -174,7 +175,6 @@ struct _GtkTextPrivate
|
||||
GtkCssNode *block_cursor_node;
|
||||
GtkCssNode *undershoot_node[2];
|
||||
|
||||
GActionMap *context_actions;
|
||||
GtkWidget *popup_menu;
|
||||
GMenuModel *extra_menu;
|
||||
|
||||
@@ -542,10 +542,35 @@ static void begin_change (GtkText *self);
|
||||
static void end_change (GtkText *self);
|
||||
static void emit_changed (GtkText *self);
|
||||
|
||||
static void gtk_text_add_context_actions (GtkText *self);
|
||||
static void gtk_text_update_clipboard_actions (GtkText *self);
|
||||
static void gtk_text_update_emoji_action (GtkText *self);
|
||||
|
||||
static void gtk_text_activate_clipboard_cut (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_activate_clipboard_copy (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_activate_clipboard_paste (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_activate_selection_delete (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_activate_selection_select_all (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_activate_misc_insert_emoji (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_activate_misc_toggle_visibility (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_set_misc_toggle_visibility (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *state);
|
||||
static GVariant *gtk_text_get_misc_toggle_visibility (GtkWidget *widget,
|
||||
const char *action_name);
|
||||
|
||||
/* GtkTextContent implementation
|
||||
*/
|
||||
@@ -706,7 +731,7 @@ gtk_text_class_init (GtkTextClass *class)
|
||||
class->toggle_overwrite = gtk_text_toggle_overwrite;
|
||||
class->insert_emoji = gtk_text_insert_emoji;
|
||||
class->activate = gtk_text_real_activate;
|
||||
|
||||
|
||||
quark_password_hint = g_quark_from_static_string ("gtk-entry-password-hint");
|
||||
quark_gtk_signal = g_quark_from_static_string ("gtk-signal");
|
||||
|
||||
@@ -1336,6 +1361,24 @@ gtk_text_class_init (GtkTextClass *class)
|
||||
|
||||
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_TEXT_ACCESSIBLE);
|
||||
gtk_widget_class_set_css_name (widget_class, I_("text"));
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.cut",
|
||||
gtk_text_activate_clipboard_cut);
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.copy",
|
||||
gtk_text_activate_clipboard_copy);
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.paste",
|
||||
gtk_text_activate_clipboard_paste);
|
||||
gtk_widget_class_install_action (widget_class, "selection.delete",
|
||||
gtk_text_activate_selection_delete);
|
||||
gtk_widget_class_install_action (widget_class, "selection.select-all",
|
||||
gtk_text_activate_selection_select_all);
|
||||
gtk_widget_class_install_action (widget_class, "misc.insert-emoji",
|
||||
gtk_text_activate_misc_insert_emoji);
|
||||
gtk_widget_class_install_stateful_action (widget_class, "misc.toggle-visibility",
|
||||
gtk_text_activate_misc_toggle_visibility,
|
||||
NULL,
|
||||
gtk_text_set_misc_toggle_visibility,
|
||||
gtk_text_get_misc_toggle_visibility);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1720,7 +1763,6 @@ gtk_text_init (GtkText *self)
|
||||
}
|
||||
|
||||
set_text_cursor (GTK_WIDGET (self));
|
||||
gtk_text_add_context_actions (self);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1766,7 +1808,7 @@ gtk_text_dispose (GObject *object)
|
||||
keymap = gdk_display_get_keymap (gtk_widget_get_display (GTK_WIDGET (object)));
|
||||
g_signal_handlers_disconnect_by_func (keymap, keymap_direction_changed, self);
|
||||
|
||||
g_clear_object (&priv->context_actions);
|
||||
g_clear_pointer (&priv->selection_bubble, gtk_widget_unparent);
|
||||
g_clear_pointer (&priv->popup_menu, gtk_widget_unparent);
|
||||
g_clear_object (&priv->extra_menu);
|
||||
|
||||
@@ -1783,7 +1825,6 @@ gtk_text_finalize (GObject *object)
|
||||
|
||||
g_clear_object (&priv->cached_layout);
|
||||
g_clear_object (&priv->im_context);
|
||||
g_clear_pointer (&priv->selection_bubble, gtk_widget_unparent);
|
||||
g_clear_pointer (&priv->magnifier_popover, gtk_widget_destroy);
|
||||
g_clear_object (&priv->text_handle);
|
||||
g_free (priv->im_module);
|
||||
@@ -2176,6 +2217,9 @@ gtk_text_size_allocate (GtkWidget *widget,
|
||||
|
||||
if (priv->popup_menu)
|
||||
gtk_native_check_resize (GTK_NATIVE (priv->popup_menu));
|
||||
|
||||
if (priv->selection_bubble)
|
||||
gtk_native_check_resize (GTK_NATIVE (priv->selection_bubble));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -4047,6 +4091,7 @@ gtk_text_set_positions (GtkText *self,
|
||||
|
||||
if (changed)
|
||||
{
|
||||
gtk_text_update_clipboard_actions (self);
|
||||
gtk_text_recompute (self);
|
||||
}
|
||||
}
|
||||
@@ -5261,15 +5306,14 @@ gtk_text_set_visibility (GtkText *self,
|
||||
|
||||
if (priv->visible != visible)
|
||||
{
|
||||
GAction *action;
|
||||
|
||||
priv->visible = visible;
|
||||
|
||||
g_object_notify (G_OBJECT (self), "visibility");
|
||||
gtk_text_recompute (self);
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "toggle-visibility");
|
||||
g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_boolean (visible));
|
||||
gtk_text_update_clipboard_actions (self);
|
||||
gtk_widget_notify_class_action_state (GTK_WIDGET (self), "misc.toggle-visibility",
|
||||
g_variant_new_boolean (visible));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5615,152 +5659,129 @@ hide_selection_bubble (GtkText *self)
|
||||
}
|
||||
|
||||
static void
|
||||
cut_clipboard_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_text_activate_clipboard_cut (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
g_signal_emit_by_name (user_data, "cut-clipboard");
|
||||
hide_selection_bubble (GTK_TEXT (user_data));
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
g_signal_emit_by_name (self, "cut-clipboard");
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
static void
|
||||
copy_clipboard_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_text_activate_clipboard_copy (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
g_signal_emit_by_name (user_data, "copy-clipboard");
|
||||
hide_selection_bubble (GTK_TEXT (user_data));
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
g_signal_emit_by_name (self, "copy-clipboard");
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
static void
|
||||
paste_clipboard_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_text_activate_clipboard_paste (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
g_signal_emit_by_name (user_data, "paste-clipboard");
|
||||
hide_selection_bubble (GTK_TEXT (user_data));
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
g_signal_emit_by_name (self, "paste-clipboard");
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_selection_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_text_activate_selection_delete (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
gtk_text_delete_cb (GTK_TEXT (user_data));
|
||||
hide_selection_bubble (GTK_TEXT (user_data));
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
gtk_text_delete_cb (self);
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
static void
|
||||
select_all_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_text_activate_selection_select_all (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
gtk_text_select_all (GTK_TEXT (user_data));
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
gtk_text_select_all (self);
|
||||
}
|
||||
|
||||
static void
|
||||
insert_emoji_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_text_activate_misc_insert_emoji (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
gtk_text_insert_emoji (GTK_TEXT (user_data));
|
||||
hide_selection_bubble (GTK_TEXT (user_data));
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
gtk_text_insert_emoji (self);
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
static void
|
||||
toggle_visibility (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
gtk_text_activate_misc_toggle_visibility (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkText *text = GTK_TEXT (user_data);
|
||||
gtk_text_set_visibility (text, !gtk_text_get_visibility (text));
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
gtk_text_set_visibility (self, !gtk_text_get_visibility (self));
|
||||
}
|
||||
|
||||
static GVariant *
|
||||
gtk_text_get_misc_toggle_visibility (GtkWidget *widget,
|
||||
const char *action_name)
|
||||
{
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
DisplayMode mode = gtk_text_get_display_mode (self);
|
||||
|
||||
return g_variant_new_boolean (mode == DISPLAY_NORMAL);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_add_context_actions (GtkText *self)
|
||||
gtk_text_set_misc_toggle_visibility (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *state)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
|
||||
GActionEntry entries[] = {
|
||||
{ "cut-clipboard", cut_clipboard_activated, NULL, NULL, NULL },
|
||||
{ "copy-clipboard", copy_clipboard_activated, NULL, NULL, NULL },
|
||||
{ "paste-clipboard", paste_clipboard_activated, NULL, NULL, NULL },
|
||||
{ "delete-selection", delete_selection_activated, NULL, NULL, NULL },
|
||||
{ "select-all", select_all_activated, NULL, NULL, NULL },
|
||||
{ "insert-emoji", insert_emoji_activated, NULL, NULL, NULL },
|
||||
{ "toggle-visibility", toggle_visibility, NULL, "true", NULL },
|
||||
};
|
||||
|
||||
GSimpleActionGroup *actions = g_simple_action_group_new ();
|
||||
GAction *action;
|
||||
|
||||
priv->context_actions = G_ACTION_MAP (actions);
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), self);
|
||||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "cut-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "copy-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "paste-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "delete-selection");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "select-all");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "insert-emoji");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (self), "context", G_ACTION_GROUP (actions));
|
||||
GtkText *self = GTK_TEXT (widget);
|
||||
gboolean visible = g_variant_get_boolean (state);
|
||||
gtk_text_set_visibility (self, visible);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_update_clipboard_actions (GtkText *self)
|
||||
{
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
DisplayMode mode;
|
||||
GdkClipboard *clipboard;
|
||||
gboolean has_clipboard;
|
||||
GAction *action;
|
||||
|
||||
gboolean has_selection;
|
||||
gboolean has_content;
|
||||
gboolean visible;
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (self));
|
||||
has_clipboard = gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), G_TYPE_STRING);
|
||||
mode = gtk_text_get_display_mode (self);
|
||||
has_clipboard = gdk_content_formats_contain_gtype (gdk_clipboard_get_formats (clipboard), G_TYPE_STRING);
|
||||
has_selection = priv->current_pos != priv->selection_bound;
|
||||
has_content = priv->buffer && (gtk_entry_buffer_get_length (priv->buffer) > 0);
|
||||
visible = mode == DISPLAY_NORMAL;
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "cut-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
mode == DISPLAY_NORMAL &&
|
||||
priv->editable &&
|
||||
priv->current_pos != priv->selection_bound);
|
||||
gtk_widget_notify_class_action_enabled (GTK_WIDGET (self), "clipboard.cut",
|
||||
visible && priv->editable && has_selection);
|
||||
gtk_widget_notify_class_action_enabled (GTK_WIDGET (self), "clipboard.copy",
|
||||
visible && has_selection);
|
||||
gtk_widget_notify_class_action_enabled (GTK_WIDGET (self), "clipboard.paste",
|
||||
priv->editable && has_clipboard);
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "copy-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
mode == DISPLAY_NORMAL &&
|
||||
priv->current_pos != priv->selection_bound);
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "paste-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
priv->editable && has_clipboard);
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "delete-selection");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
priv->editable &&
|
||||
priv->current_pos != priv->selection_bound);
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "select-all");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
priv->buffer && (gtk_entry_buffer_get_length (priv->buffer) > 0));
|
||||
gtk_widget_notify_class_action_enabled (GTK_WIDGET (self), "selection.delete",
|
||||
priv->editable && has_selection);
|
||||
gtk_widget_notify_class_action_enabled (GTK_WIDGET (self), "selection.select-all",
|
||||
has_content);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_update_emoji_action (GtkText *self)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
GAction *action;
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "insert-emoji");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
(gtk_text_get_input_hints (self) & GTK_INPUT_HINT_NO_EMOJI) == 0);
|
||||
gtk_widget_notify_class_action_enabled (GTK_WIDGET (self), "misc.insert-emoji",
|
||||
(gtk_text_get_input_hints (self) & GTK_INPUT_HINT_NO_EMOJI) == 0);
|
||||
}
|
||||
|
||||
static GMenuModel *
|
||||
@@ -5773,19 +5794,19 @@ gtk_text_get_menu_model (GtkText *self)
|
||||
menu = g_menu_new ();
|
||||
|
||||
section = g_menu_new ();
|
||||
item = g_menu_item_new (_("Cu_t"), "context.cut-clipboard");
|
||||
item = g_menu_item_new (_("Cu_t"), "clipboard.cut");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-cut-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
item = g_menu_item_new (_("_Copy"), "context.copy-clipboard");
|
||||
item = g_menu_item_new (_("_Copy"), "clipboard.copy");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-copy-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
item = g_menu_item_new (_("_Paste"), "context.paste-clipboard");
|
||||
item = g_menu_item_new (_("_Paste"), "clipboard.paste");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-paste-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
item = g_menu_item_new (_("_Delete"), "context.delete-selection");
|
||||
item = g_menu_item_new (_("_Delete"), "selection.delete");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-delete-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
@@ -5794,12 +5815,12 @@ gtk_text_get_menu_model (GtkText *self)
|
||||
|
||||
section = g_menu_new ();
|
||||
|
||||
item = g_menu_item_new (_("Select _All"), "context.select-all");
|
||||
item = g_menu_item_new (_("Select _All"), "selection.select-all");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-select-all-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
|
||||
item = g_menu_item_new ( _("Insert _Emoji"), "context.insert-emoji");
|
||||
item = g_menu_item_new ( _("Insert _Emoji"), "misc.insert-emoji");
|
||||
g_menu_item_set_attribute (item, "hidden-when", "s", "action-disabled");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "face-smile-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
@@ -5860,12 +5881,11 @@ append_bubble_item (GtkText *self,
|
||||
GMenuModel *model,
|
||||
int index)
|
||||
{
|
||||
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
|
||||
GtkActionMuxer *muxer;
|
||||
GtkWidget *item, *image;
|
||||
GVariant *att;
|
||||
const char *icon_name;
|
||||
const char *action_name;
|
||||
GAction *action;
|
||||
GMenuModel *link;
|
||||
|
||||
link = g_menu_model_get_item_link (model, index, "section");
|
||||
@@ -5891,12 +5911,9 @@ append_bubble_item (GtkText *self,
|
||||
action_name = g_variant_get_string (att, NULL);
|
||||
g_variant_unref (att);
|
||||
|
||||
if (g_str_has_prefix (action_name, "context."))
|
||||
{
|
||||
action = g_action_map_lookup_action (priv->context_actions, action_name + strlen ("context."));
|
||||
if (action && !g_action_get_enabled (action))
|
||||
return;
|
||||
}
|
||||
muxer = _gtk_widget_get_action_muxer (GTK_WIDGET (self), FALSE);
|
||||
if (!g_action_group_get_action_enabled (G_ACTION_GROUP (muxer), action_name))
|
||||
return;
|
||||
|
||||
item = gtk_button_new ();
|
||||
gtk_widget_set_focus_on_click (item, FALSE);
|
||||
@@ -5990,7 +6007,7 @@ gtk_text_selection_bubble_popup_show (gpointer user_data)
|
||||
rect.height += 10;
|
||||
|
||||
gtk_popover_set_pointing_to (GTK_POPOVER (priv->selection_bubble), &rect);
|
||||
gtk_widget_show (priv->selection_bubble);
|
||||
gtk_popover_popup (GTK_POPOVER (priv->selection_bubble));
|
||||
|
||||
priv->selection_bubble_timeout_id = 0;
|
||||
|
||||
|
@@ -182,8 +182,6 @@ struct _GtkTextViewPrivate
|
||||
GtkAdjustment *hadjustment;
|
||||
GtkAdjustment *vadjustment;
|
||||
|
||||
GActionMap *context_actions;
|
||||
|
||||
/* X offset between widget coordinates and buffer coordinates
|
||||
* taking left_padding in account
|
||||
*/
|
||||
@@ -595,10 +593,28 @@ static void extend_selection (GtkTextView *text_view,
|
||||
GtkTextIter *start,
|
||||
GtkTextIter *end);
|
||||
|
||||
static void gtk_text_view_add_context_actions (GtkTextView *text_view);
|
||||
|
||||
static void gtk_text_view_update_clipboard_actions (GtkTextView *text_view);
|
||||
static void gtk_text_view_update_emoji_action (GtkTextView *text_view);
|
||||
|
||||
static void gtk_text_view_activate_clipboard_cut (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_view_activate_clipboard_copy (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_view_activate_clipboard_paste (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_view_activate_selection_delete (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_view_activate_selection_select_all (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_text_view_activate_misc_insert_emoji (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
|
||||
|
||||
/* FIXME probably need the focus methods. */
|
||||
@@ -1585,6 +1601,19 @@ gtk_text_view_class_init (GtkTextViewClass *klass)
|
||||
quark_text_selection_data = g_quark_from_static_string ("gtk-text-view-text-selection-data");
|
||||
quark_gtk_signal = g_quark_from_static_string ("gtk-signal");
|
||||
quark_text_view_child = g_quark_from_static_string ("gtk-text-view-child");
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.cut",
|
||||
gtk_text_view_activate_clipboard_cut);
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.copy",
|
||||
gtk_text_view_activate_clipboard_copy);
|
||||
gtk_widget_class_install_action (widget_class, "clipboard.paste",
|
||||
gtk_text_view_activate_clipboard_paste);
|
||||
gtk_widget_class_install_action (widget_class, "selection.delete",
|
||||
gtk_text_view_activate_selection_delete);
|
||||
gtk_widget_class_install_action (widget_class, "selection.select-all",
|
||||
gtk_text_view_activate_selection_select_all);
|
||||
gtk_widget_class_install_action (widget_class, "misc.insert-emoji",
|
||||
gtk_text_view_activate_misc_insert_emoji);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1694,8 +1723,6 @@ gtk_text_view_init (GtkTextView *text_view)
|
||||
gtk_css_node_get_state (priv->text_window->css_node) & ~GTK_STATE_FLAG_DROP_ACTIVE);
|
||||
gtk_css_node_set_visible (priv->selection_node, FALSE);
|
||||
g_object_unref (priv->selection_node);
|
||||
|
||||
gtk_text_view_add_context_actions (text_view);
|
||||
}
|
||||
|
||||
GtkCssNode *
|
||||
@@ -3617,7 +3644,6 @@ gtk_text_view_finalize (GObject *object)
|
||||
g_free (priv->im_module);
|
||||
|
||||
g_clear_pointer (&priv->popup_menu, gtk_widget_unparent);
|
||||
g_clear_object (&priv->context_actions);
|
||||
g_clear_object (&priv->extra_menu);
|
||||
|
||||
G_OBJECT_CLASS (gtk_text_view_parent_class)->finalize (object);
|
||||
@@ -8438,33 +8464,6 @@ hide_selection_bubble (GtkTextView *text_view)
|
||||
gtk_widget_hide (priv->selection_bubble);
|
||||
}
|
||||
|
||||
static void
|
||||
cut_clipboard_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_signal_emit_by_name (user_data, "cut-clipboard");
|
||||
hide_selection_bubble (GTK_TEXT_VIEW (user_data));
|
||||
}
|
||||
|
||||
static void
|
||||
copy_clipboard_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_signal_emit_by_name (user_data, "copy-clipboard");
|
||||
hide_selection_bubble (GTK_TEXT_VIEW (user_data));
|
||||
}
|
||||
|
||||
static void
|
||||
paste_clipboard_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
g_signal_emit_by_name (user_data, "paste-clipboard");
|
||||
hide_selection_bubble (GTK_TEXT_VIEW (user_data));
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_select_all (GtkWidget *widget,
|
||||
gboolean select)
|
||||
@@ -8487,34 +8486,6 @@ gtk_text_view_select_all (GtkWidget *widget,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
select_all_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkTextView *text_view = user_data;
|
||||
|
||||
gtk_text_view_select_all (GTK_WIDGET (text_view), TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
delete_selection_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
GtkTextView *text_view = user_data;
|
||||
|
||||
gtk_text_buffer_delete_selection (get_buffer (text_view), TRUE,
|
||||
text_view->priv->editable);
|
||||
}
|
||||
|
||||
static void
|
||||
insert_emoji_activated (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer user_data)
|
||||
{
|
||||
gtk_text_view_insert_emoji (GTK_TEXT_VIEW (user_data));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
range_contains_editable_text (const GtkTextIter *start,
|
||||
@@ -8535,40 +8506,60 @@ range_contains_editable_text (const GtkTextIter *start,
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_add_context_actions (GtkTextView *text_view)
|
||||
gtk_text_view_activate_clipboard_cut (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkTextViewPrivate *priv = text_view->priv;
|
||||
GtkTextView *self = GTK_TEXT_VIEW (widget);
|
||||
g_signal_emit_by_name (self, "cut-clipboard");
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
GActionEntry entries[] = {
|
||||
{ "cut-clipboard", cut_clipboard_activated, NULL, NULL, NULL },
|
||||
{ "copy-clipboard", copy_clipboard_activated, NULL, NULL, NULL },
|
||||
{ "paste-clipboard", paste_clipboard_activated, NULL, NULL, NULL },
|
||||
{ "delete-selection", delete_selection_activated, NULL, NULL, NULL },
|
||||
{ "select-all", select_all_activated, NULL, NULL, NULL },
|
||||
{ "insert-emoji", insert_emoji_activated, NULL, NULL, NULL },
|
||||
};
|
||||
static void
|
||||
gtk_text_view_activate_clipboard_copy (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkTextView *self = GTK_TEXT_VIEW (widget);
|
||||
g_signal_emit_by_name (self, "copy-clipboard");
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
GSimpleActionGroup *actions = g_simple_action_group_new ();
|
||||
GAction *action;
|
||||
static void
|
||||
gtk_text_view_activate_clipboard_paste (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkTextView *self = GTK_TEXT_VIEW (widget);
|
||||
g_signal_emit_by_name (self, "paste-clipboard");
|
||||
hide_selection_bubble (self);
|
||||
}
|
||||
|
||||
priv->context_actions = G_ACTION_MAP (actions);
|
||||
static void
|
||||
gtk_text_view_activate_selection_select_all (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
gtk_text_view_select_all (widget, TRUE);
|
||||
}
|
||||
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions), entries, G_N_ELEMENTS (entries), text_view);
|
||||
static void
|
||||
gtk_text_view_activate_selection_delete (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GtkTextView *text_view = GTK_TEXT_VIEW (widget);
|
||||
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "cut-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "copy-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "paste-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "delete-selection");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "select-all");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "insert-emoji");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), FALSE);
|
||||
gtk_text_buffer_delete_selection (get_buffer (text_view), TRUE,
|
||||
text_view->priv->editable);
|
||||
}
|
||||
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (text_view), "context", G_ACTION_GROUP (actions));
|
||||
static void
|
||||
gtk_text_view_activate_misc_insert_emoji (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
gtk_text_view_insert_emoji (GTK_TEXT_VIEW (widget));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -8578,7 +8569,6 @@ gtk_text_view_update_clipboard_actions (GtkTextView *text_view)
|
||||
GdkClipboard *clipboard;
|
||||
gboolean have_selection;
|
||||
gboolean can_paste, can_insert;
|
||||
GAction *action;
|
||||
GtkTextIter iter, sel_start, sel_end;
|
||||
|
||||
clipboard = gtk_widget_get_clipboard (GTK_WIDGET (text_view));
|
||||
@@ -8593,36 +8583,25 @@ gtk_text_view_update_clipboard_actions (GtkTextView *text_view)
|
||||
|
||||
can_insert = gtk_text_iter_can_insert (&iter, priv->editable);
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "cut-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
have_selection &&
|
||||
range_contains_editable_text (&sel_start, &sel_end, priv->editable));
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "copy-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), have_selection);
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "paste-clipboard");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), can_insert && can_paste);
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "delete-selection");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
have_selection &&
|
||||
range_contains_editable_text (&sel_start, &sel_end, priv->editable));
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "select-all");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
gtk_text_buffer_get_char_count (priv->buffer) > 0);
|
||||
gtk_widget_notify_class_action_enabled (GTK_WIDGET (text_view), "clipboard.cut",
|
||||
have_selection &&
|
||||
range_contains_editable_text (&sel_start, &sel_end, priv->editable));
|
||||
gtk_widget_notify_class_action_enabled (GTK_WIDGET (text_view), "clipboard.copy",
|
||||
have_selection);
|
||||
gtk_widget_notify_class_action_enabled (GTK_WIDGET (text_view), "clipboard.paste",
|
||||
can_insert && can_paste);
|
||||
gtk_widget_notify_class_action_enabled (GTK_WIDGET (text_view), "selection.delete",
|
||||
have_selection &&
|
||||
range_contains_editable_text (&sel_start, &sel_end, priv->editable));
|
||||
gtk_widget_notify_class_action_enabled (GTK_WIDGET (text_view), "selection.select-all",
|
||||
gtk_text_buffer_get_char_count (priv->buffer) > 0);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_text_view_update_emoji_action (GtkTextView *text_view)
|
||||
{
|
||||
GtkTextViewPrivate *priv = text_view->priv;
|
||||
GAction *action;
|
||||
|
||||
action = g_action_map_lookup_action (priv->context_actions, "insert-emoji");
|
||||
g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
|
||||
(gtk_text_view_get_input_hints (text_view) & GTK_INPUT_HINT_NO_EMOJI) == 0);
|
||||
gtk_widget_notify_class_action_enabled (GTK_WIDGET (text_view), "misc.insert-emoji",
|
||||
(gtk_text_view_get_input_hints (text_view) & GTK_INPUT_HINT_NO_EMOJI) == 0);
|
||||
}
|
||||
|
||||
static GMenuModel *
|
||||
@@ -8635,19 +8614,19 @@ gtk_text_view_get_menu_model (GtkTextView *text_view)
|
||||
menu = g_menu_new ();
|
||||
|
||||
section = g_menu_new ();
|
||||
item = g_menu_item_new (_("Cu_t"), "context.cut-clipboard");
|
||||
item = g_menu_item_new (_("Cu_t"), "clipboard.cut");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-cut-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
item = g_menu_item_new (_("_Copy"), "context.copy-clipboard");
|
||||
item = g_menu_item_new (_("_Copy"), "clipboard.copy");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-copy-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
item = g_menu_item_new (_("_Paste"), "context.paste-clipboard");
|
||||
item = g_menu_item_new (_("_Paste"), "clipboard.paste");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-paste-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
item = g_menu_item_new (_("_Delete"), "context.delete-selection");
|
||||
item = g_menu_item_new (_("_Delete"), "selection.delete");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-delete-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
@@ -8656,12 +8635,12 @@ gtk_text_view_get_menu_model (GtkTextView *text_view)
|
||||
|
||||
section = g_menu_new ();
|
||||
|
||||
item = g_menu_item_new (_("Select _All"), "context.select-all");
|
||||
item = g_menu_item_new (_("Select _All"), "selection.select-all");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "edit-select-all-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
g_object_unref (item);
|
||||
|
||||
item = g_menu_item_new ( _("Insert _Emoji"), "context.insert-emoji");
|
||||
item = g_menu_item_new ( _("Insert _Emoji"), "misc.insert-emoji");
|
||||
g_menu_item_set_attribute (item, "hidden-when", "s", "action-disabled");
|
||||
g_menu_item_set_attribute (item, "touch-icon", "s", "face-smile-symbolic");
|
||||
g_menu_append_item (section, item);
|
||||
|
322
gtk/gtkwidget.c
322
gtk/gtkwidget.c
@@ -73,6 +73,7 @@
|
||||
#include "gtkwindowgroup.h"
|
||||
#include "gtkwindowprivate.h"
|
||||
#include "gtknativeprivate.h"
|
||||
#include "gtkapplicationaccelsprivate.h"
|
||||
|
||||
#include "a11y/gtkwidgetaccessible.h"
|
||||
#include "inspector/window.h"
|
||||
@@ -501,6 +502,8 @@ struct _GtkWidgetClassPrivate
|
||||
AtkRole accessible_role;
|
||||
const char *css_name;
|
||||
GType layout_manager_type;
|
||||
GPtrArray *actions;
|
||||
GtkApplicationAccels *accels;
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -712,6 +715,13 @@ static gboolean gtk_widget_class_get_visible_by_default (GtkWidgetClass *widget_
|
||||
static void remove_parent_surface_transform_changed_listener (GtkWidget *widget);
|
||||
static void add_parent_surface_transform_changed_listener (GtkWidget *widget);
|
||||
|
||||
static gboolean gtk_widget_activate_accels (GtkWidget *widget,
|
||||
const GdkEvent *event);
|
||||
|
||||
static void gtk_widget_activate_menu_popup (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
|
||||
|
||||
/* --- variables --- */
|
||||
static gint GtkWidget_private_offset = 0;
|
||||
@@ -864,7 +874,6 @@ static void
|
||||
gtk_widget_class_init (GtkWidgetClass *klass)
|
||||
{
|
||||
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
||||
GtkBindingSet *binding_set;
|
||||
|
||||
g_type_class_adjust_private_offset (klass, &GtkWidget_private_offset);
|
||||
gtk_widget_parent_class = g_type_class_peek_parent (klass);
|
||||
@@ -2120,11 +2129,11 @@ gtk_widget_class_init (GtkWidgetClass *klass)
|
||||
G_TYPE_FROM_CLASS (klass),
|
||||
_gtk_marshal_BOOLEAN__UINTv);
|
||||
|
||||
binding_set = gtk_binding_set_by_class (klass);
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KEY_F10, GDK_SHIFT_MASK,
|
||||
"popup-menu", 0);
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KEY_Menu, 0,
|
||||
"popup-menu", 0);
|
||||
gtk_widget_class_install_action (klass, "menu.popup",
|
||||
gtk_widget_activate_menu_popup);
|
||||
|
||||
gtk_widget_class_bind_action (klass, GDK_KEY_Menu, 0, "menu.popup", NULL);
|
||||
gtk_widget_class_bind_action (klass, GDK_KEY_Menu, GDK_SHIFT_MASK, "menu.popup", NULL);
|
||||
|
||||
gtk_widget_class_set_accessible_type (klass, GTK_TYPE_WIDGET_ACCESSIBLE);
|
||||
gtk_widget_class_set_css_name (klass, I_("widget"));
|
||||
@@ -5359,6 +5368,11 @@ gtk_widget_event_internal (GtkWidget *widget,
|
||||
event->any.type == GDK_KEY_RELEASE))
|
||||
return_val |= gtk_bindings_activate_event (G_OBJECT (widget), (GdkEventKey *) event);
|
||||
|
||||
if (return_val == FALSE &&
|
||||
(event->any.type == GDK_KEY_PRESS ||
|
||||
event->any.type == GDK_KEY_RELEASE))
|
||||
return_val = gtk_widget_activate_accels (widget, event);
|
||||
|
||||
return return_val;
|
||||
}
|
||||
|
||||
@@ -11897,14 +11911,16 @@ _gtk_widget_get_action_muxer (GtkWidget *widget,
|
||||
gboolean create)
|
||||
{
|
||||
GtkActionMuxer *muxer;
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_GET_CLASS (widget);
|
||||
GtkWidgetClassPrivate *priv = widget_class->priv;
|
||||
|
||||
muxer = (GtkActionMuxer*)g_object_get_qdata (G_OBJECT (widget), quark_action_muxer);
|
||||
if (muxer)
|
||||
return muxer;
|
||||
|
||||
if (create)
|
||||
if (create || priv->actions)
|
||||
{
|
||||
muxer = gtk_action_muxer_new (widget);
|
||||
muxer = gtk_action_muxer_new (widget, priv->actions);
|
||||
g_object_set_qdata_full (G_OBJECT (widget),
|
||||
quark_action_muxer,
|
||||
muxer,
|
||||
@@ -12455,6 +12471,17 @@ gtk_widget_activate_default (GtkWidget *widget)
|
||||
gtk_widget_activate_action (widget, "default.activate", NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_widget_activate_menu_popup (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
gboolean handled;
|
||||
|
||||
g_signal_emit (widget, widget_signals[POPUP_MENU], 0, &handled);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_widget_cancel_event_sequence (GtkWidget *widget,
|
||||
GtkGesture *gesture,
|
||||
@@ -13427,3 +13454,282 @@ gtk_widget_should_layout (GtkWidget *widget)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_widget_class_install_action:
|
||||
* @widget_class: a #GtkWidgetClass
|
||||
* @action_name: a prefixed action name, such as "clipboard.paste"
|
||||
* @activate: callback to use when the action is activated
|
||||
*
|
||||
* This should be called at class initialization time to specify
|
||||
* actions to be added for all instances of this class.
|
||||
*
|
||||
* Actions installed by this function are stateless. The only state
|
||||
* they have is whether they are enabled or not. For more complicated
|
||||
* actions, see gtk_widget_class_install_stateful_action().
|
||||
*/
|
||||
void
|
||||
gtk_widget_class_install_action (GtkWidgetClass *widget_class,
|
||||
const char *action_name,
|
||||
GtkWidgetActionActivateFunc activate)
|
||||
{
|
||||
gtk_widget_class_install_stateful_action (widget_class, action_name, activate,
|
||||
NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* gtk_widget_class_install_stateful_action:
|
||||
* @widget_class: a #GtkWidgetClass
|
||||
* @action_name: a prefixed action name, such as "clipboard.paste"
|
||||
* @activate: callback to use when the action is activated
|
||||
* @parameter_type: (allow-none): the parameter type, or %NULL
|
||||
* @query: (allow-none): callback to use when the action properties
|
||||
are queried, or %NULL for always-enabled stateless actions
|
||||
* @query_state: (allow-none): callback to use when the action state
|
||||
is queried, or %NULL for stateless actions
|
||||
*
|
||||
* This should be called at class initialization time to specify
|
||||
* actions to be added for all instances of this class.
|
||||
*
|
||||
* Actions installed in this way can be simple or stateful.
|
||||
* See the #GAction documentation for more information.
|
||||
*/
|
||||
void
|
||||
gtk_widget_class_install_stateful_action (GtkWidgetClass *widget_class,
|
||||
const char *action_name,
|
||||
GtkWidgetActionActivateFunc activate,
|
||||
const char *parameter_type,
|
||||
GtkWidgetActionSetStateFunc set_state,
|
||||
GtkWidgetActionGetStateFunc get_state)
|
||||
{
|
||||
GtkWidgetClassPrivate *priv = widget_class->priv;
|
||||
GtkWidgetAction *action;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET_CLASS (widget_class));
|
||||
|
||||
if (priv->actions == NULL)
|
||||
priv->actions = g_ptr_array_new ();
|
||||
else if (GTK_IS_WIDGET_CLASS (&widget_class->parent_class))
|
||||
{
|
||||
GtkWidgetClass *parent_class = GTK_WIDGET_CLASS (&widget_class->parent_class);
|
||||
GtkWidgetClassPrivate *parent_priv = parent_class->priv;
|
||||
GPtrArray *parent_actions = parent_priv->actions;
|
||||
|
||||
if (priv->actions == parent_actions)
|
||||
{
|
||||
int i;
|
||||
|
||||
priv->actions = g_ptr_array_new ();
|
||||
for (i = 0; i < parent_actions->len; i++)
|
||||
g_ptr_array_add (priv->actions, g_ptr_array_index (parent_actions, i));
|
||||
}
|
||||
}
|
||||
|
||||
action = g_new0 (GtkWidgetAction, 1);
|
||||
action->name = g_strdup (action_name);
|
||||
action->activate = activate;
|
||||
action->parameter_type = parameter_type ? g_variant_type_new (parameter_type) : NULL;
|
||||
action->set_state = set_state;
|
||||
action->get_state = get_state;
|
||||
|
||||
GTK_NOTE(ACTIONS,
|
||||
g_message ("%sClass: Adding %s action\n",
|
||||
g_type_name (G_TYPE_FROM_CLASS (widget_class)),
|
||||
action_name));
|
||||
|
||||
g_ptr_array_add (priv->actions, action);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_notify_class_action_enabled:
|
||||
* @widget: a #GtkWidget
|
||||
* @action_name: a prefixed action name, such as "clipboard.paste"
|
||||
* @enabled: whether the action is now enabled
|
||||
*
|
||||
* Convenience API to notify when an action installed
|
||||
* with gtk_widget_class_install_action() changes its
|
||||
* enabled state. It must be called after the change
|
||||
* has taken place (we expect the @query callback to
|
||||
* already return the new state).
|
||||
*
|
||||
* This function is a more convenient alternative
|
||||
* to calling g_action_group_action_enabled_changed()
|
||||
* directly.
|
||||
*/
|
||||
void
|
||||
gtk_widget_notify_class_action_enabled (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
gboolean enabled)
|
||||
{
|
||||
GtkActionMuxer *muxer;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
muxer = _gtk_widget_get_action_muxer (widget, TRUE);
|
||||
gtk_action_muxer_action_enabled_changed (muxer, action_name, enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_notify_class_action_state:
|
||||
* @widget: a #GtkWidget
|
||||
* @action_name: a prefixed action name, such as "clipboard.paste"
|
||||
* @state: the new state
|
||||
*
|
||||
* Convenience API to notify when an action installed
|
||||
* with gtk_widget_class_install_action() changes its
|
||||
* state. It must be called after the change has taken
|
||||
* place (we expect the @query callback to already
|
||||
* return the new state).
|
||||
*
|
||||
* This function is a more convenient alternative
|
||||
* to calling g_action_group_action_state_changed()
|
||||
* directly.
|
||||
*/
|
||||
void
|
||||
gtk_widget_notify_class_action_state (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *state)
|
||||
{
|
||||
GtkActionMuxer *muxer;
|
||||
|
||||
g_return_if_fail (GTK_IS_WIDGET (widget));
|
||||
|
||||
muxer = _gtk_widget_get_action_muxer (widget, TRUE);
|
||||
gtk_action_muxer_action_state_changed (muxer, action_name, state);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_widget_class_add_accel_for_action (GtkWidgetClass *widget_class,
|
||||
const char *detailed_action,
|
||||
const char *accel)
|
||||
{
|
||||
GtkWidgetClassPrivate *priv = widget_class->priv;
|
||||
char **accels;
|
||||
int n;
|
||||
|
||||
if (priv->accels == NULL)
|
||||
priv->accels = gtk_application_accels_new ();
|
||||
|
||||
accels = gtk_application_accels_get_accels_for_action (priv->accels, detailed_action);
|
||||
|
||||
if (accels)
|
||||
{
|
||||
n = g_strv_length (accels);
|
||||
accels = g_renew (char *, accels, n + 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = 0;
|
||||
accels = g_new (char *, 2);
|
||||
}
|
||||
|
||||
accels[n] = g_strdup (accel);
|
||||
accels[n + 1] = NULL;
|
||||
|
||||
gtk_application_accels_set_accels_for_action (priv->accels, detailed_action, (const char **)accels);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_widget_class_bind_action:
|
||||
* @widget_class: a #GtkWidgetClass
|
||||
* @keyval: key value of the binding
|
||||
* @modifiers: key modifiers of the binding
|
||||
* @action_name: the name of the action to bind
|
||||
* @format_string: (allow-none): GVariant format string for
|
||||
* the parameters, or %NULL
|
||||
*
|
||||
* Binds the @keyval, @modifiers shortcut to
|
||||
* trigger the action named @action_name with the
|
||||
* given parameters.
|
||||
*
|
||||
* This function should be called at class-init time.
|
||||
*
|
||||
* The action must be defined using
|
||||
* gtk_widget_class_install_action() and the parameters
|
||||
* must match the @parameter_type passed to that function.
|
||||
*/
|
||||
void
|
||||
gtk_widget_class_bind_action (GtkWidgetClass *widget_class,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers,
|
||||
const char *action_name,
|
||||
const char *format_string,
|
||||
...)
|
||||
{
|
||||
GtkWidgetClassPrivate *priv = widget_class->priv;
|
||||
gboolean found = FALSE;
|
||||
GVariantType *type = NULL;
|
||||
GVariant *parameters = NULL;
|
||||
char *detailed_action = NULL;
|
||||
char *accel = NULL;
|
||||
|
||||
if (priv->actions)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < priv->actions->len; i++)
|
||||
{
|
||||
GtkWidgetAction *action = g_ptr_array_index (priv->actions, i);
|
||||
if (strcmp (action->name, action_name) == 0)
|
||||
{
|
||||
type = action->parameter_type;
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
g_warning ("Widget action %s not found", action_name);
|
||||
return;
|
||||
}
|
||||
|
||||
if (format_string)
|
||||
{
|
||||
va_list args;
|
||||
va_start (args, format_string);
|
||||
parameters = g_variant_ref_sink (g_variant_new_va (format_string, NULL, &args));
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
if (parameters && !g_variant_is_of_type (parameters, type))
|
||||
{
|
||||
g_warning ("Parameters don't match expected type for action %s", action_name);
|
||||
g_variant_unref (parameters);
|
||||
return;
|
||||
}
|
||||
|
||||
detailed_action = g_action_print_detailed_name (action_name, parameters);
|
||||
|
||||
accel = gtk_accelerator_name (keyval, modifiers);
|
||||
|
||||
gtk_widget_class_add_accel_for_action (widget_class, detailed_action, accel);
|
||||
|
||||
g_free (detailed_action);
|
||||
g_free (accel);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gtk_widget_activate_accels (GtkWidget *widget,
|
||||
const GdkEvent *event)
|
||||
{
|
||||
GtkWidgetClass *class = GTK_WIDGET_GET_CLASS (widget);
|
||||
GtkWidgetClassPrivate *priv = class->priv;
|
||||
GtkApplicationAccels *accels = priv->accels;
|
||||
GtkActionMuxer *muxer;
|
||||
guint keyval;
|
||||
GdkModifierType modifiers;
|
||||
|
||||
if (!accels)
|
||||
return FALSE;
|
||||
|
||||
muxer = _gtk_widget_get_action_muxer (widget, FALSE);
|
||||
if (!muxer)
|
||||
return FALSE;
|
||||
|
||||
gdk_event_get_keyval ((GdkEvent *)event, &keyval);
|
||||
gdk_event_get_state ((GdkEvent *)event, &modifiers);
|
||||
|
||||
return gtk_application_accels_activate (accels,
|
||||
G_ACTION_GROUP (muxer),
|
||||
keyval, modifiers);
|
||||
}
|
||||
|
@@ -1023,6 +1023,84 @@ GDK_AVAILABLE_IN_ALL
|
||||
gboolean gtk_widget_should_layout (GtkWidget *widget);
|
||||
|
||||
|
||||
/**
|
||||
* GtkWidgetActionActivateFunc:
|
||||
* @widget: the widget to which the action belongs
|
||||
* @action_name: the action name
|
||||
* @parameter: parameter for activation
|
||||
*
|
||||
* The type of the callback functions used for activating
|
||||
* actions installed with gtk_widget_class_install_action().
|
||||
*
|
||||
* The @parameter must match the @parameter_type of the action.
|
||||
*/
|
||||
typedef void (* GtkWidgetActionActivateFunc) (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
|
||||
/**
|
||||
* GtkWidgetActionGetStateFunc:
|
||||
* @widget: the widget to which the action belongs
|
||||
* @action_name: the action name
|
||||
*
|
||||
* The type of the callback functions used to query the state
|
||||
* of stateful actions installed with gtk_widget_class_install_action().
|
||||
*
|
||||
* See the #GAction documentation for more details about the
|
||||
* meaning of these properties.
|
||||
*/
|
||||
typedef GVariant * (* GtkWidgetActionGetStateFunc) (GtkWidget *widget,
|
||||
const char *action_name);
|
||||
|
||||
/**
|
||||
* GtkWidgetActionSetStateFunc:
|
||||
* @widget: the widget to which the action belongs
|
||||
* @action_name: the action name
|
||||
* @state: the new state
|
||||
*
|
||||
* The type of the callback functions used to change the
|
||||
* state of actions installed with gtk_widget_class_install_action().
|
||||
*
|
||||
* The @state must match the @state_type of the action.
|
||||
*
|
||||
* This callback is used when the action state is
|
||||
* changed via the #GActionGroup API.
|
||||
*/
|
||||
typedef void (*GtkWidgetActionSetStateFunc) (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *state);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_class_install_action (GtkWidgetClass *widget_class,
|
||||
const char *action_name,
|
||||
GtkWidgetActionActivateFunc activate);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_class_install_stateful_action (GtkWidgetClass *widget_class,
|
||||
const char *action_name,
|
||||
GtkWidgetActionActivateFunc activate,
|
||||
const char *parameter_type,
|
||||
GtkWidgetActionSetStateFunc set_state,
|
||||
GtkWidgetActionGetStateFunc get_state);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_notify_class_action_enabled (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
gboolean enabled);
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_notify_class_action_state (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *state);
|
||||
|
||||
GDK_AVAILABLE_IN_ALL
|
||||
void gtk_widget_class_bind_action (GtkWidgetClass *widget_class,
|
||||
guint keyval,
|
||||
GdkModifierType modifiers,
|
||||
const char *action_name,
|
||||
const char *format_string,
|
||||
...);
|
||||
|
||||
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkWidget, g_object_unref)
|
||||
G_DEFINE_AUTOPTR_CLEANUP_FUNC(GtkRequisition, gtk_requisition_free)
|
||||
|
||||
|
@@ -492,6 +492,13 @@ static void gtk_window_on_theme_variant_changed (GtkSettings *settings,
|
||||
#endif
|
||||
static void gtk_window_set_theme_variant (GtkWindow *window);
|
||||
|
||||
static void gtk_window_activate_default_activate (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
static void gtk_window_activate_focus_move (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter);
|
||||
|
||||
static void gtk_window_do_popup (GtkWindow *window,
|
||||
GdkEventButton *event);
|
||||
static void gtk_window_style_updated (GtkWidget *widget);
|
||||
@@ -1196,6 +1203,12 @@ gtk_window_class_init (GtkWindowClass *klass)
|
||||
|
||||
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_WINDOW_ACCESSIBLE);
|
||||
gtk_widget_class_set_css_name (widget_class, I_("window"));
|
||||
|
||||
gtk_widget_class_install_action (widget_class, "default.activate",
|
||||
gtk_window_activate_default_activate);
|
||||
gtk_widget_class_install_stateful_action (widget_class, "focus.move",
|
||||
gtk_window_activate_focus_move,
|
||||
"i", NULL, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1766,28 +1779,22 @@ gtk_window_capture_motion (GtkWidget *widget,
|
||||
}
|
||||
|
||||
static void
|
||||
activate_default_cb (GSimpleAction *action,
|
||||
GVariant *parameter,
|
||||
gpointer data)
|
||||
gtk_window_activate_default_activate (GtkWidget *widget,
|
||||
const char *name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
gtk_window_real_activate_default (GTK_WINDOW (data));
|
||||
gtk_window_real_activate_default (GTK_WINDOW (widget));
|
||||
}
|
||||
|
||||
static void
|
||||
add_actions (GtkWindow *window)
|
||||
gtk_window_activate_focus_move (GtkWidget *widget,
|
||||
const char *action_name,
|
||||
GVariant *parameter)
|
||||
{
|
||||
GActionEntry entries[] = {
|
||||
{ "activate", activate_default_cb, NULL, NULL, NULL },
|
||||
};
|
||||
|
||||
GActionGroup *actions;
|
||||
|
||||
actions = G_ACTION_GROUP (g_simple_action_group_new ());
|
||||
g_action_map_add_action_entries (G_ACTION_MAP (actions),
|
||||
entries, G_N_ELEMENTS (entries),
|
||||
window);
|
||||
gtk_widget_insert_action_group (GTK_WIDGET (window), "default", actions);
|
||||
g_object_unref (actions);
|
||||
gtk_window_move_focus (widget,
|
||||
CLAMP (g_variant_get_int32 (parameter),
|
||||
GTK_DIR_TAB_FORWARD,
|
||||
GTK_DIR_RIGHT));
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1879,8 +1886,6 @@ gtk_window_init (GtkWindow *window)
|
||||
g_signal_connect_swapped (priv->key_controller, "focus-out",
|
||||
G_CALLBACK (gtk_window_focus_out), window);
|
||||
gtk_widget_add_controller (widget, priv->key_controller);
|
||||
|
||||
add_actions (window);
|
||||
}
|
||||
|
||||
static GtkGesture *
|
||||
|
Reference in New Issue
Block a user