Merge branch 'otte/for-master' into 'master'

Otte/for master

See merge request GNOME/gtk!1133
This commit is contained in:
Benjamin Otte 2019-10-15 18:47:57 +00:00
commit 7fc74eaeae
36 changed files with 860 additions and 219 deletions

View File

@ -129,13 +129,13 @@ demo_tagged_entry_size_allocate (GtkWidget *widget,
baseline);
}
static void
static gboolean
demo_tagged_entry_grab_focus (GtkWidget *widget)
{
DemoTaggedEntry *entry = DEMO_TAGGED_ENTRY (widget);
DemoTaggedEntryPrivate *priv = demo_tagged_entry_get_instance_private (entry);
gtk_widget_grab_focus (priv->entry);
return gtk_widget_grab_focus (priv->entry);
}
static void

View File

@ -51,6 +51,7 @@
<xi:include href="xml/gtksortlistmodel.xml" />
<xi:include href="xml/gtktreelistmodel.xml" />
<xi:include href="xml/gtkselectionmodel.xml" />
<xi:include href="xml/gtknoselection.xml" />
<xi:include href="xml/gtksingleselection.xml" />
</chapter>

View File

@ -465,12 +465,23 @@ GTK_TYPE_SELECTION_MODEL
gtk_selection_model_get_type
</SECTION>
<SECTION>
<FILE>gtknoselection</FILE>
<TITLE>GtkNoSelection</TITLE>
GtkNoSelection
gtk_no_selection_new
gtk_no_selection_get_model
<SUBSECTION Private>
gtk_no_selection_get_type
</SECTION>
<SECTION>
<FILE>gtksingleselection</FILE>
<TITLE>GtkSingleSelection</TITLE>
GtkSingleSelection
GTK_INVALID_LIST_POSITION
gtk_single_selection_new
gtk_single_selection_get_model
gtk_single_selection_get_selected
gtk_single_selection_set_selected
gtk_single_selection_get_selected_item
@ -5236,6 +5247,9 @@ gtk_binding_set_find
gtk_bindings_activate
gtk_bindings_activate_event
gtk_binding_set_activate
gtk_binding_entry_add_action
gtk_binding_entry_add_action_variant
gtk_binding_entry_add_callback
gtk_binding_entry_add_signal
gtk_binding_entry_add_signal_from_string
gtk_binding_entry_skip

View File

@ -166,6 +166,7 @@
#include <gtk/gtkmountoperation.h>
#include <gtk/gtknative.h>
#include <gtk/gtknativedialog.h>
#include <gtk/gtknoselection.h>
#include <gtk/gtknotebook.h>
#include <gtk/gtkorientable.h>
#include <gtk/gtkoverlay.h>

View File

@ -138,6 +138,13 @@ struct _GtkBindingArg
} d;
};
typedef enum
{
GTK_BINDING_SIGNAL,
GTK_BINDING_ACTION,
GTK_BINDING_CALLBACK
} GtkBindingActionType;
/**
* GtkBindingSignal:
* @next: implementation detail
@ -151,10 +158,21 @@ struct _GtkBindingArg
*/
struct _GtkBindingSignal
{
GtkBindingSignal *next;
gchar *signal_name;
guint n_args;
GtkBindingArg *args;
GtkBindingSignal *next;
gchar *signal_name;
GtkBindingActionType action_type;
union {
struct {
guint n_args;
GtkBindingArg *args;
};
GVariant *variant;
struct {
GtkCallback callback;
gpointer user_data;
GDestroyNotify user_destroy;
} callback;
};
};
/* --- variables --- */
@ -168,13 +186,14 @@ static GQuark key_id_class_binding_set = 0;
/* --- functions --- */
static GtkBindingSignal*
binding_signal_new (const gchar *signal_name,
guint n_args)
binding_signal_new_signal (const gchar *signal_name,
guint n_args)
{
GtkBindingSignal *signal;
signal = (GtkBindingSignal *) g_slice_alloc0 (sizeof (GtkBindingSignal) + n_args * sizeof (GtkBindingArg));
signal->next = NULL;
signal->action_type = GTK_BINDING_SIGNAL;
signal->signal_name = (gchar *)g_intern_string (signal_name);
signal->n_args = n_args;
signal->args = (GtkBindingArg *)(signal + 1);
@ -182,17 +201,71 @@ binding_signal_new (const gchar *signal_name,
return signal;
}
static GtkBindingSignal*
binding_signal_new_action (const gchar *signal_name,
GVariant *variant)
{
GtkBindingSignal *signal;
signal = g_slice_new0 (GtkBindingSignal);
signal->next = NULL;
signal->action_type = GTK_BINDING_ACTION;
signal->signal_name = (gchar *)g_intern_string (signal_name);
signal->variant = variant;
if (variant)
g_variant_ref_sink (variant);
return signal;
}
static GtkBindingSignal *
binding_signal_new_callback (GtkCallback callback,
gpointer user_data,
GDestroyNotify user_destroy)
{
GtkBindingSignal *signal;
signal = g_slice_new0 (GtkBindingSignal);
signal->next = NULL;
signal->action_type = GTK_BINDING_CALLBACK;
signal->callback.callback = callback;
signal->callback.user_data = user_data;
signal->callback.user_destroy = user_destroy;
return signal;
}
static void
binding_signal_free (GtkBindingSignal *sig)
{
guint i;
for (i = 0; i < sig->n_args; i++)
switch (sig->action_type)
{
if (G_TYPE_FUNDAMENTAL (sig->args[i].arg_type) == G_TYPE_STRING)
g_free (sig->args[i].d.string_data);
case GTK_BINDING_SIGNAL:
for (i = 0; i < sig->n_args; i++)
{
if (G_TYPE_FUNDAMENTAL (sig->args[i].arg_type) == G_TYPE_STRING)
g_free (sig->args[i].d.string_data);
}
g_slice_free1 (sizeof (GtkBindingSignal) + sig->n_args * sizeof (GtkBindingArg), sig);
break;
case GTK_BINDING_ACTION:
g_clear_pointer (&sig->variant, g_variant_unref);
g_slice_free (GtkBindingSignal, sig);
break;
case GTK_BINDING_CALLBACK:
if (sig->callback.user_destroy)
sig->callback.user_destroy (sig->callback.user_data);
g_slice_free (GtkBindingSignal, sig);
break;
default:
g_assert_not_reached ();
break;
}
g_slice_free1 (sizeof (GtkBindingSignal) + sig->n_args * sizeof (GtkBindingArg), sig);
}
static guint
@ -559,6 +632,114 @@ binding_compose_params (GObject *object,
return valid;
}
static gboolean
binding_signal_activate_signal (GtkBindingSignal *sig,
GObject *object)
{
GSignalQuery query;
guint signal_id;
GValue *params = NULL;
GValue return_val = G_VALUE_INIT;
gboolean handled = FALSE;
signal_id = g_signal_lookup (sig->signal_name, G_OBJECT_TYPE (object));
if (!signal_id)
{
g_warning ("gtk_binding_entry_activate(): "
"could not find signal \"%s\" in the '%s' class ancestry",
sig->signal_name,
g_type_name (G_OBJECT_TYPE (object)));
return FALSE;
}
g_signal_query (signal_id, &query);
if (query.n_params != sig->n_args ||
(query.return_type != G_TYPE_NONE && query.return_type != G_TYPE_BOOLEAN) ||
!binding_compose_params (object, sig->args, &query, &params))
{
g_warning ("gtk_binding_entry_activate(): "
"signature mismatch for signal \"%s\" in the '%s' class ancestry",
sig->signal_name,
g_type_name (G_OBJECT_TYPE (object)));
return FALSE;
}
else if (!(query.signal_flags & G_SIGNAL_ACTION))
{
g_warning ("gtk_binding_entry_activate(): "
"signal \"%s\" in the '%s' class ancestry cannot be used for action emissions",
sig->signal_name,
g_type_name (G_OBJECT_TYPE (object)));
return FALSE;
}
if (query.return_type == G_TYPE_BOOLEAN)
g_value_init (&return_val, G_TYPE_BOOLEAN);
g_signal_emitv (params, signal_id, 0, &return_val);
if (query.return_type == G_TYPE_BOOLEAN)
{
if (g_value_get_boolean (&return_val))
handled = TRUE;
g_value_unset (&return_val);
}
else
handled = TRUE;
if (params != NULL)
{
guint i;
for (i = 0; i < query.n_params + 1; i++)
g_value_unset (&params[i]);
g_free (params);
}
return handled;
}
static gboolean
binding_signal_activate_action (GtkBindingSignal *sig,
GObject *object)
{
if (!GTK_IS_WIDGET (object))
{
g_warning ("gtk_binding_entry_activate(): "
"actions must be emitted on GtkWidget subtypes, %s is not supported",
G_OBJECT_TYPE_NAME (object));
return FALSE;
}
if (!gtk_widget_activate_action_variant (GTK_WIDGET (object), sig->signal_name, sig->variant))
{
g_warning ("gtk_binding_entry_activate(): "
"action \"%s\" does not exist on class \"%s\"",
sig->signal_name,
G_OBJECT_TYPE_NAME (object));
return FALSE;
}
return TRUE;
}
static gboolean
binding_signal_activate_callback (GtkBindingSignal *sig,
GObject *object)
{
if (!GTK_IS_WIDGET (object))
{
g_warning ("gtk_binding_entry_activate(): "
"callbacks must be run on GtkWidget subtypes, %s is not supported",
G_OBJECT_TYPE_NAME (object));
return FALSE;
}
sig->callback.callback (GTK_WIDGET (object), sig->callback.user_data);
return TRUE;
}
static gboolean
gtk_binding_entry_activate (GtkBindingEntry *entry,
GObject *object)
@ -566,7 +747,6 @@ gtk_binding_entry_activate (GtkBindingEntry *entry,
GtkBindingSignal *sig;
gboolean old_emission;
gboolean handled = FALSE;
gint i;
old_emission = entry->in_emission;
entry->in_emission = TRUE;
@ -575,73 +755,23 @@ gtk_binding_entry_activate (GtkBindingEntry *entry,
for (sig = entry->signals; sig; sig = sig->next)
{
GSignalQuery query;
guint signal_id;
GValue *params = NULL;
GValue return_val = G_VALUE_INIT;
gchar *accelerator = NULL;
signal_id = g_signal_lookup (sig->signal_name, G_OBJECT_TYPE (object));
if (!signal_id)
switch (sig->action_type)
{
accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);
g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": "
"could not find signal \"%s\" in the '%s' class ancestry",
entry->binding_set->set_name,
accelerator,
sig->signal_name,
g_type_name (G_OBJECT_TYPE (object)));
g_free (accelerator);
continue;
}
case GTK_BINDING_SIGNAL:
handled = binding_signal_activate_signal (sig, object);
break;
g_signal_query (signal_id, &query);
if (query.n_params != sig->n_args ||
(query.return_type != G_TYPE_NONE && query.return_type != G_TYPE_BOOLEAN) ||
!binding_compose_params (object, sig->args, &query, &params))
{
accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);
g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": "
"signature mismatch for signal \"%s\" in the '%s' class ancestry",
entry->binding_set->set_name,
accelerator,
sig->signal_name,
g_type_name (G_OBJECT_TYPE (object)));
}
else if (!(query.signal_flags & G_SIGNAL_ACTION))
{
accelerator = gtk_accelerator_name (entry->keyval, entry->modifiers);
g_warning ("gtk_binding_entry_activate(): binding \"%s::%s\": "
"signal \"%s\" in the '%s' class ancestry cannot be used for action emissions",
entry->binding_set->set_name,
accelerator,
sig->signal_name,
g_type_name (G_OBJECT_TYPE (object)));
}
g_free (accelerator);
if (accelerator)
continue;
case GTK_BINDING_ACTION:
handled = binding_signal_activate_action (sig, object);
break;
if (query.return_type == G_TYPE_BOOLEAN)
g_value_init (&return_val, G_TYPE_BOOLEAN);
case GTK_BINDING_CALLBACK:
handled = binding_signal_activate_callback (sig, object);
break;
g_signal_emitv (params, signal_id, 0, &return_val);
if (query.return_type == G_TYPE_BOOLEAN)
{
if (g_value_get_boolean (&return_val))
handled = TRUE;
g_value_unset (&return_val);
}
else
handled = TRUE;
if (params != NULL)
{
for (i = 0; i < query.n_params + 1; i++)
g_value_unset (&params[i]);
g_free (params);
default:
g_assert_not_reached ();
break;
}
if (entry->destroyed)
@ -858,6 +988,30 @@ gtk_binding_entry_remove (GtkBindingSet *binding_set,
binding_entry_destroy (entry);
}
static void
gtk_binding_entry_add_binding_signal (GtkBindingSet *binding_set,
guint keyval,
GdkModifierType modifiers,
GtkBindingSignal *signal)
{
GtkBindingEntry *entry;
GtkBindingSignal **signal_p;
keyval = gdk_keyval_to_lower (keyval);
modifiers = modifiers & BINDING_MOD_MASK ();
entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
if (!entry)
{
gtk_binding_entry_clear_internal (binding_set, keyval, modifiers);
entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
}
signal_p = &entry->signals;
while (*signal_p)
signal_p = &(*signal_p)->next;
*signal_p = signal;
}
/*
* gtk_binding_entry_add_signall:
* @binding_set: a #GtkBindingSet to add a signal to
@ -877,8 +1031,7 @@ gtk_binding_entry_add_signall (GtkBindingSet *binding_set,
const gchar *signal_name,
GSList *binding_args)
{
GtkBindingEntry *entry;
GtkBindingSignal *signal, **signal_p;
GtkBindingSignal *signal;
GSList *slist;
guint n = 0;
GtkBindingArg *arg;
@ -886,10 +1039,7 @@ gtk_binding_entry_add_signall (GtkBindingSet *binding_set,
g_return_if_fail (binding_set != NULL);
g_return_if_fail (signal_name != NULL);
keyval = gdk_keyval_to_lower (keyval);
modifiers = modifiers & BINDING_MOD_MASK ();
signal = binding_signal_new (signal_name, g_slist_length (binding_args));
signal = binding_signal_new_signal (signal_name, g_slist_length (binding_args));
arg = signal->args;
for (slist = binding_args; slist; slist = slist->next)
@ -933,16 +1083,7 @@ gtk_binding_entry_add_signall (GtkBindingSet *binding_set,
n++;
}
entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
if (!entry)
{
gtk_binding_entry_clear_internal (binding_set, keyval, modifiers);
entry = binding_ht_lookup_entry (binding_set, keyval, modifiers);
}
signal_p = &entry->signals;
while (*signal_p)
signal_p = &(*signal_p)->next;
*signal_p = signal;
gtk_binding_entry_add_binding_signal (binding_set, keyval, modifiers, signal);
}
/**
@ -1060,6 +1201,96 @@ gtk_binding_entry_add_signal (GtkBindingSet *binding_set,
g_slist_free (free_slist);
}
/**
* gtk_binding_entry_add_action_variant:
* @binding_set: a #GtkBindingSet to install an entry for
* @keyval: key value of binding to install
* @modifiers: key modifier of binding to install
* @action_name: signal to execute upon activation
* @args: #GVariant of the arguments or %NULL if none
*
* Override or install a new key binding for @keyval with @modifiers on
* @binding_set. When the binding is activated, @action_name will be
* activated on the target widget, with @args used as arguments.
*/
void
gtk_binding_entry_add_action_variant (GtkBindingSet *binding_set,
guint keyval,
GdkModifierType modifiers,
const gchar *action_name,
GVariant *args)
{
g_return_if_fail (binding_set != NULL);
g_return_if_fail (action_name != NULL);
gtk_binding_entry_add_binding_signal (binding_set,
keyval,
modifiers,
binding_signal_new_action (action_name, args));
}
/**
* gtk_binding_entry_add_action:
* @binding_set: a #GtkBindingSet to install an entry for
* @keyval: key value of binding to install
* @modifiers: key modifier of binding to install
* @action_name: signal to execute upon activation
* @format_string: GVariant format string for arguments or %NULL
* for no arguments
* @...: arguments, as given by format string
*
* Override or install a new key binding for @keyval with @modifiers on
* @binding_set. When the binding is activated, @action_name will be
* activated on the target widget, with arguments read according to
* @format_string.
*/
void
gtk_binding_entry_add_action (GtkBindingSet *binding_set,
guint keyval,
GdkModifierType modifiers,
const char *action_name,
const char *format_string,
...)
{
GVariant *parameters = NULL;
g_return_if_fail (binding_set != NULL);
g_return_if_fail (action_name != NULL);
if (format_string != NULL)
{
va_list args;
va_start (args, format_string);
parameters = g_variant_new_va (format_string, NULL, &args);
va_end (args);
g_variant_ref_sink (parameters);
}
gtk_binding_entry_add_action_variant (binding_set, keyval, modifiers, action_name, parameters);
g_clear_pointer (&parameters, g_variant_unref);
}
void
gtk_binding_entry_add_callback (GtkBindingSet *binding_set,
guint keyval,
GdkModifierType modifiers,
GtkCallback callback,
gpointer user_data,
GDestroyNotify user_destroy)
{
g_return_if_fail (binding_set != NULL);
g_return_if_fail (callback != NULL);
gtk_binding_entry_add_binding_signal (binding_set,
keyval,
modifiers,
binding_signal_new_callback (callback, user_data, user_destroy));
}
static guint
gtk_binding_parse_signal (GScanner *scanner,
GtkBindingSet *binding_set,

View File

@ -35,6 +35,7 @@
#include <gdk/gdk.h>
#include <gtk/gtkenums.h>
#include <gtk/gtkwidget.h>
G_BEGIN_DECLS
@ -76,6 +77,28 @@ GDK_AVAILABLE_IN_ALL
GTokenType gtk_binding_entry_add_signal_from_string
(GtkBindingSet *binding_set,
const gchar *signal_desc);
GDK_AVAILABLE_IN_ALL
void gtk_binding_entry_add_action_variant
(GtkBindingSet *binding_set,
guint keyval,
GdkModifierType modifiers,
const char *action_name,
GVariant *args);
GDK_AVAILABLE_IN_ALL
void gtk_binding_entry_add_action (GtkBindingSet *binding_set,
guint keyval,
GdkModifierType modifiers,
const char *action_name,
const char *format_string,
...);
GDK_AVAILABLE_IN_ALL
void gtk_binding_entry_add_callback(GtkBindingSet *binding_set,
guint keyval,
GdkModifierType modifiers,
GtkCallback callback,
gpointer user_data,
GDestroyNotify user_destroy);
GDK_AVAILABLE_IN_ALL
void gtk_binding_entry_remove (GtkBindingSet *binding_set,

View File

@ -215,7 +215,7 @@ static void gtk_combo_box_get_property (GObject *object,
GValue *value,
GParamSpec *spec);
static void gtk_combo_box_grab_focus (GtkWidget *widget);
static gboolean gtk_combo_box_grab_focus (GtkWidget *widget);
static void gtk_combo_box_button_toggled (GtkWidget *widget,
gpointer data);
static void gtk_combo_box_add (GtkContainer *container,
@ -2323,7 +2323,7 @@ gtk_combo_box_mnemonic_activate (GtkWidget *widget,
return TRUE;
}
static void
static gboolean
gtk_combo_box_grab_focus (GtkWidget *widget)
{
GtkComboBox *combo_box = GTK_COMBO_BOX (widget);
@ -2335,10 +2335,12 @@ gtk_combo_box_grab_focus (GtkWidget *widget)
child = gtk_bin_get_child (GTK_BIN (combo_box));
if (child)
gtk_widget_grab_focus (child);
return gtk_widget_grab_focus (child);
else
return FALSE;
}
else
gtk_widget_grab_focus (priv->button);
return gtk_widget_grab_focus (priv->button);
}
static void

View File

@ -302,13 +302,13 @@ G_DEFINE_TYPE_WITH_CODE (GtkEntry, gtk_entry, GTK_TYPE_WIDGET,
G_IMPLEMENT_INTERFACE (GTK_TYPE_CELL_EDITABLE,
gtk_entry_cell_editable_init))
static void
static gboolean
gtk_entry_grab_focus (GtkWidget *widget)
{
GtkEntry *entry = GTK_ENTRY (widget);
GtkEntryPrivate *priv = gtk_entry_get_instance_private (entry);
gtk_widget_grab_focus (priv->text);
return gtk_widget_grab_focus (priv->text);
}
static gboolean

View File

@ -342,7 +342,7 @@ gtk_expander_class_init (GtkExpanderClass *klass)
G_TYPE_NONE, 0);
gtk_widget_class_set_accessible_type (widget_class, GTK_TYPE_EXPANDER_ACCESSIBLE);
gtk_widget_class_set_css_name (widget_class, I_("expander"));
gtk_widget_class_set_css_name (widget_class, I_("expander-widget"));
}
static void
@ -370,7 +370,7 @@ gtk_expander_init (GtkExpander *expander)
NULL);
gtk_container_add (GTK_CONTAINER (priv->box), priv->title_widget);
priv->arrow_widget = gtk_icon_new ("arrow");
priv->arrow_widget = gtk_icon_new ("expander");
gtk_style_context_add_class (gtk_widget_get_style_context (priv->arrow_widget),
GTK_STYLE_CLASS_HORIZONTAL);
gtk_container_add (GTK_CONTAINER (priv->title_widget), priv->arrow_widget);

View File

@ -83,7 +83,7 @@ static guint signals[LAST_SIGNAL] = { 0 };
static void gtk_file_chooser_entry_finalize (GObject *object);
static void gtk_file_chooser_entry_dispose (GObject *object);
static void gtk_file_chooser_entry_grab_focus (GtkWidget *widget);
static gboolean gtk_file_chooser_entry_grab_focus (GtkWidget *widget);
static gboolean gtk_file_chooser_entry_tab_handler (GtkEventControllerKey *key,
guint keyval,
guint keycode,
@ -497,11 +497,14 @@ explicitly_complete (GtkFileChooserEntry *chooser_entry)
gtk_widget_error_bell (GTK_WIDGET (chooser_entry));
}
static void
static gboolean
gtk_file_chooser_entry_grab_focus (GtkWidget *widget)
{
GTK_WIDGET_CLASS (_gtk_file_chooser_entry_parent_class)->grab_focus (widget);
if (!GTK_WIDGET_CLASS (_gtk_file_chooser_entry_parent_class)->grab_focus (widget))
return FALSE;
_gtk_file_chooser_entry_select_filename (GTK_FILE_CHOOSER_ENTRY (widget));
return TRUE;
}
static void

View File

@ -455,7 +455,7 @@ static void gtk_label_leave (GtkEventControllerMotion *controller,
GdkNotifyType detail,
gpointer data);
static void gtk_label_grab_focus (GtkWidget *widget);
static gboolean gtk_label_grab_focus (GtkWidget *widget);
static gboolean gtk_label_query_tooltip (GtkWidget *widget,
gint x,
@ -4272,7 +4272,7 @@ gtk_label_select_word (GtkLabel *label)
gtk_label_select_region_index (label, min, max);
}
static void
static gboolean
gtk_label_grab_focus (GtkWidget *widget)
{
GtkLabel *label = GTK_LABEL (widget);
@ -4282,9 +4282,10 @@ gtk_label_grab_focus (GtkWidget *widget)
GList *l;
if (priv->select_info == NULL)
return;
return FALSE;
GTK_WIDGET_CLASS (gtk_label_parent_class)->grab_focus (widget);
if (!GTK_WIDGET_CLASS (gtk_label_parent_class)->grab_focus (widget))
return FALSE;
if (priv->select_info->selectable)
{
@ -4313,6 +4314,8 @@ gtk_label_grab_focus (GtkWidget *widget)
}
}
}
return TRUE;
}
static gboolean

View File

@ -3409,18 +3409,21 @@ gtk_list_box_row_dispose (GObject *object)
G_OBJECT_CLASS (gtk_list_box_row_parent_class)->dispose (object);
}
static void
static gboolean
gtk_list_box_row_grab_focus (GtkWidget *widget)
{
GtkListBoxRow *row = GTK_LIST_BOX_ROW (widget);
GtkListBox *box = gtk_list_box_row_get_box (row);
g_return_if_fail (box != NULL);
g_return_val_if_fail (box != NULL, FALSE);
if (!GTK_WIDGET_CLASS (gtk_list_box_row_parent_class)->grab_focus (widget))
return FALSE;
if (BOX_PRIV (box)->cursor_row != row)
gtk_list_box_update_cursor (box, row, FALSE);
GTK_WIDGET_CLASS (gtk_list_box_row_parent_class)->grab_focus (widget);
return TRUE;
}
static void

254
gtk/gtknoselection.c Normal file
View File

@ -0,0 +1,254 @@
/*
* Copyright © 2019 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#include "config.h"
#include "gtknoselection.h"
#include "gtkintl.h"
#include "gtkselectionmodel.h"
/**
* SECTION:gtknoselection
* @Short_description: A selection model that does not allow selecting anything
* @Title: GtkNoSelection
* @see_also: #GtkSelectionModel
*
* GtkNoSelection is an implementation of the #GtkSelectionModel interface
* that does not allow selecting anything.
*
* This model is meant to be used as a simple wrapper to #GListModels when a
* #GtkSelectionModel is required.
*/
struct _GtkNoSelection
{
GObject parent_instance;
GListModel *model;
};
struct _GtkNoSelectionClass
{
GObjectClass parent_class;
};
enum {
PROP_0,
PROP_MODEL,
N_PROPS
};
static GParamSpec *properties[N_PROPS] = { NULL, };
static GType
gtk_no_selection_get_item_type (GListModel *list)
{
GtkNoSelection *self = GTK_NO_SELECTION (list);
return g_list_model_get_item_type (self->model);
}
static guint
gtk_no_selection_get_n_items (GListModel *list)
{
GtkNoSelection *self = GTK_NO_SELECTION (list);
return g_list_model_get_n_items (self->model);
}
static gpointer
gtk_no_selection_get_item (GListModel *list,
guint position)
{
GtkNoSelection *self = GTK_NO_SELECTION (list);
return g_list_model_get_item (self->model, position);
}
static void
gtk_no_selection_list_model_init (GListModelInterface *iface)
{
iface->get_item_type = gtk_no_selection_get_item_type;
iface->get_n_items = gtk_no_selection_get_n_items;
iface->get_item = gtk_no_selection_get_item;
}
static gboolean
gtk_no_selection_is_selected (GtkSelectionModel *model,
guint position)
{
return FALSE;
}
static void
gtk_no_selection_query_range (GtkSelectionModel *model,
guint position,
guint *start_range,
guint *n_range,
gboolean *selected)
{
GtkNoSelection *self = GTK_NO_SELECTION (model);
*start_range = 0;
*n_range = g_list_model_get_n_items (self->model);
*selected = FALSE;
}
static void
gtk_no_selection_selection_model_init (GtkSelectionModelInterface *iface)
{
iface->is_selected = gtk_no_selection_is_selected;
iface->query_range = gtk_no_selection_query_range;
}
G_DEFINE_TYPE_EXTENDED (GtkNoSelection, gtk_no_selection, G_TYPE_OBJECT, 0,
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL,
gtk_no_selection_list_model_init)
G_IMPLEMENT_INTERFACE (GTK_TYPE_SELECTION_MODEL,
gtk_no_selection_selection_model_init))
static void
gtk_no_selection_clear_model (GtkNoSelection *self)
{
if (self->model == NULL)
return;
g_signal_handlers_disconnect_by_func (self->model,
g_list_model_items_changed,
self);
g_clear_object (&self->model);
}
static void
gtk_no_selection_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkNoSelection *self = GTK_NO_SELECTION (object);
switch (prop_id)
{
case PROP_MODEL:
gtk_no_selection_clear_model (self);
self->model = g_value_dup_object (value);
g_signal_connect_swapped (self->model, "items-changed",
G_CALLBACK (g_list_model_items_changed), self);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_no_selection_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkNoSelection *self = GTK_NO_SELECTION (object);
switch (prop_id)
{
case PROP_MODEL:
g_value_set_object (value, self->model);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_no_selection_dispose (GObject *object)
{
GtkNoSelection *self = GTK_NO_SELECTION (object);
gtk_no_selection_clear_model (self);
G_OBJECT_CLASS (gtk_no_selection_parent_class)->dispose (object);
}
static void
gtk_no_selection_class_init (GtkNoSelectionClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->get_property = gtk_no_selection_get_property;
gobject_class->set_property = gtk_no_selection_set_property;
gobject_class->dispose = gtk_no_selection_dispose;
/**
* GtkNoSelection:model:
*
* The model being managed
*/
properties[PROP_MODEL] =
g_param_spec_object ("model",
P_("The model"),
P_("The model being managed"),
G_TYPE_LIST_MODEL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
static void
gtk_no_selection_init (GtkNoSelection *self)
{
}
/**
* gtk_no_selection_new:
* @model: (transfer none): the #GListModel to manage
*
* Creates a new selection to handle @model.
*
* Returns: (transfer full) (type GtkNoSelection): a new #GtkNoSelection
**/
GtkNoSelection *
gtk_no_selection_new (GListModel *model)
{
g_return_val_if_fail (G_IS_LIST_MODEL (model), NULL);
return g_object_new (GTK_TYPE_NO_SELECTION,
"model", model,
NULL);
}
/**
* gtk_no_selection_get_model:
* @self: a #GtkNoSelection
*
* Gets the model that @self is wrapping.
*
* Returns: (transfer none): The model being wrapped
**/
GListModel *
gtk_no_selection_get_model (GtkNoSelection *self)
{
g_return_val_if_fail (GTK_IS_NO_SELECTION (self), NULL);
return self->model;
}

40
gtk/gtknoselection.h Normal file
View File

@ -0,0 +1,40 @@
/*
* Copyright © 2019 Benjamin Otte
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
* Authors: Benjamin Otte <otte@gnome.org>
*/
#ifndef __GTK_NO_SELECTION_H__
#define __GTK_NO_SELECTION_H__
#include <gtk/gtktypes.h>
G_BEGIN_DECLS
#define GTK_TYPE_NO_SELECTION (gtk_no_selection_get_type ())
GDK_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (GtkNoSelection, gtk_no_selection, GTK, NO_SELECTION, GObject)
GDK_AVAILABLE_IN_ALL
GtkNoSelection * gtk_no_selection_new (GListModel *model);
GDK_AVAILABLE_IN_ALL
GListModel * gtk_no_selection_get_model (GtkNoSelection *self);
G_END_DECLS
#endif /* __GTK_NO_SELECTION_H__ */

View File

@ -346,13 +346,13 @@ gtk_password_entry_get_accessible (GtkWidget *widget)
return atk_obj;
}
static void
static gboolean
gtk_password_entry_grab_focus (GtkWidget *widget)
{
GtkPasswordEntry *entry = GTK_PASSWORD_ENTRY (widget);
GtkPasswordEntryPrivate *priv = gtk_password_entry_get_instance_private (entry);
gtk_widget_grab_focus (priv->entry);
return gtk_widget_grab_focus (priv->entry);
}
static gboolean

View File

@ -241,13 +241,13 @@ gtk_search_entry_get_accessible (GtkWidget *widget)
return atk_obj;
}
static void
static gboolean
gtk_search_entry_grab_focus (GtkWidget *widget)
{
GtkSearchEntry *entry = GTK_SEARCH_ENTRY (widget);
GtkSearchEntryPrivate *priv = gtk_search_entry_get_instance_private (entry);
gtk_text_grab_focus_without_selecting (GTK_TEXT (priv->entry));
return gtk_text_grab_focus_without_selecting (GTK_TEXT (priv->entry));
}
static gboolean

View File

@ -329,9 +329,8 @@ gtk_single_selection_set_property (GObject *object,
case PROP_MODEL:
gtk_single_selection_clear_model (self);
self->model = g_value_dup_object (value);
if (self->model)
g_signal_connect (self->model, "items-changed",
G_CALLBACK (gtk_single_selection_items_changed_cb), self);
g_signal_connect (self->model, "items-changed",
G_CALLBACK (gtk_single_selection_items_changed_cb), self);
if (self->autoselect)
gtk_single_selection_set_selected (self, 0);
break;
@ -461,7 +460,7 @@ gtk_single_selection_class_init (GtkSingleSelectionClass *klass)
P_("The model"),
P_("The model being managed"),
G_TYPE_LIST_MODEL,
G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (gobject_class, N_PROPS, properties);
}
@ -491,6 +490,22 @@ gtk_single_selection_new (GListModel *model)
NULL);
}
/**
* gtk_single_selection_get_model:
* @self: a #GtkSingleSelection
*
* Gets the model that @self is wrapping.
*
* Returns: (transfer none): The model being wrapped
**/
GListModel *
gtk_single_selection_get_model (GtkSingleSelection *self)
{
g_return_val_if_fail (GTK_IS_SINGLE_SELECTION (self), NULL);
return self->model;
}
/**
* gtk_single_selection_get_selected:
* @self: a #GtkSingleSelection

View File

@ -42,8 +42,10 @@ GDK_AVAILABLE_IN_ALL
G_DECLARE_FINAL_TYPE (GtkSingleSelection, gtk_single_selection, GTK, SINGLE_SELECTION, GObject)
GDK_AVAILABLE_IN_ALL
GtkSingleSelection * gtk_single_selection_new (GListModel *model);
GtkSingleSelection * gtk_single_selection_new (GListModel *model);
GDK_AVAILABLE_IN_ALL
GListModel * gtk_single_selection_get_model (GtkSingleSelection *self);
GDK_AVAILABLE_IN_ALL
guint gtk_single_selection_get_selected (GtkSingleSelection *self);
GDK_AVAILABLE_IN_ALL

View File

@ -317,13 +317,13 @@ G_DEFINE_TYPE_WITH_CODE (GtkSpinButton, gtk_spin_button, GTK_TYPE_WIDGET,
GTK_TYPE_SCROLL_TYPE, scroll)
static void
static gboolean
gtk_spin_button_grab_focus (GtkWidget *widget)
{
GtkSpinButton *spin_button = GTK_SPIN_BUTTON (widget);
GtkSpinButtonPrivate *priv = gtk_spin_button_get_instance_private (spin_button);
gtk_widget_grab_focus (priv->entry);
return gtk_widget_grab_focus (priv->entry);
}
static gboolean
@ -333,9 +333,7 @@ gtk_spin_button_mnemonic_activate (GtkWidget *widget,
GtkSpinButton *spin_button = GTK_SPIN_BUTTON (widget);
GtkSpinButtonPrivate *priv = gtk_spin_button_get_instance_private (spin_button);
gtk_widget_grab_focus (priv->entry);
return TRUE;
return gtk_widget_grab_focus (priv->entry);
}
static void

View File

@ -321,7 +321,7 @@ static void gtk_text_snapshot (GtkWidget *widget,
GtkSnapshot *snapshot);
static void gtk_text_focus_in (GtkWidget *widget);
static void gtk_text_focus_out (GtkWidget *widget);
static void gtk_text_grab_focus (GtkWidget *widget);
static gboolean gtk_text_grab_focus (GtkWidget *widget);
static void gtk_text_style_updated (GtkWidget *widget);
static void gtk_text_direction_changed (GtkWidget *widget,
GtkTextDirection previous_dir);
@ -3017,14 +3017,15 @@ gtk_text_focus_out (GtkWidget *widget)
g_signal_handlers_disconnect_by_func (keymap, keymap_direction_changed, self);
}
static void
static gboolean
gtk_text_grab_focus (GtkWidget *widget)
{
GtkText *self = GTK_TEXT (widget);
GtkTextPrivate *priv = gtk_text_get_instance_private (self);
gboolean select_on_focus;
GTK_WIDGET_CLASS (gtk_text_parent_class)->grab_focus (GTK_WIDGET (self));
if (!GTK_WIDGET_CLASS (gtk_text_parent_class)->grab_focus (GTK_WIDGET (self)))
return FALSE;
if (priv->editable && !priv->in_click)
{
@ -3036,6 +3037,8 @@ gtk_text_grab_focus (GtkWidget *widget)
if (select_on_focus)
gtk_text_set_selection_bounds (self, 0, -1);
}
return TRUE;
}
/**
@ -3049,13 +3052,15 @@ gtk_text_grab_focus (GtkWidget *widget)
* You only want to call this on some special entries
* which the user usually doesn't want to replace all text in,
* such as search-as-you-type entries.
*
* Returns: %TRUE if focus is now inside @self
*/
void
gboolean
gtk_text_grab_focus_without_selecting (GtkText *self)
{
g_return_if_fail (GTK_IS_TEXT (self));
g_return_val_if_fail (GTK_IS_TEXT (self), FALSE);
GTK_WIDGET_CLASS (gtk_text_parent_class)->grab_focus (GTK_WIDGET (self));
return GTK_WIDGET_CLASS (gtk_text_parent_class)->grab_focus (GTK_WIDGET (self));
}
static void

View File

@ -132,7 +132,7 @@ GDK_AVAILABLE_IN_ALL
PangoTabArray * gtk_text_get_tabs (GtkText *self);
GDK_AVAILABLE_IN_ALL
void gtk_text_grab_focus_without_selecting (GtkText *self);
gboolean gtk_text_grab_focus_without_selecting (GtkText *self);
GDK_AVAILABLE_IN_ALL
void gtk_text_set_extra_menu (GtkText *self,

View File

@ -669,7 +669,7 @@ static void gtk_tree_view_key_controller_focus_out (GtkEventControllerKey
static gint gtk_tree_view_focus (GtkWidget *widget,
GtkDirectionType direction);
static void gtk_tree_view_grab_focus (GtkWidget *widget);
static gboolean gtk_tree_view_grab_focus (GtkWidget *widget);
static void gtk_tree_view_style_updated (GtkWidget *widget);
/* container signals */
@ -8033,8 +8033,7 @@ gtk_tree_view_focus (GtkWidget *widget,
return FALSE;
case GTK_DIR_TAB_FORWARD:
case GTK_DIR_DOWN:
gtk_widget_grab_focus (widget);
return TRUE;
return gtk_widget_grab_focus (widget);
default:
g_assert_not_reached ();
return FALSE;
@ -8044,8 +8043,7 @@ gtk_tree_view_focus (GtkWidget *widget,
/* Case 2. We don't have focus at all. */
if (!gtk_widget_has_focus (widget))
{
gtk_widget_grab_focus (widget);
return TRUE;
return gtk_widget_grab_focus (widget);
}
/* Case 3. We have focus already. */
@ -8055,16 +8053,17 @@ gtk_tree_view_focus (GtkWidget *widget,
return FALSE;
/* Other directions caught by the keybindings */
gtk_widget_grab_focus (widget);
return TRUE;
return gtk_widget_grab_focus (widget);
}
static void
static gboolean
gtk_tree_view_grab_focus (GtkWidget *widget)
{
GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->grab_focus (widget);
if (!GTK_WIDGET_CLASS (gtk_tree_view_parent_class)->grab_focus (widget))
return FALSE;
gtk_tree_view_focus_to_cursor (GTK_TREE_VIEW (widget));
return TRUE;
}
static void

View File

@ -623,7 +623,7 @@ static void gtk_widget_real_size_allocate (GtkWidget *widget,
static void gtk_widget_real_direction_changed(GtkWidget *widget,
GtkTextDirection previous_direction);
static void gtk_widget_real_grab_focus (GtkWidget *focus_widget);
static gboolean gtk_widget_real_grab_focus (GtkWidget *focus_widget);
static gboolean gtk_widget_real_query_tooltip (GtkWidget *widget,
gint x,
gint y,
@ -5139,7 +5139,7 @@ gtk_widget_real_mnemonic_activate (GtkWidget *widget,
if (!group_cycling && GTK_WIDGET_GET_CLASS (widget)->activate_signal)
gtk_widget_activate (widget);
else if (gtk_widget_get_can_focus (widget))
gtk_widget_grab_focus (widget);
return gtk_widget_grab_focus (widget);
else
{
g_warning ("widget '%s' isn't suitable for mnemonic activation",
@ -5411,23 +5411,48 @@ _gtk_widget_grab_notify (GtkWidget *widget,
* Causes @widget (or one of its descendents) to have the keyboard focus
* for the #GtkWindow it's inside.
*
* @widget must be focusable, or have a ::grab_focus implementation that
* transfers the focus to a descendant of @widget that is focusable.
* If @widget is not focusable, or its ::grab_focus implementation cannot
* transfer the focus to a descendant of @widget that is focusable, it will
* not take focus and %FALSE will be returned.
*
* Calling gtk_widget_grab_focus() on an already focused widget is allowed,
* should not have an effect, and return %TRUE.
*
* Returns: %TRUE if focus is now inside @widget.
**/
void
gboolean
gtk_widget_grab_focus (GtkWidget *widget)
{
g_return_if_fail (GTK_IS_WIDGET (widget));
g_return_val_if_fail (GTK_IS_WIDGET (widget), FALSE);
GTK_WIDGET_GET_CLASS (widget)->grab_focus (widget);
if (!gtk_widget_is_sensitive (widget) ||
widget->priv->root == NULL)
return FALSE;
return GTK_WIDGET_GET_CLASS (widget)->grab_focus (widget);
}
static void
static gboolean
gtk_widget_real_grab_focus (GtkWidget *focus_widget)
{
GtkWidgetPrivate *priv = gtk_widget_get_instance_private (focus_widget);
if (priv->root)
gtk_root_set_focus (priv->root, focus_widget);
GtkWidget *child;
if (priv->can_focus)
{
gtk_root_set_focus (priv->root, focus_widget);
return TRUE;
}
for (child = _gtk_widget_get_first_child (focus_widget);
child != NULL;
child = _gtk_widget_get_next_sibling (child))
{
if (gtk_widget_grab_focus (child))
return TRUE;
}
return FALSE;
}
static gboolean
@ -12444,8 +12469,11 @@ gtk_widget_get_template_child (GtkWidget *widget,
*
* The arguments must match the actions expected parameter
* type, as returned by g_action_get_parameter_type().
*
* Returns: %TRUE if the action was activated, %FALSE if the action does
* not exist.
*/
void
gboolean
gtk_widget_activate_action_variant (GtkWidget *widget,
const char *name,
GVariant *args)
@ -12453,8 +12481,15 @@ gtk_widget_activate_action_variant (GtkWidget *widget,
GtkActionMuxer *muxer;
muxer = _gtk_widget_get_action_muxer (widget, FALSE);
if (muxer)
g_action_group_activate_action (G_ACTION_GROUP (muxer), name, args);
if (muxer == NULL)
return FALSE;
if (!g_action_group_has_action (G_ACTION_GROUP (muxer), name))
return FALSE;
g_action_group_activate_action (G_ACTION_GROUP (muxer), name, args);
return TRUE;
}
/**
@ -12470,14 +12505,18 @@ gtk_widget_activate_action_variant (GtkWidget *widget,
*
* This is a wrapper around gtk_widget_activate_action_variant()
* that constructs the @args variant according to @format_string.
*
* Returns: %TRUE if the action was activated, %FALSE if the action does
* not exist.
*/
void
gboolean
gtk_widget_activate_action (GtkWidget *widget,
const char *name,
const char *format_string,
...)
{
GVariant *parameters = NULL;
gboolean result;
if (format_string != NULL)
{
@ -12490,9 +12529,11 @@ gtk_widget_activate_action (GtkWidget *widget,
g_variant_ref_sink (parameters);
}
gtk_widget_activate_action_variant (widget, name, parameters);
result = gtk_widget_activate_action_variant (widget, name, parameters);
g_clear_pointer (&parameters, g_variant_unref);
return result;
}
/**

View File

@ -266,7 +266,7 @@ struct _GtkWidgetClass
gboolean group_cycling);
/* explicit focus */
void (* grab_focus) (GtkWidget *widget);
gboolean (* grab_focus) (GtkWidget *widget);
gboolean (* focus) (GtkWidget *widget,
GtkDirectionType direction);
@ -460,7 +460,7 @@ gboolean gtk_widget_is_focus (GtkWidget *widget);
GDK_AVAILABLE_IN_ALL
gboolean gtk_widget_has_visible_focus (GtkWidget *widget);
GDK_AVAILABLE_IN_ALL
void gtk_widget_grab_focus (GtkWidget *widget);
gboolean gtk_widget_grab_focus (GtkWidget *widget);
GDK_AVAILABLE_IN_ALL
void gtk_widget_set_focus_on_click (GtkWidget *widget,
gboolean focus_on_click);
@ -972,17 +972,17 @@ void gtk_widget_insert_action_group (GtkWidget *widget,
GActionGroup *group);
GDK_AVAILABLE_IN_ALL
void gtk_widget_activate_action (GtkWidget *widget,
gboolean gtk_widget_activate_action (GtkWidget *widget,
const char *name,
const char *format_string,
...);
GDK_AVAILABLE_IN_ALL
void gtk_widget_activate_action_variant (GtkWidget *widget,
gboolean gtk_widget_activate_action_variant (GtkWidget *widget,
const char *name,
GVariant *args);
GDK_AVAILABLE_IN_ALL
void gtk_widget_activate_default (GtkWidget *widget);
void gtk_widget_activate_default (GtkWidget *widget);
GDK_AVAILABLE_IN_ALL
void gtk_widget_set_font_map (GtkWidget *widget,

View File

@ -295,6 +295,7 @@ gtk_public_sources = files([
'gtkmountoperation.c',
'gtknativedialog.c',
'gtknomediafile.c',
'gtknoselection.c',
'gtknotebook.c',
'gtkorientable.c',
'gtkoverlay.c',
@ -554,6 +555,7 @@ gtk_public_headers = files([
'gtkmountoperation.h',
'gtknative.h',
'gtknativedialog.h',
'gtknoselection.h',
'gtknotebook.h',
'gtkorientable.h',
'gtkoverlay.h',

View File

@ -3798,21 +3798,19 @@ row {
* Expanders *
*************/
expander {
title > arrow {
min-width: 16px;
min-height: 16px;
-gtk-icon-source: -gtk-icontheme('pan-end-symbolic');
&:dir(rtl) { -gtk-icon-source: -gtk-icontheme('pan-end-symbolic-rtl'); }
min-width: 16px;
min-height: 16px;
-gtk-icon-source: -gtk-icontheme('pan-end-symbolic');
&:dir(rtl) { -gtk-icon-source: -gtk-icontheme('pan-end-symbolic-rtl'); }
&:disabled { color: $insensitive_fg_color; }
&:disabled:backdrop { color: $backdrop_insensitive_color; }
}
&:disabled { color: $insensitive_fg_color; }
&:disabled:backdrop { color: $backdrop_insensitive_color; }
title > arrow:checked, title:checked > arrow { -gtk-icon-source: -gtk-icontheme('pan-down-symbolic'); }
&:checked { -gtk-icon-source: -gtk-icontheme('pan-down-symbolic'); }
}
title:hover > arrow {
color: lighten($fg_color,30%); //only lightens the arrow
}
expander-widget title:hover > expander {
color: lighten($fg_color,30%); //only lightens the icon
}

View File

@ -1655,17 +1655,17 @@ row.activatable:selected:backdrop { background-color: #15539e; }
.app-notification border, .app-notification.frame border { border: none; }
/************* Expanders * */
expander title > arrow { min-width: 16px; min-height: 16px; -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
expander { min-width: 16px; min-height: 16px; -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
expander title > arrow:dir(rtl) { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); }
expander:dir(rtl) { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); }
expander title > arrow:disabled { color: #919190; }
expander:disabled { color: #919190; }
expander title > arrow:disabled:backdrop { color: #5b5b5b; }
expander:disabled:backdrop { color: #5b5b5b; }
expander title > arrow:checked, expander title:checked > arrow { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
expander:checked { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
expander title:hover > arrow { color: white; }
expander-widget title:hover > expander { color: white; }
/************ Calendar * */
calendar { color: white; border: 1px solid #1b1b1b; }

View File

@ -1671,17 +1671,17 @@ row.activatable:selected:backdrop { background-color: #3584e4; }
.app-notification border, .app-notification.frame border { border: none; }
/************* Expanders * */
expander title > arrow { min-width: 16px; min-height: 16px; -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
expander { min-width: 16px; min-height: 16px; -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
expander title > arrow:dir(rtl) { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); }
expander:dir(rtl) { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); }
expander title > arrow:disabled { color: #929595; }
expander:disabled { color: #929595; }
expander title > arrow:disabled:backdrop { color: #d4cfca; }
expander:disabled:backdrop { color: #d4cfca; }
expander title > arrow:checked, expander title:checked > arrow { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
expander:checked { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
expander title:hover > arrow { color: #748489; }
expander-widget title:hover > expander { color: #748489; }
/************ Calendar * */
calendar { color: black; border: 1px solid #cdc7c2; }

View File

@ -2763,20 +2763,18 @@ row.activatable {
*************/
expander {
title > arrow {
min-width: 24px;
min-height: 24px;
-gtk-icon-source: -gtk-icontheme('pan-end-symbolic');
&:dir(rtl) { -gtk-icon-source: -gtk-icontheme('pan-end-symbolic-rtl'); }
min-width: 24px;
min-height: 24px;
-gtk-icon-source: -gtk-icontheme('pan-end-symbolic');
&:dir(rtl) { -gtk-icon-source: -gtk-icontheme('pan-end-symbolic-rtl'); }
&:disabled { color: $insensitive_fg_color; }
&:checked { -gtk-icon-source: -gtk-icontheme('pan-down-symbolic'); }
&:checked { -gtk-icon-source: -gtk-icontheme('pan-down-symbolic'); }
}
&:disabled { color: $insensitive_fg_color; }
}
title:hover > arrow {
color: lighten($fg_color,30%); //only lightens the arrow
}
expander-widget title:hover > expander {
color: lighten($fg_color,30%); //only lightens the icon
}
/************

View File

@ -675,7 +675,7 @@ notebook.frame { border: 1px solid gray; }
notebook.frame:backdrop { border-color: #737373; }
notebook header { background-color: #262626; }
notebook header { background-color: #131313; }
.frame notebook header { border: 1px solid gray; }
@ -789,11 +789,11 @@ notebook tab:backdrop { background-color: transparent; border-color: transparent
.right notebook tab.reorderable-page:backdrop { border-color: transparent; background-color: transparent; }
notebook tab label { padding: 0 2px; font-weight: bold; color: gray; /* color: inherit doesn't work here */ }
notebook tab label { padding: 0 2px; font-weight: bold; color: silver; /* color: inherit doesn't work here */ }
notebook tab label:backdrop { color: gray; }
notebook tab:hover label { color: silver; }
notebook tab:hover label { color: #dfdfdf; }
notebook tab:checked label { color: #fff; }
@ -1242,15 +1242,15 @@ row:hover, row.activatable:hover { transition: none; }
.app-notification border, .app-notification.frame border { border-width: 0; }
/************* Expanders * */
expander title > arrow { min-width: 24px; min-height: 24px; -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
expander { min-width: 24px; min-height: 24px; -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
expander title > arrow:dir(rtl) { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); }
expander:dir(rtl) { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); }
expander title > arrow:disabled { color: gray; }
expander:checked { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
expander title > arrow:checked { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
expander:disabled { color: gray; }
expander title:hover > arrow { color: white; }
expander-widget title:hover > expander { color: white; }
/************ Calendar * */
calendar { border: 1px solid gray; }

View File

@ -679,7 +679,7 @@ notebook.frame { border: 1px solid gray; }
notebook.frame:backdrop { border-color: #8d8d8d; }
notebook header { background-color: #d9d9d9; }
notebook header { background-color: #ececec; }
.frame notebook header { border: 1px solid gray; }
@ -793,11 +793,11 @@ notebook tab:backdrop { background-color: transparent; border-color: transparent
.right notebook tab.reorderable-page:backdrop { border-color: transparent; background-color: transparent; }
notebook tab label { padding: 0 2px; font-weight: bold; color: gray; /* color: inherit doesn't work here */ }
notebook tab label { padding: 0 2px; font-weight: bold; color: #404040; /* color: inherit doesn't work here */ }
notebook tab label:backdrop { color: gray; }
notebook tab:hover label { color: #404040; }
notebook tab:hover label { color: #202020; }
notebook tab:checked label { color: #000; }
@ -1248,15 +1248,15 @@ row:hover, row.activatable:hover { transition: none; }
.app-notification border, .app-notification.frame border { border-width: 0; }
/************* Expanders * */
expander title > arrow { min-width: 24px; min-height: 24px; -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
expander { min-width: 24px; min-height: 24px; -gtk-icon-source: -gtk-icontheme("pan-end-symbolic"); }
expander title > arrow:dir(rtl) { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); }
expander:dir(rtl) { -gtk-icon-source: -gtk-icontheme("pan-end-symbolic-rtl"); }
expander title > arrow:disabled { color: gray; }
expander:checked { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
expander title > arrow:checked { -gtk-icon-source: -gtk-icontheme("pan-down-symbolic"); }
expander:disabled { color: gray; }
expander title:hover > arrow { color: #4d4d4d; }
expander-widget title:hover > expander { color: #4d4d4d; }
/************ Calendar * */
calendar { border: 1px solid gray; }

View File

@ -1,7 +1,7 @@
[window.background:dir(ltr)]
decoration:dir(ltr)
expander:dir(ltr)
expander-widget:dir(ltr)
box.vertical:dir(ltr)
title.horizontal:dir(ltr)
arrow.horizontal:dir(ltr)
expander.horizontal:dir(ltr)
label:dir(ltr)

View File

@ -1,7 +1,7 @@
[window.background:dir(rtl)]
decoration:dir(rtl)
expander:dir(rtl)
expander-widget:dir(rtl)
box.vertical:dir(rtl)
title.horizontal:dir(rtl)
arrow.horizontal:dir(rtl)
expander.horizontal:dir(rtl)
label:dir(rtl)

View File

@ -109,7 +109,9 @@ test_type (gconstpointer data)
instance = G_OBJECT (g_object_ref (gdk_surface_new_temp (display,
&(GdkRectangle) { 0, 0, 100, 100 })));
}
else if (g_type_is_a (type, GTK_TYPE_FILTER_LIST_MODEL))
else if (g_type_is_a (type, GTK_TYPE_FILTER_LIST_MODEL) ||
g_type_is_a (type, GTK_TYPE_NO_SELECTION) ||
g_type_is_a (type, GTK_TYPE_SINGLE_SELECTION))
{
GListStore *list_store = g_list_store_new (G_TYPE_OBJECT);
instance = g_object_new (type,
@ -255,7 +257,9 @@ G_GNUC_BEGIN_IGNORE_DEPRECATIONS
G_GNUC_END_IGNORE_DEPRECATIONS
if (g_type_is_a (type, GTK_TYPE_FILTER_LIST_MODEL) &&
if ((g_type_is_a (type, GTK_TYPE_FILTER_LIST_MODEL) ||
g_type_is_a (type, GTK_TYPE_NO_SELECTION) ||
g_type_is_a (type, GTK_TYPE_SINGLE_SELECTION)) &&
strcmp (pspec->name, "model") == 0)
continue;

View File

@ -431,7 +431,9 @@ test_type (gconstpointer data)
NULL);
gdk_content_formats_unref (formats);
}
else if (g_type_is_a (type, GTK_TYPE_FILTER_LIST_MODEL))
else if (g_type_is_a (type, GTK_TYPE_FILTER_LIST_MODEL) ||
g_type_is_a (type, GTK_TYPE_NO_SELECTION) ||
g_type_is_a (type, GTK_TYPE_SINGLE_SELECTION))
{
GListStore *list_store = g_list_store_new (G_TYPE_OBJECT);
instance = g_object_new (type,

View File

@ -64,7 +64,9 @@ test_finalize_object (gconstpointer data)
NULL);
gdk_content_formats_unref (formats);
}
else if (g_type_is_a (test_type, GTK_TYPE_FILTER_LIST_MODEL))
else if (g_type_is_a (test_type, GTK_TYPE_FILTER_LIST_MODEL) ||
g_type_is_a (test_type, GTK_TYPE_NO_SELECTION) ||
g_type_is_a (test_type, GTK_TYPE_SINGLE_SELECTION))
{
GListStore *list_store = g_list_store_new (G_TYPE_OBJECT);
object = g_object_new (test_type,