keyboard: Port to GTK4

Drop the wm-common insanity.
This commit is contained in:
Georges Basile Stavracas Neto 2021-10-31 17:40:27 -03:00
parent 8141af469c
commit d7e794e7ab
25 changed files with 805 additions and 1327 deletions

View file

@ -22,7 +22,6 @@
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include <libgnome-desktop/gnome-languages.h>
#include "list-box-helper.h"
#include "cc-common-language.h"
#include "cc-util.h"
#include "cc-input-chooser.h"
@ -139,26 +138,23 @@ padded_label_new (const gchar *text,
if (direction == ROW_TRAVEL_DIRECTION_BACKWARD)
{
arrow = gtk_image_new_from_icon_name ("go-previous-symbolic", GTK_ICON_SIZE_MENU);
gtk_widget_show (arrow);
gtk_container_add (GTK_CONTAINER (widget), arrow);
arrow = gtk_image_new_from_icon_name ("go-previous-symbolic");
gtk_box_append (GTK_BOX (widget), arrow);
}
label = gtk_label_new (text);
gtk_widget_show (label);
gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_MIDDLE);
gtk_widget_set_hexpand (label, TRUE);
gtk_widget_set_halign (label, alignment);
set_row_widget_margins (label);
gtk_container_add (GTK_CONTAINER (widget), label);
gtk_box_append (GTK_BOX (widget), label);
if (dim_label)
gtk_style_context_add_class (gtk_widget_get_style_context (label), "dim-label");
if (direction == ROW_TRAVEL_DIRECTION_FORWARD)
{
arrow = gtk_image_new_from_icon_name ("go-next-symbolic", GTK_ICON_SIZE_MENU);
gtk_widget_show (arrow);
gtk_container_add (GTK_CONTAINER (widget), arrow);
arrow = gtk_image_new_from_icon_name ("go-next-symbolic");
gtk_box_append (GTK_BOX (widget), arrow);
}
return widget;
@ -173,16 +169,14 @@ more_row_new (void)
row = gtk_list_box_row_new ();
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
gtk_widget_show (box);
gtk_container_add (GTK_CONTAINER (row), box);
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), box);
gtk_widget_set_tooltip_text (row, _("More…"));
arrow = gtk_image_new_from_icon_name ("view-more-symbolic", GTK_ICON_SIZE_MENU);
gtk_widget_show (arrow);
gtk_style_context_add_class (gtk_widget_get_style_context (arrow), "dim-label");
arrow = gtk_image_new_from_icon_name ("view-more-symbolic");
gtk_widget_add_css_class (arrow, "dim-label");
gtk_widget_set_hexpand (arrow, TRUE);
set_row_widget_margins (arrow);
gtk_container_add (GTK_CONTAINER (box), arrow);
gtk_box_append (GTK_BOX (box), arrow);
return GTK_LIST_BOX_ROW (row);
}
@ -201,8 +195,7 @@ back_row_new (const gchar *text)
row = gtk_list_box_row_new ();
widget = padded_label_new (text, ROW_LABEL_POSITION_CENTER, ROW_TRAVEL_DIRECTION_BACKWARD, TRUE);
gtk_widget_show (widget);
gtk_container_add (GTK_CONTAINER (row), widget);
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), widget);
return GTK_LIST_BOX_ROW (row);
}
@ -215,8 +208,7 @@ locale_row_new (const gchar *text)
row = gtk_list_box_row_new ();
widget = padded_label_new (text, ROW_LABEL_POSITION_CENTER, ROW_TRAVEL_DIRECTION_NONE, FALSE);
gtk_widget_show (widget);
gtk_container_add (GTK_CONTAINER (row), widget);
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), widget);
return GTK_LIST_BOX_ROW (row);
}
@ -240,8 +232,7 @@ input_source_row_new (CcInputChooser *self,
ROW_LABEL_POSITION_START,
ROW_TRAVEL_DIRECTION_NONE,
FALSE);
gtk_widget_show (widget);
gtk_container_add (GTK_CONTAINER (row), widget);
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), widget);
g_object_set_data (G_OBJECT (row), "name", (gpointer) display_name);
g_object_set_data_full (G_OBJECT (row), "unaccented-name",
cc_util_normalize_casefold_and_unaccent (display_name), g_free);
@ -259,13 +250,12 @@ input_source_row_new (CcInputChooser *self,
ROW_LABEL_POSITION_START,
ROW_TRAVEL_DIRECTION_NONE,
FALSE);
gtk_widget_show (widget);
gtk_container_add (GTK_CONTAINER (row), widget);
image = gtk_image_new_from_icon_name ("system-run-symbolic", GTK_ICON_SIZE_MENU);
gtk_widget_show (image);
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), widget);
image = gtk_image_new_from_icon_name ("system-run-symbolic");
set_row_widget_margins (image);
gtk_style_context_add_class (gtk_widget_get_style_context (image), "dim-label");
gtk_container_add (GTK_CONTAINER (widget), image);
gtk_box_append (GTK_BOX (widget), image);
g_object_set_data_full (G_OBJECT (row), "name", display_name, g_free);
g_object_set_data_full (G_OBJECT (row), "unaccented-name",
@ -287,14 +277,12 @@ input_source_row_new (CcInputChooser *self,
}
static void
remove_all_children (GtkContainer *container)
remove_all_rows (GtkListBox *listbox)
{
g_autoptr(GList) list = NULL;
GList *l;
GtkWidget *child;
list = gtk_container_get_children (container);
for (l = list; l; l = l->next)
gtk_container_remove (container, (GtkWidget *) l->data);
while ((child = gtk_widget_get_first_child (GTK_WIDGET (listbox))) != NULL)
gtk_list_box_remove (listbox, child);
}
static void
@ -306,22 +294,22 @@ add_input_source_rows_for_locale (CcInputChooser *self,
const gchar *id;
if (info->default_input_source_row)
gtk_container_add (GTK_CONTAINER (self->input_sources_listbox), GTK_WIDGET (info->default_input_source_row));
gtk_list_box_append (self->input_sources_listbox, GTK_WIDGET (info->default_input_source_row));
g_hash_table_iter_init (&iter, info->layout_rows_by_id);
while (g_hash_table_iter_next (&iter, (gpointer *) &id, (gpointer *) &row))
gtk_container_add (GTK_CONTAINER (self->input_sources_listbox), row);
gtk_list_box_append (self->input_sources_listbox, row);
g_hash_table_iter_init (&iter, info->engine_rows_by_id);
while (g_hash_table_iter_next (&iter, (gpointer *) &id, (gpointer *) &row))
gtk_container_add (GTK_CONTAINER (self->input_sources_listbox), row);
gtk_list_box_append (self->input_sources_listbox, row);
}
static void
show_input_sources_for_locale (CcInputChooser *self,
LocaleInfo *info)
{
remove_all_children (GTK_CONTAINER (self->input_sources_listbox));
remove_all_rows (self->input_sources_listbox);
if (!info->back_row)
{
@ -330,13 +318,12 @@ show_input_sources_for_locale (CcInputChooser *self,
g_object_set_data (G_OBJECT (info->back_row), "back", GINT_TO_POINTER (TRUE));
g_object_set_data (G_OBJECT (info->back_row), "locale-info", info);
}
gtk_container_add (GTK_CONTAINER (self->input_sources_listbox), GTK_WIDGET (info->back_row));
gtk_list_box_append (self->input_sources_listbox, GTK_WIDGET (info->back_row));
add_input_source_rows_for_locale (self, info);
gtk_adjustment_set_value (self->scroll_adjustment,
gtk_adjustment_get_lower (self->scroll_adjustment));
gtk_list_box_set_header_func (self->input_sources_listbox, cc_list_box_update_header_func, NULL, NULL);
gtk_list_box_invalidate_filter (self->input_sources_listbox);
gtk_list_box_set_selection_mode (self->input_sources_listbox, GTK_SELECTION_SINGLE);
gtk_list_box_set_activate_on_single_click (self->input_sources_listbox, FALSE);
@ -360,7 +347,7 @@ show_locale_rows (CcInputChooser *self)
LocaleInfo *info;
GHashTableIter iter;
remove_all_children (GTK_CONTAINER (self->input_sources_listbox));
remove_all_rows (self->input_sources_listbox);
if (!self->showing_extra)
initial = cc_common_language_get_initial_languages ();
@ -384,14 +371,13 @@ show_locale_rows (CcInputChooser *self)
!is_current_locale (info->id))
g_object_set_data (G_OBJECT (info->locale_row), "is-extra", GINT_TO_POINTER (TRUE));
}
gtk_container_add (GTK_CONTAINER (self->input_sources_listbox), GTK_WIDGET (info->locale_row));
gtk_list_box_append (self->input_sources_listbox, GTK_WIDGET (info->locale_row));
}
gtk_container_add (GTK_CONTAINER (self->input_sources_listbox), GTK_WIDGET (self->more_row));
gtk_list_box_append (self->input_sources_listbox, GTK_WIDGET (self->more_row));
gtk_adjustment_set_value (self->scroll_adjustment,
gtk_adjustment_get_lower (self->scroll_adjustment));
gtk_list_box_set_header_func (self->input_sources_listbox, cc_list_box_update_header_func, NULL, NULL);
gtk_list_box_invalidate_filter (self->input_sources_listbox);
gtk_list_box_set_selection_mode (self->input_sources_listbox, GTK_SELECTION_NONE);
gtk_list_box_set_activate_on_single_click (self->input_sources_listbox, TRUE);
@ -573,7 +559,7 @@ do_filter (CcInputChooser *self)
self->filter_timeout_id = 0;
filter_contents =
cc_util_normalize_casefold_and_unaccent (gtk_entry_get_text (GTK_ENTRY (self->filter_entry)));
cc_util_normalize_casefold_and_unaccent (gtk_editable_get_text (GTK_EDITABLE (self->filter_entry)));
previous_words = self->filter_words;
self->filter_words = g_strsplit_set (g_strstrip (filter_contents), " ", 0);
@ -662,23 +648,6 @@ on_input_sources_listbox_selected_rows_changed_cb (CcInputChooser *self)
gtk_widget_set_sensitive (GTK_WIDGET (self->add_button), sensitive);
}
static gboolean
on_input_sources_listbox_button_release_event_cb (CcInputChooser *self, GdkEvent *event)
{
gdouble x, y;
GtkListBoxRow *row;
gdk_event_get_coords (event, &x, &y);
row = gtk_list_box_get_row_at_y (self->input_sources_listbox, y);
if (row && g_object_get_data (G_OBJECT (row), "back"))
{
g_signal_emit_by_name (row, "activate", NULL);
return TRUE;
}
return FALSE;
}
static void
add_default_row (CcInputChooser *self,
LocaleInfo *info,
@ -977,6 +946,7 @@ get_locale_infos (CcInputChooser *self)
add_row_other (self, INPUT_SOURCE_TYPE_XKB, l->data);
}
/*
static gboolean
on_filter_entry_key_release_event_cb (CcInputChooser *self, GdkEventKey *event)
{
@ -990,6 +960,7 @@ on_filter_entry_key_release_event_cb (CcInputChooser *self, GdkEventKey *event)
return FALSE;
}
*/
static void
cc_input_chooser_dispose (GObject *object)
@ -1026,15 +997,16 @@ cc_input_chooser_class_init (CcInputChooserClass *klass)
gtk_widget_class_bind_template_callback (widget_class, on_input_sources_listbox_row_activated_cb);
gtk_widget_class_bind_template_callback (widget_class, on_input_sources_listbox_selected_rows_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, on_input_sources_listbox_button_release_event_cb);
gtk_widget_class_bind_template_callback (widget_class, on_filter_entry_search_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, on_filter_entry_key_release_event_cb);
//gtk_widget_class_bind_template_callback (widget_class, on_filter_entry_key_release_event_cb);
}
void
cc_input_chooser_init (CcInputChooser *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
gtk_search_entry_set_key_capture_widget (self->filter_entry, GTK_WIDGET (self));
}
CcInputChooser *
@ -1043,7 +1015,6 @@ cc_input_chooser_new (gboolean is_login,
GHashTable *ibus_engines)
{
CcInputChooser *self;
g_autoptr(GError) error = NULL;
self = g_object_new (CC_TYPE_INPUT_CHOOSER,
"use-header-bar", 1,

View file

@ -9,8 +9,6 @@
<child type="action">
<object class="GtkButton" id="cancel_button">
<property name="label" translatable="yes">_Cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="use_underline">True</property>
<property name="valign">center</property>
</object>
@ -18,26 +16,20 @@
<child type="action">
<object class="GtkButton" id="add_button">
<property name="label" translatable="yes">_Add</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="sensitive">False</property>
<property name="use_underline">True</property>
<property name="valign">center</property>
</object>
</child>
<child internal-child="vbox">
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">0</property>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="hscrollbar-policy">never</property>
<property name="vscrollbar-policy">automatic</property>
<property name="propagate-natural-height">True</property>
<property name="shadow-type">in</property>
<property name="margin-start">6</property>
<property name="margin-end">6</property>
<property name="margin-top">6</property>
@ -46,14 +38,14 @@
<property name="vadjustment">scroll_adjustment</property>
<child>
<object class="GtkListBox" id="input_sources_listbox">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="vexpand">True</property>
<property name="halign">fill</property>
<property name="valign">fill</property>
<signal name="row-activated" handler="on_input_sources_listbox_row_activated_cb" object="CcInputChooser" swapped="yes" />
<signal name="selected-rows-changed" handler="on_input_sources_listbox_selected_rows_changed_cb" object="CcInputChooser" swapped="yes" />
<signal name="button-release-event" handler="on_input_sources_listbox_button_release_event_cb" object="CcInputChooser" swapped="yes" />
<style>
<class name="content" />
</style>
</object>
</child>
</object>
@ -67,7 +59,6 @@
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<signal name="search-changed" handler="on_filter_entry_search_changed_cb" object="CcInputChooser" swapped="yes" />
<signal name="key-release-event" handler="on_filter_entry_key_release_event_cb" object="CcInputChooser" swapped="yes" />
</object>
</child>
<child>

View file

@ -25,7 +25,6 @@
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include <libgnome-desktop/gnome-xkb-info.h>
#include "list-box-helper.h"
#include "cc-input-list-box.h"
#include "cc-input-chooser.h"
#include "cc-input-row.h"
@ -40,10 +39,11 @@
#define KEY_INPUT_SOURCES "sources"
struct _CcInputListBox {
GtkListBox parent_instance;
AdwBin parent_instance;
GtkListBoxRow *add_input_row;
GtkSizeGroup *input_size_group;
GtkListBox *listbox;
GtkListBoxRow *no_inputs_row;
GCancellable *cancellable;
@ -61,7 +61,7 @@ struct _CcInputListBox {
#endif
};
G_DEFINE_TYPE (CcInputListBox, cc_input_list_box, GTK_TYPE_LIST_BOX)
G_DEFINE_TYPE (CcInputListBox, cc_input_list_box, ADW_TYPE_BIN)
typedef struct
{
@ -97,18 +97,18 @@ static void show_input_chooser (CcInputListBox *self);
static void
update_ibus_active_sources (CcInputListBox *self)
{
g_autoptr(GList) rows = NULL;
GList *l;
GtkWidget *child;
rows = gtk_container_get_children (GTK_CONTAINER (self));
for (l = rows; l; l = l->next) {
for (child = gtk_widget_get_first_child (GTK_WIDGET (self->listbox));
child;
child = gtk_widget_get_next_sibling (child)) {
CcInputRow *row;
CcInputSourceIBus *source;
IBusEngineDesc *engine_desc;
if (!CC_IS_INPUT_ROW (l->data))
if (!CC_IS_INPUT_ROW (child))
continue;
row = CC_INPUT_ROW (l->data);
row = CC_INPUT_ROW (child);
if (!CC_IS_INPUT_SOURCE_IBUS (cc_input_row_get_source (row)))
continue;
@ -200,7 +200,7 @@ row_settings_cb (CcInputListBox *self,
return;
ctx = gdk_display_get_app_launch_context (gdk_display_get_default ());
gdk_app_launch_context_set_timestamp (ctx, gtk_get_current_event_time ());
gdk_app_launch_context_set_timestamp (ctx, GDK_CURRENT_TIME);
g_app_launch_context_setenv (G_APP_LAUNCH_CONTEXT (ctx),
"IBUS_ENGINE_NAME", cc_input_source_ibus_get_engine_name (source));
@ -254,20 +254,22 @@ row_removed_cb (CcInputListBox *self,
static void
update_input_rows (CcInputListBox *self)
{
g_autoptr(GList) rows = NULL;
GList *l;
GtkWidget *child;
guint n_input_rows = 0;
rows = gtk_container_get_children (GTK_CONTAINER (self));
for (l = rows; l; l = l->next)
if (CC_IS_INPUT_ROW (l->data))
child = gtk_widget_get_first_child (GTK_WIDGET (self->listbox));
while ((child = gtk_widget_get_next_sibling (child)) != NULL)
if (CC_IS_INPUT_ROW (child))
n_input_rows++;
for (l = rows; l; l = l->next) {
for (child = gtk_widget_get_first_child (GTK_WIDGET (self->listbox));
child;
child = gtk_widget_get_next_sibling (child)) {
CcInputRow *row;
if (!CC_IS_INPUT_ROW (l->data))
if (!CC_IS_INPUT_ROW (child))
continue;
row = CC_INPUT_ROW (l->data);
row = CC_INPUT_ROW (child);
cc_input_row_set_removable (row, n_input_rows > 1);
cc_input_row_set_draggable (row, n_input_rows > 1);
@ -288,7 +290,7 @@ add_input_row (CcInputListBox *self, CcInputSource *source)
g_signal_connect_object (row, "show-layout", G_CALLBACK (row_layout_cb), self, G_CONNECT_SWAPPED);
g_signal_connect_object (row, "move-row", G_CALLBACK (row_moved_cb), self, G_CONNECT_SWAPPED);
g_signal_connect_object (row, "remove-row", G_CALLBACK (row_removed_cb), self, G_CONNECT_SWAPPED);
gtk_list_box_insert (GTK_LIST_BOX (self), GTK_WIDGET (row), gtk_list_box_row_get_index (self->add_input_row));
gtk_list_box_insert (self->listbox, GTK_WIDGET (row), gtk_list_box_row_get_index (self->add_input_row));
update_input_rows (self);
}
@ -339,31 +341,32 @@ add_input_sources_from_settings (CcInputListBox *self)
static void
clear_input_sources (CcInputListBox *self)
{
g_autoptr(GList) list = NULL;
GList *l;
GtkWidget *child;
list = gtk_container_get_children (GTK_CONTAINER (self));
for (l = list; l; l = l->next) {
if (CC_IS_INPUT_ROW (l->data))
gtk_container_remove (GTK_CONTAINER (self), GTK_WIDGET (l->data));
child = gtk_widget_get_first_child (GTK_WIDGET (self->listbox));
while (child) {
GtkWidget *next = gtk_widget_get_next_sibling (child);
if (CC_IS_INPUT_ROW (child))
gtk_list_box_remove (self->listbox, GTK_WIDGET (child));
child = next;
}
cc_list_box_adjust_scrolling (GTK_LIST_BOX (self));
}
static CcInputRow *
get_row_by_source (CcInputListBox *self, CcInputSource *source)
{
g_autoptr(GList) list = NULL;
GList *l;
GtkWidget *child;
list = gtk_container_get_children (GTK_CONTAINER (self));
for (l = list; l; l = l->next) {
for (child = gtk_widget_get_first_child (GTK_WIDGET (self->listbox));
child;
child = gtk_widget_get_next_sibling (child)) {
CcInputRow *row;
if (!CC_IS_INPUT_ROW (l->data))
if (!CC_IS_INPUT_ROW (child))
continue;
row = CC_INPUT_ROW (l->data);
row = CC_INPUT_ROW (child);
if (cc_input_source_matches (source, cc_input_row_get_source (row)))
return row;
@ -379,7 +382,7 @@ input_sources_changed (CcInputListBox *self,
CcInputRow *selected;
g_autoptr(CcInputSource) source = NULL;
selected = CC_INPUT_ROW (gtk_list_box_get_selected_row (GTK_LIST_BOX (self)));
selected = CC_INPUT_ROW (gtk_list_box_get_selected_row (self->listbox));
if (selected)
source = g_object_ref (cc_input_row_get_source (selected));
clear_input_sources (self);
@ -387,7 +390,7 @@ input_sources_changed (CcInputListBox *self,
if (source != NULL) {
CcInputRow *row = get_row_by_source (self, source);
if (row != NULL)
gtk_list_box_select_row (GTK_LIST_BOX (self), GTK_LIST_BOX_ROW (row));
gtk_list_box_select_row (self->listbox, GTK_LIST_BOX_ROW (row));
}
}
@ -395,18 +398,19 @@ static void
set_input_settings (CcInputListBox *self)
{
GVariantBuilder builder;
g_autoptr(GList) list = NULL;
GList *l;
GtkWidget *child;
g_variant_builder_init (&builder, G_VARIANT_TYPE ("a(ss)"));
list = gtk_container_get_children (GTK_CONTAINER (self));
for (l = list; l; l = l->next) {
for (child = gtk_widget_get_first_child (GTK_WIDGET (self->listbox));
child;
child = gtk_widget_get_next_sibling (child)) {
CcInputRow *row;
CcInputSource *source;
if (!CC_IS_INPUT_ROW (l->data))
if (!CC_IS_INPUT_ROW (child))
continue;
row = CC_INPUT_ROW (l->data);
row = CC_INPUT_ROW (child);
source = cc_input_row_get_source (row);
if (CC_IS_INPUT_SOURCE_XKB (source)) {
@ -435,6 +439,24 @@ update_input (CcInputListBox *self)
}
}
static void
on_chooser_response_cb (GtkDialog *dialog,
gint response,
CcInputListBox *self)
{
if (response == GTK_RESPONSE_OK) {
CcInputSource *source;
source = cc_input_chooser_get_source (CC_INPUT_CHOOSER (dialog));
if (source != NULL && get_row_by_source (self, source) == NULL) {
add_input_row (self, source);
update_input (self);
}
}
gtk_window_destroy (GTK_WINDOW (dialog));
}
static void
show_input_chooser (CcInputListBox *self)
{
@ -448,18 +470,10 @@ show_input_chooser (CcInputListBox *self)
NULL
#endif
);
gtk_window_set_transient_for (GTK_WINDOW (chooser), GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (self))));
if (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_OK) {
CcInputSource *source;
source = cc_input_chooser_get_source (chooser);
if (source != NULL && get_row_by_source (self, source) == NULL) {
add_input_row (self, source);
update_input (self);
}
}
gtk_widget_destroy (GTK_WIDGET (chooser));
gtk_window_set_transient_for (GTK_WINDOW (chooser),
GTK_WINDOW (gtk_widget_get_native (GTK_WIDGET (self))));
g_signal_connect (chooser, "response", G_CALLBACK (on_chooser_response_cb), self);
gtk_window_present (GTK_WINDOW (chooser));
}
// Duplicated from cc-region-panel.c
@ -501,23 +515,20 @@ add_input (CcInputListBox *self)
}
static GtkWidget *
find_sibling (GtkContainer *container, GtkWidget *child)
find_sibling (GtkWidget *child)
{
g_autoptr(GList) list = NULL;
GList *c, *l;
GtkWidget *sibling;
list = gtk_container_get_children (container);
c = g_list_find (list, child);
for (l = c->next; l; l = l->next) {
sibling = l->data;
for (sibling = gtk_widget_get_next_sibling (child);
sibling;
sibling = gtk_widget_get_next_sibling (child)) {
if (gtk_widget_get_visible (sibling) && gtk_widget_get_child_visible (sibling))
return sibling;
}
for (l = c->prev; l; l = l->prev) {
sibling = l->data;
for (sibling = gtk_widget_get_prev_sibling (child);
sibling;
sibling = gtk_widget_get_prev_sibling (child)) {
if (gtk_widget_get_visible (sibling) && gtk_widget_get_child_visible (sibling))
return sibling;
}
@ -530,11 +541,9 @@ do_remove_input (CcInputListBox *self, CcInputRow *row)
{
GtkWidget *sibling;
sibling = find_sibling (GTK_CONTAINER (self), GTK_WIDGET (row));
gtk_container_remove (GTK_CONTAINER (self), GTK_WIDGET (row));
gtk_list_box_select_row (GTK_LIST_BOX (self), GTK_LIST_BOX_ROW (sibling));
cc_list_box_adjust_scrolling (GTK_LIST_BOX(self));
sibling = find_sibling (GTK_WIDGET (row));
gtk_list_box_remove (self->listbox, GTK_WIDGET (row));
gtk_list_box_select_row (self->listbox, GTK_LIST_BOX_ROW (sibling));
update_input (self);
update_input_rows (self);
@ -571,12 +580,10 @@ do_move_input (CcInputListBox *self, CcInputRow *source, CcInputRow *dest)
dest_index = gtk_list_box_row_get_index (GTK_LIST_BOX_ROW (dest));
g_object_ref (source);
gtk_container_remove (GTK_CONTAINER (self), GTK_WIDGET (source));
gtk_list_box_insert (GTK_LIST_BOX (self), GTK_WIDGET (source), dest_index);
gtk_list_box_remove (self->listbox, GTK_WIDGET (source));
gtk_list_box_insert (self->listbox, GTK_WIDGET (source), dest_index);
g_object_unref (source);
cc_list_box_adjust_scrolling (GTK_LIST_BOX (self));
update_input (self);
}
@ -659,22 +666,22 @@ set_localed_input (CcInputListBox *self)
{
g_autoptr(GString) layouts = NULL;
g_autoptr(GString) variants = NULL;
g_autoptr(GList) list = NULL;
GList *li;
GtkWidget *child;
layouts = g_string_new ("");
variants = g_string_new ("");
list = gtk_container_get_children (GTK_CONTAINER (self));
for (li = list; li; li = li->next) {
for (child = gtk_widget_get_first_child (GTK_WIDGET (self->listbox));
child;
child = gtk_widget_get_next_sibling (child)) {
CcInputRow *row;
CcInputSourceXkb *source;
g_autofree gchar *id = NULL;
const gchar *l, *v;
if (!CC_IS_INPUT_ROW (li->data))
if (!CC_IS_INPUT_ROW (child))
continue;
row = CC_INPUT_ROW (li->data);
row = CC_INPUT_ROW (child);
if (!CC_IS_INPUT_SOURCE_XKB (cc_input_row_get_source (row)))
continue;
@ -727,6 +734,7 @@ cc_input_list_box_class_init (CcInputListBoxClass *klass)
gtk_widget_class_bind_template_child (widget_class, CcInputListBox, add_input_row);
gtk_widget_class_bind_template_child (widget_class, CcInputListBox, input_size_group);
gtk_widget_class_bind_template_child (widget_class, CcInputListBox, listbox);
gtk_widget_class_bind_template_child (widget_class, CcInputListBox, no_inputs_row);
gtk_widget_class_bind_template_callback (widget_class, input_row_activated_cb);

View file

@ -26,10 +26,10 @@
G_BEGIN_DECLS
#include <gtk/gtk.h>
#include <adwaita.h>
#define CC_TYPE_INPUT_LIST_BOX (cc_input_list_box_get_type ())
G_DECLARE_FINAL_TYPE (CcInputListBox, cc_input_list_box, CC, INPUT_LIST_BOX, GtkListBox)
G_DECLARE_FINAL_TYPE (CcInputListBox, cc_input_list_box, CC, INPUT_LIST_BOX, AdwBin)
void cc_input_list_box_set_login (CcInputListBox *box,
gboolean login);

View file

@ -1,8 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<template class="CcInputListBox" parent="GtkListBox">
<property name="can_focus">True</property>
<template class="CcInputListBox" parent="AdwBin">
<child>
<object class="GtkListBox" id="listbox">
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="selection-mode">none</property>
<signal name="row_activated" handler="input_row_activated_cb" object="CcInputListBox" swapped="yes"/>
<style>
@ -10,16 +14,12 @@
</style>
<child>
<object class="GtkListBoxRow" id="no_inputs_row">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="selectable">False</property>
<property name="activatable">False</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="margin_bottom">8</property>
<property name="margin_top">8</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">No input source selected</property>
</object>
</child>
@ -27,13 +27,9 @@
</child>
<child>
<object class="GtkListBoxRow" id="add_input_row">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="selectable">False</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="height_request">50</property>
<property name="margin_start">12</property>
@ -43,6 +39,9 @@
</child>
</object>
</child>
</object>
</child>
</template>
<object class="GtkSizeGroup" id="input_size_group">
<property name="mode">vertical</property>

View file

@ -25,13 +25,16 @@ struct _CcInputRow
CcInputSource *source;
GtkEventBox *drag_handle;
GtkLabel *name_label;
GtkButton *remove_button;
GtkButton *settings_button;
GtkSeparator *settings_separator;
GtkListBox *drag_widget;
GtkDragSource *drag_source;
gdouble drag_x;
gdouble drag_y;
};
G_DEFINE_TYPE (CcInputRow, cc_input_row, GTK_TYPE_LIST_BOX_ROW)
@ -47,70 +50,61 @@ enum
static guint signals[SIGNAL_LAST] = { 0, };
static GdkContentProvider *
drag_prepare_cb (GtkDragSource *source,
double x,
double y,
CcInputRow *self)
{
self->drag_x = x;
self->drag_y = y;
return gdk_content_provider_new_typed (CC_TYPE_INPUT_ROW, self);
}
static void
drag_begin_cb (CcInputRow *self,
GdkDragContext *drag_context)
drag_begin_cb (GtkDragSource *source,
GdkDrag *drag,
CcInputRow *self)
{
GtkAllocation alloc;
gint x = 0, y = 0;
CcInputRow *drag_row;
GtkWidget *drag_icon;
gtk_widget_get_allocation (GTK_WIDGET (self), &alloc);
gdk_window_get_device_position (gtk_widget_get_window (GTK_WIDGET (self)),
gdk_drag_context_get_device (drag_context),
&x, &y, NULL);
self->drag_widget = GTK_LIST_BOX (gtk_list_box_new ());
gtk_widget_show (GTK_WIDGET (self->drag_widget));
gtk_widget_set_size_request (GTK_WIDGET (self->drag_widget), alloc.width, alloc.height);
CcInputRow *drag_row = cc_input_row_new (self->source);
gtk_widget_show (GTK_WIDGET (drag_row));
gtk_container_add (GTK_CONTAINER (self->drag_widget), GTK_WIDGET (drag_row));
drag_row = cc_input_row_new (self->source);
gtk_list_box_append (self->drag_widget, GTK_WIDGET (drag_row));
gtk_list_box_drag_highlight_row (self->drag_widget, GTK_LIST_BOX_ROW (drag_row));
gtk_drag_set_icon_widget (drag_context, GTK_WIDGET (self->drag_widget), x - alloc.x, y - alloc.y);
drag_icon = gtk_drag_icon_get_for_drag (drag);
gtk_drag_icon_set_child (GTK_DRAG_ICON (drag_icon), GTK_WIDGET (self->drag_widget));
gdk_drag_set_hotspot (drag, self->drag_x, self->drag_y);
}
static void
drag_end_cb (CcInputRow *self)
{
g_clear_pointer ((GtkWidget **) &self->drag_widget, gtk_widget_destroy);
}
static void
drag_data_get_cb (CcInputRow *self,
GdkDragContext *context,
GtkSelectionData *selection_data,
guint info,
guint time_)
{
gtk_selection_data_set (selection_data,
gdk_atom_intern_static_string ("GTK_LIST_BOX_ROW"),
32,
(const guchar *)&self,
sizeof (gpointer));
}
static void
drag_data_received_cb (CcInputRow *self,
GdkDragContext *context,
gint x,
gint y,
GtkSelectionData *selection_data,
guint info,
guint time_)
static gboolean
drop_cb (GtkDropTarget *drop_target,
const GValue *value,
gdouble x,
gdouble y,
CcInputRow *self)
{
CcInputRow *source;
source = *((CcInputRow **) gtk_selection_data_get_data (selection_data));
if (!G_VALUE_HOLDS (value, CC_TYPE_INPUT_ROW))
return FALSE;
if (source == self)
return;
source = g_value_get_object (value);
g_signal_emit (source,
signals[SIGNAL_MOVE_ROW],
0,
self);
return TRUE;
}
static void
@ -191,16 +185,11 @@ cc_input_row_class_init (CcInputRowClass *klass)
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/keyboard/cc-input-row.ui");
gtk_widget_class_bind_template_child (widget_class, CcInputRow, drag_handle);
gtk_widget_class_bind_template_child (widget_class, CcInputRow, name_label);
gtk_widget_class_bind_template_child (widget_class, CcInputRow, remove_button);
gtk_widget_class_bind_template_child (widget_class, CcInputRow, settings_button);
gtk_widget_class_bind_template_child (widget_class, CcInputRow, settings_separator);
gtk_widget_class_bind_template_callback (widget_class, drag_begin_cb);
gtk_widget_class_bind_template_callback (widget_class, drag_data_get_cb);
gtk_widget_class_bind_template_callback (widget_class, drag_data_received_cb);
gtk_widget_class_bind_template_callback (widget_class, drag_end_cb);
gtk_widget_class_bind_template_callback (widget_class, layout_button_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, move_down_button_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, move_up_button_clicked_cb);
@ -248,18 +237,23 @@ cc_input_row_class_init (CcInputRowClass *klass)
0);
}
static GtkTargetEntry entries[] =
{
{ "GTK_LIST_BOX_ROW", GTK_TARGET_SAME_APP, 0 }
};
void
cc_input_row_init (CcInputRow *self)
{
GtkDropTarget *drop_target;
gtk_widget_init_template (GTK_WIDGET (self));
gtk_drag_source_set (GTK_WIDGET (self->drag_handle), GDK_BUTTON1_MASK, entries, 1, GDK_ACTION_MOVE);
gtk_drag_dest_set (GTK_WIDGET (self), GTK_DEST_DEFAULT_ALL, entries, 1, GDK_ACTION_MOVE);
self->drag_source = gtk_drag_source_new ();
gtk_drag_source_set_actions (self->drag_source, GDK_ACTION_MOVE);
g_signal_connect (self->drag_source, "prepare", G_CALLBACK (drag_prepare_cb), self);
g_signal_connect (self->drag_source, "drag-begin", G_CALLBACK (drag_begin_cb), self);
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (self->drag_source));
drop_target = gtk_drop_target_new (CC_TYPE_INPUT_ROW, GDK_ACTION_MOVE);
gtk_drop_target_set_preload (drop_target, TRUE);
g_signal_connect (drop_target, "drop", G_CALLBACK (drop_cb), self);
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (drop_target));
}
static void
@ -305,8 +299,6 @@ void
cc_input_row_set_draggable (CcInputRow *self,
gboolean draggable)
{
if (draggable)
gtk_drag_source_set (GTK_WIDGET (self->drag_handle), GDK_BUTTON1_MASK, entries, 1, GDK_ACTION_MOVE);
else
gtk_drag_source_unset (GTK_WIDGET (self->drag_handle));
gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (self->drag_source),
draggable ? GTK_PHASE_BUBBLE : GTK_PHASE_NONE);
}

View file

@ -2,26 +2,15 @@
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="CcInputRow" parent="GtkListBoxRow">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="selectable">False</property>
<signal name="drag_data_received" handler="drag_data_received_cb" object="CcInputRow" swapped="yes"/>
<child>
<object class="GtkEventBox" id="drag_handle">
<property name="visible">True</property>
<signal name="drag_data_get" handler="drag_data_get_cb" object="CcInputRow" swapped="yes"/>
<signal name="drag_begin" handler="drag_begin_cb" object="CcInputRow" swapped="yes"/>
<signal name="drag_end" handler="drag_end_cb" object="CcInputRow" swapped="yes"/>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="height_request">50</property>
<property name="margin_start">12</property>
<property name="margin_end">6</property>
<property name="spacing">12</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon_name">list-drag-handle-symbolic</property>
<style>
<class name="drag-handle"/>
@ -30,7 +19,6 @@
</child>
<child>
<object class="GtkLabel" id="name_label">
<property name="visible">True</property>
<property name="margin_bottom">8</property>
<property name="margin_top">8</property>
<property name="ellipsize">end</property>
@ -40,7 +28,6 @@
</child>
<child>
<object class="GtkMenuButton">
<property name="visible">True</property>
<property name="margin_bottom">8</property>
<property name="margin_top">8</property>
<property name="valign">center</property>
@ -50,7 +37,6 @@
</style>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon_name">view-more-symbolic</property>
</object>
</child>
@ -58,50 +44,61 @@
</child>
</object>
</child>
</object>
</child>
</template>
<object class="GtkPopoverMenu" id="popover_menu">
<object class="GtkPopover" id="popover_menu">
<style>
<class name="menu" />
</style>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="margin">6</property>
<property name="margin-top">6</property>
<property name="margin-bottom">6</property>
<property name="margin-start">6</property>
<property name="margin-end">6</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkButton">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Move up</property>
<signal name="clicked" handler="move_up_button_clicked_cb" object="CcInputRow" swapped="yes"/>
<style>
<class name="flat"/>
</style>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Move up</property>
<property name="xalign">0.0</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkButton">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Move down</property>
<signal name="clicked" handler="move_down_button_clicked_cb" object="CcInputRow" swapped="yes"/>
<style>
<class name="flat"/>
</style>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Move down</property>
<property name="xalign">0.0</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSeparator">
<property name="visible">True</property>
<property name="orientation">horizontal</property>
</object>
</child>
<child>
<object class="GtkButton" id="settings_button">
<property name="visible">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Preferences</property>
<signal name="clicked" handler="settings_button_clicked_cb" object="CcInputRow" swapped="yes"/>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Preferences</property>
<property name="xalign">0.0</property>
</object>
</child>
<style>
<class name="flat"/>
</style>
@ -109,36 +106,40 @@
</child>
<child>
<object class="GtkSeparator" id="settings_separator">
<property name="visible">True</property>
<property name="orientation">horizontal</property>
</object>
</child>
<child>
<object class="GtkButton">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">View Keyboard Layout</property>
<signal name="clicked" handler="layout_button_clicked_cb" object="CcInputRow" swapped="yes"/>
<style>
<class name="flat"/>
</style>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">View Keyboard Layout</property>
<property name="xalign">0.0</property>
</object>
</child>
</object>
</child>
<child>
<object class="GtkSeparator">
<property name="visible">True</property>
<property name="orientation">horizontal</property>
</object>
</child>
<child>
<object class="GtkButton" id="remove_button">
<property name="visible">True</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Remove</property>
<signal name="clicked" handler="remove_button_clicked_cb" object="CcInputRow" swapped="yes"/>
<style>
<class name="flat"/>
</style>
<child>
<object class="GtkLabel">
<property name="label" translatable="yes">Remove</property>
<property name="xalign">0.0</property>
</object>
</child>
</object>
</child>
</object>

View file

@ -131,7 +131,11 @@ binding_from_string (const char *str,
return TRUE;
}
gtk_accelerator_parse_with_keycode (str, &combo->keyval, &keycodes, &combo->mask);
gtk_accelerator_parse_with_keycode (str,
gdk_display_get_default (),
&combo->keyval,
&keycodes,
&combo->mask);
combo->keycode = (keycodes ? keycodes[0] : 0);
@ -358,7 +362,6 @@ cc_keyboard_item_new (CcKeyboardItemType type)
static guint *
get_above_tab_keysyms (void)
{
GdkKeymap *keymap = gdk_keymap_get_for_display (gdk_display_get_default ());
guint keycode = 0x29 /* KEY_GRAVE */ + 8;
g_autofree guint *keyvals = NULL;
GArray *keysyms;
@ -366,7 +369,11 @@ get_above_tab_keysyms (void)
keysyms = g_array_new (TRUE, FALSE, sizeof (guint));
if (!gdk_keymap_get_entries_for_keycode (keymap, keycode, NULL, &keyvals, &n_entries))
if (!gdk_display_map_keycode (gdk_display_get_default (),
keycode,
NULL,
&keyvals,
&n_entries))
goto out;
for (i = 0; i < n_entries; i++)

View file

@ -24,10 +24,9 @@
#include "cc-keyboard-manager.h"
#include "keyboard-shortcuts.h"
#include "wm-common.h"
#ifdef GDK_WINDOWING_X11
#include <gdk/gdkx.h>
#include <gdk/x11/gdkx.h>
#endif
#define BINDINGS_SCHEMA "org.gnome.settings-daemon.plugins.media-keys"
@ -44,8 +43,6 @@ struct _CcKeyboardManager
GHashTable *kb_user_sections;
GSettings *binding_settings;
gpointer wm_changed_id;
};
G_DEFINE_TYPE (CcKeyboardManager, cc_keyboard_manager, G_TYPE_OBJECT)
@ -61,7 +58,7 @@ enum
static guint signals[LAST_SIGNAL] = { 0, };
/*
* Auxiliary methos
* Auxiliary methods
*/
static void
free_key_array (GPtrArray *keys)
@ -529,11 +526,6 @@ reload_sections (CcKeyboardManager *self)
(GDestroyNotify) free_key_array);
/* Load WM keybindings */
#ifdef GDK_WINDOWING_X11
if (GDK_IS_X11_DISPLAY (gdk_display_get_default ()))
wm_keybindings = wm_common_get_current_keybindings ();
else
#endif
wm_keybindings = g_strdupv (default_wm_keybindings);
loaded_files = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
@ -580,13 +572,6 @@ reload_sections (CcKeyboardManager *self)
/*
* Callbacks
*/
static void
on_window_manager_change (const char *wm_name,
CcKeyboardManager *self)
{
reload_sections (self);
}
static void
cc_keyboard_manager_finalize (GObject *object)
{
@ -597,8 +582,6 @@ cc_keyboard_manager_finalize (GObject *object)
g_clear_pointer (&self->kb_user_sections, g_hash_table_destroy);
g_clear_object (&self->binding_settings);
g_clear_pointer (&self->wm_changed_id, wm_common_unregister_window_manager_change);
G_OBJECT_CLASS (cc_keyboard_manager_parent_class)->finalize (object);
}
@ -683,12 +666,6 @@ cc_keyboard_manager_init (CcKeyboardManager *self)
G_TYPE_STRING,
G_TYPE_STRING,
G_TYPE_INT);
#ifdef GDK_WINDOWING_X11
if (GDK_IS_X11_DISPLAY (gdk_display_get_default ()))
self->wm_changed_id = wm_common_register_window_manager_change ((GFunc) on_window_manager_change,
self);
#endif
}

View file

@ -33,7 +33,6 @@
#include "cc-xkb-modifier-dialog.h"
#include "keyboard-shortcuts.h"
#include "list-box-helper.h"
struct _CcKeyboardPanel
{
@ -41,8 +40,8 @@ struct _CcKeyboardPanel
GtkListBox *input_source_list;
GtkRadioButton *per_window_source;
GtkRadioButton *same_source;
GtkCheckButton *per_window_source;
GtkCheckButton *same_source;
GSettings *keybindings_settings;
GSettings *input_source_settings;
@ -250,9 +249,9 @@ cc_keyboard_panel_init (CcKeyboardPanel *self)
gtk_widget_init_template (GTK_WIDGET (self));
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_data (provider, custom_css, -1, NULL);
gtk_css_provider_load_from_data (provider, custom_css, -1);
gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1);
g_object_unref (provider);

View file

@ -9,41 +9,32 @@
<property name="page_increment">200</property>
</object>
<template class="CcKeyboardPanel" parent="CcPanel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="expand">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<child>
<object class="GtkScrolledWindow">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="hscrollbar_policy">never</property>
<property name="propagate_natural_width">True</property>
<property name="propagate_natural_height">True</property>
<child>
<object class="HdyClamp">
<property name="visible">True</property>
<object class="AdwClamp">
<property name="margin_top">32</property>
<property name="margin_bottom">32</property>
<property name="margin_start">12</property>
<property name="margin_end">12</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">12</property>
<property name="hexpand">True</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Input Sources</property>
<attributes>
@ -53,8 +44,6 @@
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Includes keyboard layouts and input methods.</property>
<property name="wrap">True</property>
@ -68,19 +57,16 @@
</child>
<child>
<object class="CcInputListBox" id="input_list">
<property name="visible">True</property>
<property name="vexpand">False</property>
<property name="margin-bottom">20</property>
</object>
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Input Source Switching</property>
<attributes>
@ -90,8 +76,6 @@
</child>
<child>
<object class="GtkLabel" id="input_switch_description">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="wrap">True</property>
<property name="max-width-chars">50</property>
@ -104,29 +88,21 @@
</child>
<child>
<object class="GtkListBox" id="input_source_list">
<property name="visible">True</property>
<property name="margin-bottom">20</property>
<style>
<class name="content"/>
</style>
<child>
<object class="GtkListBoxRow">
<property name="visible">True</property>
<child>
<object class="GtkRadioButton" id="same_source">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="xalign">0</property>
<object class="GtkCheckButton" id="same_source">
<property name="active">True</property>
<property name="draw_indicator">True</property>
<style>
<class name="keyboard-panel-radio-button" />
</style>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="margin_left">6</property>
<property name="margin_start">6</property>
<property name="use_underline">True</property>
<property name="label" translatable="yes">Use the _same source for all windows</property>
</object>
@ -137,23 +113,16 @@
</child>
<child>
<object class="GtkListBoxRow">
<property name="visible">True</property>
<child>
<object class="GtkRadioButton" id="per_window_source">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="xalign">0</property>
<object class="GtkCheckButton" id="per_window_source">
<property name="active">True</property>
<property name="draw_indicator">True</property>
<property name="group">same_source</property>
<style>
<class name="keyboard-panel-radio-button" />
</style>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="margin_left">6</property>
<property name="margin_start">6</property>
<property name="use_underline">True</property>
<property name="label" translatable="yes">Switch input sources _individually for each window</property>
</object>
@ -166,13 +135,10 @@
</child>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Special Character Entry</property>
<attributes>
@ -182,8 +148,6 @@
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Methods for entering symbols and letter variants using the keyboard.</property>
<property name="wrap">True</property>
@ -197,8 +161,6 @@
</child>
<child>
<object class="GtkListBox" id="special_chars_list">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="selection-mode">none</property>
<property name="width-request">250</property>
<property name="margin-bottom">20</property>
@ -207,21 +169,16 @@
<class name="content"/>
</style>
<child>
<object class="HdyActionRow" id="alt_chars_row">
<property name="visible">True</property>
<property name="can_focus">True</property>
<object class="AdwActionRow" id="alt_chars_row">
<property name="title" translatable="yes">Alternate Characters Key</property>
<property name="activatable">True</property>
<child>
<object class="GtkLabel" id="value_alternate_chars">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="no">Right Alt</property>
</object>
</child>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon_name">go-next-symbolic</property>
<style>
<class name="dim-label"/>
@ -231,20 +188,15 @@
</object>
</child>
<child>
<object class="HdyActionRow" id="compose_row">
<property name="visible">True</property>
<property name="can_focus">True</property>
<object class="AdwActionRow" id="compose_row">
<property name="title" translatable="yes">Compose Key</property>
<property name="activatable">True</property>
<child>
<object class="GtkLabel" id="value_compose">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
</child>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon_name">go-next-symbolic</property>
<style>
<class name="dim-label"/>
@ -257,8 +209,6 @@
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Keyboard Shortcuts</property>
<attributes>
@ -268,8 +218,6 @@
</child>
<child>
<object class="GtkListBox" id="keyboard_shortcuts_listbox">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="selection-mode">none</property>
<property name="width-request">250</property>
<signal name="row-activated" handler="keyboard_shortcuts_activated" object="CcKeyboardPanel" swapped="no" />
@ -277,14 +225,11 @@
<class name="content"/>
</style>
<child>
<object class="HdyActionRow" id="common_shortcuts_row">
<property name="visible">True</property>
<property name="can_focus">True</property>
<object class="AdwActionRow" id="common_shortcuts_row">
<property name="title" translatable="yes">View and Customize Shortcuts</property>
<property name="activatable">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon_name">go-next-symbolic</property>
<style>
<class name="dim-label"/>

View file

@ -26,7 +26,7 @@
#include <config.h>
#include <glib/gi18n.h>
#include <handy.h>
#include <adwaita.h>
#include "cc-keyboard-shortcut-dialog.h"
#include "cc-keyboard-item.h"
@ -35,7 +35,6 @@
#include "cc-keyboard-shortcut-row.h"
#include "cc-list-row.h"
#include "cc-util.h"
#include "list-box-helper.h"
#include "keyboard-shortcuts.h"
#define SHORTCUT_DELIMITERS "+ "
@ -59,19 +58,20 @@ struct _CcKeyboardShortcutDialog
GtkDialog parent_instance;
GtkSizeGroup *accelerator_sizegroup;
GtkRevealer *back_revealer;
GtkWidget *back_button;
GtkListBoxRow *custom_shortcut_add_row;
guint custom_shortcut_count;
GtkWidget *empty_custom_shortcuts_placeholder;
GtkWidget *empty_search_placeholder;
GtkHeaderBar *headerbar;
GtkRevealer *reset_all_revealer;
GtkStack *header_stack;
GtkWidget *reset_all_button;
GtkWidget *section_box;
GtkSearchEntry *search_entry;
GtkListBox *section_listbox;
GtkListBoxRow *section_row;
GtkScrolledWindow *section_scrolled_window;
GtkWidget *shortcut_box;
GtkListBox *shortcut_listbox;
GtkScrolledWindow *shortcut_scrolled_window;
GtkStack *stack;
CcKeyboardManager *manager;
@ -141,19 +141,17 @@ add_section (CcKeyboardShortcutDialog *self,
{
GtkWidget *icon, *modified_label, *row;
icon = gtk_image_new_from_icon_name ("go-next-symbolic", GTK_ICON_SIZE_BUTTON);
gtk_style_context_add_class (gtk_widget_get_style_context (icon), "dim-label");
icon = gtk_image_new_from_icon_name ("go-next-symbolic");
gtk_widget_add_css_class (icon, "dim-label");
modified_label = gtk_label_new (NULL);
gtk_style_context_add_class (gtk_widget_get_style_context (modified_label), "dim-label");
gtk_widget_add_css_class (modified_label, "dim-label");
row = hdy_action_row_new ();
row = adw_action_row_new ();
gtk_list_box_row_set_activatable (GTK_LIST_BOX_ROW (row), TRUE);
hdy_preferences_row_set_title (HDY_PREFERENCES_ROW (row), _(section_title));
gtk_container_add (GTK_CONTAINER (row), modified_label);
gtk_container_add (GTK_CONTAINER (row), icon);
gtk_widget_show_all (GTK_WIDGET (row));
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (row), _(section_title));
//TODO gtk_container_add (GTK_CONTAINER (row), modified_label);
//TODO gtk_container_add (GTK_CONTAINER (row), icon);
g_object_set_data_full (G_OBJECT (row),
"data",
@ -161,7 +159,7 @@ add_section (CcKeyboardShortcutDialog *self,
(GDestroyNotify)section_row_data_free);
g_hash_table_insert (self->sections, g_strdup (section_id), row);
gtk_container_add (GTK_CONTAINER (self->section_listbox), GTK_WIDGET (row));
gtk_list_box_append (self->section_listbox, row);
return GTK_LIST_BOX_ROW (row);
}
@ -181,7 +179,7 @@ set_custom_shortcut_placeholder_visibility (CcKeyboardShortcutDialog *self)
if (is_custom_shortcuts && (self->custom_shortcut_count == 0))
gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->empty_custom_shortcuts_placeholder));
else
gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->shortcut_scrolled_window));
gtk_stack_set_visible_child (self->stack, self->shortcut_box);
}
}
@ -217,22 +215,25 @@ add_item (CcKeyboardShortcutDialog *self,
set_custom_shortcut_placeholder_visibility (self);
}
gtk_container_add (GTK_CONTAINER (self->shortcut_listbox), row);
gtk_list_box_append (self->shortcut_listbox, row);
}
static void
remove_item (CcKeyboardShortcutDialog *self,
CcKeyboardItem *item)
{
g_autoptr(GList) children;
GtkWidget *child;
children = gtk_container_get_children (GTK_CONTAINER (self->shortcut_listbox));
for (GList *l = children; l != NULL; l = l->next)
for (child = gtk_widget_get_first_child (GTK_WIDGET (self->shortcut_listbox));
child;
child = gtk_widget_get_next_sibling (child))
{
ShortcutRowData *row_data;
row_data = g_object_get_data (l->data, "data");
if (!GTK_IS_LIST_BOX_ROW (child))
continue;
row_data = g_object_get_data (G_OBJECT (child), "data");
if (row_data->item == item)
{
@ -242,7 +243,7 @@ remove_item (CcKeyboardShortcutDialog *self,
set_custom_shortcut_placeholder_visibility (self);
}
gtk_container_remove (GTK_CONTAINER (self->shortcut_listbox), l->data);
gtk_list_box_remove (self->shortcut_listbox, child);
break;
}
}
@ -251,32 +252,44 @@ remove_item (CcKeyboardShortcutDialog *self,
static void
update_modified_counts (CcKeyboardShortcutDialog *self)
{
g_autoptr(GList) sections = NULL, shortcuts = NULL;
SectionRowData *section_data;
ShortcutRowData *shortcut_data;
g_autofree gchar *modified_text = NULL;
GtkWidget *child;
sections = gtk_container_get_children (GTK_CONTAINER (self->section_listbox));
shortcuts = gtk_container_get_children (GTK_CONTAINER (self->shortcut_listbox));
for (GList *l = sections; l != NULL; l = l->next)
for (child = gtk_widget_get_first_child (GTK_WIDGET (self->section_listbox));
child;
child = gtk_widget_get_next_sibling (child))
{
section_data = g_object_get_data (G_OBJECT (l->data), "data");
if (!GTK_IS_LIST_BOX_ROW (child))
continue;
section_data = g_object_get_data (G_OBJECT (child), "data");
section_data->modified_count = 0;
}
for (GList *l = shortcuts; l != NULL; l = l->next)
for (child = gtk_widget_get_first_child (GTK_WIDGET (self->shortcut_listbox));
child;
child = gtk_widget_get_next_sibling (child))
{
if (l->data == self->custom_shortcut_add_row)
if (!GTK_IS_LIST_BOX_ROW (child))
continue;
shortcut_data = g_object_get_data (G_OBJECT (l->data), "data");
if (GTK_LIST_BOX_ROW (child) == self->custom_shortcut_add_row)
continue;
shortcut_data = g_object_get_data (G_OBJECT (child), "data");
if (!cc_keyboard_item_is_value_default (shortcut_data->item))
shortcut_data->section_data->modified_count++;
}
for (GList *l = sections; l != NULL; l = l->next)
for (child = gtk_widget_get_first_child (GTK_WIDGET (self->section_listbox));
child;
child = gtk_widget_get_next_sibling (child))
{
section_data = g_object_get_data (G_OBJECT (l->data), "data");
if (!GTK_IS_LIST_BOX_ROW (child))
continue;
section_data = g_object_get_data (G_OBJECT (child), "data");
if (section_data->modified_count > 0)
{
modified_text = g_strdup_printf (g_dngettext (GETTEXT_PACKAGE,
@ -302,11 +315,10 @@ show_section_list (CcKeyboardShortcutDialog *self)
gtk_stack_set_transition_type (self->stack, GTK_STACK_TRANSITION_TYPE_NONE);
self->section_row = NULL;
gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->section_scrolled_window));
gtk_header_bar_set_title (self->headerbar, _("Keyboard Shortcuts"));
gtk_entry_set_text(GTK_ENTRY (self->search_entry), "");
gtk_revealer_set_reveal_child (self->reset_all_revealer, TRUE);
gtk_revealer_set_reveal_child (self->back_revealer, FALSE);
gtk_stack_set_visible_child (self->stack, self->section_box);
gtk_window_set_title (GTK_WINDOW (self), _("Keyboard Shortcuts"));
gtk_editable_set_text (GTK_EDITABLE (self->search_entry), "");
gtk_stack_set_visible_child (self->header_stack, self->reset_all_button);
gtk_widget_set_visible (GTK_WIDGET (self->search_entry), TRUE);
update_modified_counts (self);
@ -333,12 +345,11 @@ show_shortcut_list (CcKeyboardShortcutDialog *self)
if (is_custom_shortcuts && (self->custom_shortcut_count == 0))
gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->empty_custom_shortcuts_placeholder));
else
gtk_stack_set_visible_child (self->stack, GTK_WIDGET (self->shortcut_scrolled_window));
gtk_stack_set_visible_child (self->stack, self->shortcut_box);
gtk_header_bar_set_title (self->headerbar, title);
gtk_window_set_title (GTK_WINDOW (self), title);
set_custom_shortcut_placeholder_visibility (self);
gtk_revealer_set_reveal_child (self->reset_all_revealer, FALSE);
gtk_revealer_set_reveal_child (self->back_revealer, TRUE);
gtk_stack_set_visible_child (self->header_stack, self->back_button);
gtk_widget_set_visible (GTK_WIDGET (self->search_entry), self->section_row == NULL);
}
@ -395,15 +406,12 @@ back_button_clicked_cb (CcKeyboardShortcutDialog *self)
}
static void
reset_all_shortcuts_cb (GtkWidget *widget,
gpointer user_data)
reset_shortcut (CcKeyboardShortcutDialog *self,
GtkWidget *row)
{
CcKeyboardShortcutDialog *self;
ShortcutRowData *data;
self = user_data;
data = g_object_get_data (G_OBJECT (widget), "data");
data = g_object_get_data (G_OBJECT (row), "data");
/* Don't reset custom shortcuts */
if (cc_keyboard_item_get_item_type (data->item) == CC_KEYBOARD_ITEM_TYPE_GSETTINGS_PATH)
@ -414,14 +422,38 @@ reset_all_shortcuts_cb (GtkWidget *widget,
cc_keyboard_manager_reset_shortcut (self->manager, data->item);
}
static void
on_reset_all_dialog_response_cb (GtkDialog *dialog,
gint response,
CcKeyboardShortcutDialog *self)
{
if (response == GTK_RESPONSE_ACCEPT)
{
GtkWidget *child;
for (child = gtk_widget_get_first_child (GTK_WIDGET (self->shortcut_listbox));
child;
child = gtk_widget_get_next_sibling (child))
{
if (!GTK_IS_LIST_BOX_ROW (child))
continue;
if (GTK_LIST_BOX_ROW (child) == self->custom_shortcut_add_row)
continue;
reset_shortcut (self, child);
}
}
gtk_window_destroy (GTK_WINDOW (dialog));
update_modified_counts (self);
}
static void
reset_all_clicked_cb (CcKeyboardShortcutDialog *self)
{
GtkWidget *dialog, *toplevel, *button;
guint response;
GtkWidget *dialog, *button;
toplevel = gtk_widget_get_toplevel (GTK_WIDGET (self));
dialog = gtk_message_dialog_new (GTK_WINDOW (toplevel),
dialog = gtk_message_dialog_new (GTK_WINDOW (self),
GTK_DIALOG_MODAL | GTK_DIALOG_USE_HEADER_BAR | GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_WARNING,
GTK_BUTTONS_NONE,
@ -440,44 +472,29 @@ reset_all_clicked_cb (CcKeyboardShortcutDialog *self)
/* Make the "Reset All" button destructive */
button = gtk_dialog_get_widget_for_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
gtk_style_context_add_class (gtk_widget_get_style_context (button), "destructive-action");
gtk_widget_add_css_class (button, "destructive-action");
/* Reset shortcuts if accepted */
response = gtk_dialog_run (GTK_DIALOG (dialog));
g_signal_connect (dialog, "response", G_CALLBACK (on_reset_all_dialog_response_cb), self);
if (response == GTK_RESPONSE_ACCEPT)
{
gtk_container_foreach (GTK_CONTAINER (self->shortcut_listbox),
reset_all_shortcuts_cb,
self);
}
gtk_widget_destroy (dialog);
update_modified_counts (self);
gtk_window_present (GTK_WINDOW (dialog));
}
static void
search_entry_cb (CcKeyboardShortcutDialog *self)
{
gboolean is_shortcut = is_matched_shortcut_present (self->shortcut_listbox, self);
const gchar *search_text = gtk_editable_get_text (GTK_EDITABLE (self->search_entry));
if (!is_shortcut)
gtk_stack_set_visible_child (self->stack, self->empty_search_placeholder);
else if (gtk_entry_get_text_length (GTK_ENTRY (self->search_entry)) == 0 && self->section_row == NULL)
else if (g_utf8_strlen (search_text, -1) == 0 && self->section_row == NULL)
show_section_list (self);
else if (gtk_stack_get_visible_child (self->stack) != GTK_WIDGET (self->shortcut_scrolled_window))
else if (gtk_stack_get_visible_child (self->stack) != self->shortcut_box)
show_shortcut_list (self);
else
gtk_list_box_invalidate_filter (self->shortcut_listbox);
}
static void
key_press_cb (CcKeyboardShortcutDialog *self, GdkEvent *event)
{
if (gtk_widget_get_visible (GTK_WIDGET (self->search_entry)))
gtk_search_entry_handle_event (self->search_entry, event);
}
static gboolean
strv_contains_prefix_or_match (gchar **strv,
const gchar *prefix)
@ -636,6 +653,7 @@ shortcut_filter_function (GtkListBoxRow *row,
g_autofree gchar *name = NULL;
g_auto(GStrv) terms = NULL;
gboolean is_custom_shortcuts = FALSE;
const gchar *search_text;
if (self->section_row != NULL)
{
@ -650,13 +668,14 @@ shortcut_filter_function (GtkListBoxRow *row,
if (row == self->custom_shortcut_add_row)
return is_custom_shortcuts;
if (gtk_entry_get_text_length (GTK_ENTRY (self->search_entry)) == 0)
search_text = gtk_editable_get_text (GTK_EDITABLE (self->search_entry));
if (g_utf8_strlen (search_text, -1) == 0)
return TRUE;
data = g_object_get_data (G_OBJECT (row), "data");
item = data->item;
name = cc_util_normalize_casefold_and_unaccent (cc_keyboard_item_get_description (item));
search = cc_util_normalize_casefold_and_unaccent (gtk_entry_get_text (GTK_ENTRY (self->search_entry)));
search = cc_util_normalize_casefold_and_unaccent (search_text);
terms = g_strsplit (search, " ", -1);
for (guint i = 0; terms && terms[i]; i++)
@ -718,17 +737,9 @@ shortcut_header_function (GtkListBoxRow *row,
g_autofree gchar *markup = NULL;
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
gtk_widget_show (box);
if (!before)
gtk_widget_set_margin_top (box, 6);
if (before)
{
separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
gtk_widget_show (separator);
gtk_container_add (GTK_CONTAINER (box), separator);
}
markup = g_strdup_printf ("<b>%s</b>", _(data->section_title));
label = g_object_new (GTK_TYPE_LABEL,
"label", markup,
@ -736,22 +747,13 @@ shortcut_header_function (GtkListBoxRow *row,
"xalign", 0.0,
"margin-start", 6,
NULL);
gtk_widget_show (label);
gtk_container_add (GTK_CONTAINER (box), label);
gtk_box_append (GTK_BOX (box), label);
separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
gtk_widget_show (separator);
gtk_container_add (GTK_CONTAINER (box), separator);
gtk_box_append (GTK_BOX (box), separator);
gtk_list_box_row_set_header (row, box);
}
else if (before)
{
GtkWidget *separator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
gtk_widget_show (separator);
gtk_list_box_row_set_header (row, separator);
}
else
{
gtk_list_box_row_set_header (row, NULL);
@ -776,7 +778,7 @@ cc_keyboard_shortcut_dialog_finalize (GObject *object)
g_clear_object (&self->manager);
g_clear_pointer (&self->sections, g_hash_table_destroy);
g_clear_pointer (&self->shortcut_editor, gtk_widget_destroy);
g_clear_pointer ((GtkWindow**)&self->shortcut_editor, gtk_window_destroy);
}
static void
@ -791,22 +793,22 @@ cc_keyboard_shortcut_dialog_class_init (CcKeyboardShortcutDialogClass *klass)
gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/control-center/keyboard/cc-keyboard-shortcut-dialog.ui");
gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutDialog, accelerator_sizegroup);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutDialog, back_revealer);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutDialog, back_button);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutDialog, custom_shortcut_add_row);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutDialog, empty_custom_shortcuts_placeholder);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutDialog, empty_search_placeholder);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutDialog, headerbar);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutDialog, reset_all_revealer);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutDialog, header_stack);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutDialog, reset_all_button);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutDialog, search_entry);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutDialog, section_listbox);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutDialog, section_scrolled_window);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutDialog, section_box);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutDialog, shortcut_listbox);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutDialog, shortcut_scrolled_window);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutDialog, shortcut_box);
gtk_widget_class_bind_template_child (widget_class, CcKeyboardShortcutDialog, stack);
gtk_widget_class_bind_template_callback (widget_class, add_custom_shortcut_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, back_button_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, key_press_cb);
gtk_widget_class_bind_template_callback (widget_class, reset_all_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, search_entry_cb);
gtk_widget_class_bind_template_callback (widget_class, section_row_activated);
@ -818,6 +820,8 @@ cc_keyboard_shortcut_dialog_init (CcKeyboardShortcutDialog *self)
{
gtk_widget_init_template (GTK_WIDGET (self));
gtk_search_entry_set_key_capture_widget (self->search_entry, GTK_WIDGET (self));
self->manager = cc_keyboard_manager_new ();
self->shortcut_editor = cc_keyboard_shortcut_editor_new (self->manager);
@ -840,7 +844,6 @@ cc_keyboard_shortcut_dialog_init (CcKeyboardShortcutDialog *self)
add_section(self, "custom", "Custom Shortcuts");
cc_keyboard_manager_load_shortcuts (self->manager);
gtk_list_box_set_header_func (self->section_listbox, cc_list_box_update_header_func, NULL, NULL);
gtk_list_box_set_sort_func (GTK_LIST_BOX (self->section_listbox),
section_sort_function,
self,

View file

@ -3,13 +3,59 @@
<!-- interface-requires gtk+ 3.0 -->
<template class="CcKeyboardShortcutDialog" parent="GtkDialog">
<property name="modal">True</property>
<signal name="key-press-event" handler="key_press_cb" object="CcKeyboardShortcutDialog" swapped="yes" />
<child internal-child="vbox">
<property name="default-width">600</property>
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar">
<property name="show_title_buttons">True</property>
<child>
<object class="GtkStack" id="header_stack">
<property name="hhomogeneous">False</property>
<property name="vhomogeneous">False</property>
<property name="transition-type">crossfade</property>
<child>
<object class="GtkButton" id="back_button">
<property name="halign">start</property>
<property name="valign">center</property>
<property name="icon_name">go-previous-symbolic</property>
<property name="use-underline">True</property>
<signal name="clicked" handler="back_button_clicked_cb" object="CcKeyboardShortcutDialog" swapped="yes" />
<style>
<class name="image-button"/>
</style>
<accessibility>
<property name="label">Back</property>
</accessibility>
</object>
</child>
<child>
<object class="GtkButton" id="reset_all_button">
<property name="label" translatable="yes">Reset All…</property>
<property name="tooltip-text" translatable="yes">Reset all shortcuts to their default keybindings</property>
<signal name="clicked" handler="reset_all_clicked_cb" object="CcKeyboardShortcutDialog" swapped="yes" />
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow">
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="hscrollbar_policy">never</property>
<property name="propagate_natural_width">True</property>
<property name="propagate_natural_height">True</property>
<property name="max_content_height">450</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkSearchEntry" id="search_entry">
<property name="visible">True</property>
<property name="margin-top">12</property>
<property name="width_chars">30</property>
<property name="halign">center</property>
@ -18,67 +64,51 @@
</child>
<child>
<object class="GtkStack" id="stack">
<property name="visible">True</property>
<child>
<object class="GtkScrolledWindow" id="section_scrolled_window">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="hscrollbar_policy">never</property>
<property name="propagate_natural_width">True</property>
<property name="propagate_natural_height">True</property>
<property name="max_content_height">450</property>
<property name="hhomogeneous">False</property>
<property name="vhomogeneous">False</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<object class="GtkBox" id="section_box">
<property name="orientation">vertical</property>
<property name="border_width">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<child>
<object class="GtkListBox" id="section_listbox">
<property name="visible">True</property>
<property name="selection-mode">none</property>
<property name="border_width">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<signal name="row-activated" handler="section_row_activated" object="CcKeyboardShortcutDialog" swapped="no" />
<style>
<class name="frame" />
<class name="content" />
</style>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkScrolledWindow" id="shortcut_scrolled_window">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="hscrollbar_policy">never</property>
<property name="propagate_natural_width">True</property>
<property name="propagate_natural_height">True</property>
<property name="max_content_height">450</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<object class="GtkBox" id="shortcut_box">
<property name="orientation">vertical</property>
<property name="border_width">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<property name="spacing">12</property>
<child>
<object class="GtkListBox" id="shortcut_listbox">
<property name="visible">True</property>
<property name="selection-mode">none</property>
<style>
<class name="frame" />
<class name="content" />
</style>
<signal name="row-activated" handler="shortcut_row_activated" object="CcKeyboardShortcutDialog" swapped="no" />
<child>
<object class="GtkListBoxRow" id="custom_shortcut_add_row">
<property name="visible">True</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="hexpand">True</property>
<property name="icon_name">list-add-symbolic</property>
<property name="height_request">48</property>
@ -90,13 +120,13 @@
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox" id="empty_custom_shortcuts_placeholder">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="border_width">18</property>
<property name="margin-top">18</property>
<property name="margin-bottom">18</property>
<property name="margin-start">18</property>
<property name="margin-end">18</property>
<property name="spacing">18</property>
<property name="valign">center</property>
<style>
@ -104,14 +134,12 @@
</style>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon-name">input-keyboard-symbolic</property>
<property name="pixel-size">128</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Add Custom Shortcuts</property>
<attributes>
<attribute name="weight" value="bold" />
@ -120,13 +148,11 @@
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="label" translatable="yes">Set up custom shortcuts for launching apps, running scripts, and more.</property>
</object>
</child>
<child>
<object class="GtkButton">
<property name="visible">True</property>
<property name="halign">center</property>
<property name="label" translatable="yes">Add Shortcut</property>
<style>
@ -139,19 +165,18 @@
</child>
<child>
<object class="GtkBox" id="empty_search_placeholder">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">center</property>
<property name="valign">center</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="border_width">18</property>
<property name="margin-top">18</property>
<property name="margin-bottom">18</property>
<property name="margin-start">18</property>
<property name="margin-end">18</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixel_size">80</property>
<property name="icon_name">edit-find-symbolic</property>
<style>
@ -161,8 +186,6 @@
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">No keyboard shortcut found</property>
<attributes>
<attribute name="weight" value="bold"/>
@ -172,8 +195,6 @@
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Try a different search</property>
<style>
<class name="dim-label"/>
@ -186,64 +207,9 @@
</child>
</object>
</child>
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar">
<property name="visible">True</property>
<property name="show_close_button">True</property>
<child>
<object class="GtkRevealer" id="back_revealer">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="transition-type">crossfade</property>
<child>
<object class="GtkButton" id="back">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="receives_default">False</property>
<property name="valign">center</property>
<property name="use-underline">True</property>
<signal name="clicked" handler="back_button_clicked_cb" object="CcKeyboardShortcutDialog" swapped="yes" />
<style>
<class name="image-button"/>
</style>
<child internal-child="accessible">
<object class="AtkObject" id="a11y-back">
<property name="accessible-name" translatable="yes">Back</property>
</object>
</child>
<child>
<object class="GtkImage" id="back_image">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">go-previous-symbolic</property>
<property name="icon_size">1</property>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkRevealer" id="reset_all_revealer">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="transition-type">crossfade</property>
<child>
<object class="GtkButton" id="reset_all_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Reset All…</property>
<property name="tooltip-text" translatable="yes">Reset all shortcuts to their default keybindings</property>
<signal name="clicked" handler="reset_all_clicked_cb" object="CcKeyboardShortcutDialog" swapped="yes" />
</object>
</child>
</object>
<packing>
<property name="pack_type">end</property>
</packing>
</child>
</object>
</child>
</template>
<object class="GtkSizeGroup" id="accelerator_sizegroup" />
</interface>

View file

@ -59,7 +59,7 @@ struct _CcKeyboardShortcutEditor
CcKeyboardItem *collision_item;
/* Custom shortcuts */
GdkDevice *grab_pointer;
gboolean system_shortcuts_inhibited;
guint grab_idle_id;
CcKeyCombo *custom_combo;
@ -156,8 +156,12 @@ apply_custom_item_fields (CcKeyboardShortcutEditor *self,
/* Set the keyboard shortcut name and command for custom entries */
if (cc_keyboard_item_get_item_type (item) == CC_KEYBOARD_ITEM_TYPE_GSETTINGS_PATH)
{
g_settings_set_string (cc_keyboard_item_get_settings (item), "name", gtk_entry_get_text (self->name_entry));
g_settings_set_string (cc_keyboard_item_get_settings (item), "command", gtk_entry_get_text (self->command_entry));
g_settings_set_string (cc_keyboard_item_get_settings (item),
"name",
gtk_editable_get_text (GTK_EDITABLE (self->name_entry)));
g_settings_set_string (cc_keyboard_item_get_settings (item),
"command",
gtk_editable_get_text (GTK_EDITABLE (self->command_entry)));
}
}
@ -167,8 +171,8 @@ clear_custom_entries (CcKeyboardShortcutEditor *self)
g_signal_handlers_block_by_func (self->command_entry, command_entry_changed_cb, self);
g_signal_handlers_block_by_func (self->name_entry, name_entry_changed_cb, self);
gtk_entry_set_text (self->name_entry, "");
gtk_entry_set_text (self->command_entry, "");
gtk_editable_set_text (GTK_EDITABLE (self->name_entry), "");
gtk_editable_set_text (GTK_EDITABLE (self->command_entry), "");
gtk_shortcut_label_set_accelerator (GTK_SHORTCUT_LABEL (self->custom_shortcut_accel_label), "");
gtk_label_set_label (self->new_shortcut_conflict_label, "");
@ -199,43 +203,40 @@ is_custom_shortcut (CcKeyboardShortcutEditor *self) {
}
static void
grab_seat (CcKeyboardShortcutEditor *self)
inhibit_system_shortcuts (CcKeyboardShortcutEditor *self)
{
GdkGrabStatus status;
GdkWindow *window;
GdkSeat *seat;
GtkNative *native;
GdkSurface *surface;
window = gtk_widget_get_window (GTK_WIDGET (self));
g_assert (window);
seat = gdk_display_get_default_seat (gdk_window_get_display (window));
status = gdk_seat_grab (seat,
window,
GDK_SEAT_CAPABILITY_KEYBOARD,
FALSE,
NULL,
NULL,
NULL,
NULL);
if (status != GDK_GRAB_SUCCESS) {
g_warning ("Grabbing keyboard failed");
if (self->system_shortcuts_inhibited)
return;
}
self->grab_pointer = gdk_seat_get_keyboard (seat);
if (!self->grab_pointer)
self->grab_pointer = gdk_seat_get_pointer (seat);
native = gtk_widget_get_native (GTK_WIDGET (self));
surface = gtk_native_get_surface (native);
if (GDK_IS_TOPLEVEL (surface))
{
gdk_toplevel_inhibit_system_shortcuts (GDK_TOPLEVEL (surface), NULL);
self->system_shortcuts_inhibited = TRUE;
}
}
static void
release_grab (CcKeyboardShortcutEditor *self)
uninhibit_system_shortcuts (CcKeyboardShortcutEditor *self)
{
if (self->grab_pointer)
GtkNative *native;
GdkSurface *surface;
if (!self->system_shortcuts_inhibited)
return;
native = gtk_widget_get_native (GTK_WIDGET (self));
surface = gtk_native_get_surface (native);
if (GDK_IS_TOPLEVEL (surface))
{
gdk_seat_ungrab (gdk_device_get_seat (self->grab_pointer));
self->grab_pointer = NULL;
gdk_toplevel_restore_system_shortcuts (GDK_TOPLEVEL (surface));
self->system_shortcuts_inhibited = FALSE;
}
}
@ -271,7 +272,7 @@ static void
set_header_mode (CcKeyboardShortcutEditor *self,
HeaderMode mode)
{
gtk_header_bar_set_show_close_button (self->headerbar, mode == HEADER_MODE_CUSTOM_EDIT);
gtk_header_bar_set_show_title_buttons (self->headerbar, mode == HEADER_MODE_CUSTOM_EDIT);
gtk_widget_set_visible (GTK_WIDGET (self->add_button), mode == HEADER_MODE_ADD);
gtk_widget_set_visible (GTK_WIDGET (self->cancel_button), mode != HEADER_MODE_NONE &&
@ -369,7 +370,7 @@ setup_custom_shortcut (CcKeyboardShortcutEditor *self)
self->edited = TRUE;
release_grab (self);
uninhibit_system_shortcuts (self);
/*
* Oops! Looks like the accelerator is already being used, so we
@ -454,7 +455,7 @@ cancel_button_clicked_cb (GtkWidget *button,
static void
change_custom_shortcut_button_clicked_cb (CcKeyboardShortcutEditor *self)
{
grab_seat (self);
inhibit_system_shortcuts (self);
set_shortcut_editor_page (self, PAGE_EDIT);
set_header_mode (self, HEADER_MODE_NONE);
}
@ -546,7 +547,7 @@ setup_keyboard_item (CcKeyboardShortcutEditor *self,
*self->custom_combo = combo;
/* Headerbar */
gtk_header_bar_set_title (self->headerbar,
gtk_window_set_title (GTK_WINDOW (self),
is_custom ? _("Set Custom Shortcut") : _("Set Shortcut"));
set_header_mode (self, is_custom ? HEADER_MODE_CUSTOM_EDIT : HEADER_MODE_NONE);
@ -582,11 +583,11 @@ setup_keyboard_item (CcKeyboardShortcutEditor *self,
g_signal_handlers_block_by_func (self->name_entry, name_entry_changed_cb, self);
/* Name entry */
gtk_entry_set_text (self->name_entry, cc_keyboard_item_get_description (item));
gtk_editable_set_text (GTK_EDITABLE (self->name_entry), cc_keyboard_item_get_description (item));
gtk_widget_set_sensitive (GTK_WIDGET (self->name_entry), cc_keyboard_item_get_desc_editable (item));
/* Command entry */
gtk_entry_set_text (self->command_entry, cc_keyboard_item_get_command (item));
gtk_editable_set_text (GTK_EDITABLE (self->command_entry), cc_keyboard_item_get_command (item));
gtk_widget_set_sensitive (GTK_WIDGET (self->command_entry), cc_keyboard_item_get_cmd_editable (item));
/* If there is no accelerator set for this custom shortcut, show the "Set Shortcut" button. */
@ -600,7 +601,7 @@ setup_keyboard_item (CcKeyboardShortcutEditor *self,
g_signal_handlers_unblock_by_func (self->command_entry, command_entry_changed_cb, self);
g_signal_handlers_unblock_by_func (self->name_entry, name_entry_changed_cb, self);
release_grab (self);
uninhibit_system_shortcuts (self);
}
/* Show the appropriate view */
@ -667,56 +668,60 @@ cc_keyboard_shortcut_editor_set_property (GObject *object,
}
static gboolean
cc_keyboard_shortcut_editor_key_press_event (GtkWidget *widget,
GdkEventKey *event)
on_key_pressed_cb (GtkEventControllerKey *key_controller,
guint keyval,
guint keycode,
GdkModifierType state,
CcKeyboardShortcutEditor *self)
{
CcKeyboardShortcutEditor *self;
GdkModifierType real_mask;
GdkEvent *event;
gboolean editing;
gboolean is_modifier;
guint keyval_lower;
self = CC_KEYBOARD_SHORTCUT_EDITOR (widget);
/* Being in the "change-shortcut" page is the only check we must
* perform to decide if we're editing a shortcut. */
editing = get_shortcut_editor_page (self) == PAGE_EDIT;
if (!editing)
return GTK_WIDGET_CLASS (cc_keyboard_shortcut_editor_parent_class)->key_press_event (widget, event);
return GDK_EVENT_PROPAGATE;
real_mask = event->state & gtk_accelerator_get_default_mod_mask ();
real_mask = state & gtk_accelerator_get_default_mod_mask ();
keyval_lower = gdk_keyval_to_lower (event->keyval);
keyval_lower = gdk_keyval_to_lower (keyval);
/* Normalise <Tab> */
if (keyval_lower == GDK_KEY_ISO_Left_Tab)
keyval_lower = GDK_KEY_Tab;
/* Put shift back if it changed the case of the key, not otherwise. */
if (keyval_lower != event->keyval)
if (keyval_lower != keyval)
real_mask |= GDK_SHIFT_MASK;
if (keyval_lower == GDK_KEY_Sys_Req &&
(real_mask & GDK_MOD1_MASK) != 0)
if (keyval_lower == GDK_KEY_Sys_Req && (real_mask & GDK_ALT_MASK) != 0)
{
/* HACK: we don't want to use SysRq as a keybinding (but we do
* want Alt+Print), so we avoid translation from Alt+Print to SysRq */
keyval_lower = GDK_KEY_Print;
}
event = gtk_event_controller_get_current_event (GTK_EVENT_CONTROLLER (key_controller));
is_modifier = gdk_key_event_is_modifier (event);
/* A single Escape press cancels the editing */
if (!event->is_modifier && real_mask == 0 && keyval_lower == GDK_KEY_Escape)
if (!is_modifier && real_mask == 0 && keyval_lower == GDK_KEY_Escape)
{
self->edited = FALSE;
release_grab (self);
uninhibit_system_shortcuts (self);
cancel_editing (self);
return GDK_EVENT_STOP;
}
/* Backspace disables the current shortcut */
if (!event->is_modifier && real_mask == 0 && keyval_lower == GDK_KEY_BackSpace)
if (!is_modifier && real_mask == 0 && keyval_lower == GDK_KEY_BackSpace)
{
self->edited = TRUE;
self->custom_is_modifier = FALSE;
@ -725,7 +730,7 @@ cc_keyboard_shortcut_editor_key_press_event (GtkWidget *widget,
gtk_shortcut_label_set_accelerator (GTK_SHORTCUT_LABEL (self->custom_shortcut_accel_label), "");
gtk_shortcut_label_set_accelerator (GTK_SHORTCUT_LABEL (self->shortcut_accel_label), "");
release_grab (self);
uninhibit_system_shortcuts (self);
self->edited = FALSE;
@ -734,8 +739,8 @@ cc_keyboard_shortcut_editor_key_press_event (GtkWidget *widget,
return GDK_EVENT_STOP;
}
self->custom_is_modifier = event->is_modifier;
self->custom_combo->keycode = event->hardware_keycode;
self->custom_is_modifier = is_modifier;
self->custom_combo->keycode = keycode;
self->custom_combo->keyval = keyval_lower;
self->custom_combo->mask = real_mask;
@ -777,7 +782,7 @@ grab_idle (gpointer data)
CcKeyboardShortcutEditor *self = data;
if (self->item && cc_keyboard_item_get_item_type (self->item) != CC_KEYBOARD_ITEM_TYPE_GSETTINGS_PATH)
grab_seat (self);
inhibit_system_shortcuts (self);
self->grab_idle_id = 0;
@ -805,7 +810,7 @@ cc_keyboard_shortcut_editor_unrealize (GtkWidget *widget)
self->grab_idle_id = 0;
}
release_grab (self);
uninhibit_system_shortcuts (self);
GTK_WIDGET_CLASS (cc_keyboard_shortcut_editor_parent_class)->unrealize (widget);
}
@ -823,7 +828,6 @@ cc_keyboard_shortcut_editor_class_init (CcKeyboardShortcutEditorClass *klass)
widget_class->show = cc_keyboard_shortcut_editor_show;
widget_class->unrealize = cc_keyboard_shortcut_editor_unrealize;
widget_class->key_press_event = cc_keyboard_shortcut_editor_key_press_event;
dialog_class->close = cc_keyboard_shortcut_editor_close;
dialog_class->response = cc_keyboard_shortcut_editor_response;
@ -881,6 +885,7 @@ cc_keyboard_shortcut_editor_class_init (CcKeyboardShortcutEditorClass *klass)
gtk_widget_class_bind_template_callback (widget_class, change_custom_shortcut_button_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, command_entry_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, name_entry_changed_cb);
gtk_widget_class_bind_template_callback (widget_class, on_key_pressed_cb);
gtk_widget_class_bind_template_callback (widget_class, remove_button_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, replace_button_clicked_cb);
gtk_widget_class_bind_template_callback (widget_class, reset_custom_clicked_cb);
@ -984,7 +989,7 @@ cc_keyboard_shortcut_editor_set_mode (CcKeyboardShortcutEditor *self,
set_header_mode (self, HEADER_MODE_ADD);
set_shortcut_editor_page (self, PAGE_CUSTOM);
gtk_header_bar_set_title (self->headerbar, _("Add Custom Shortcut"));
gtk_window_set_title (GTK_WINDOW (self), _("Add Custom Shortcut"));
gtk_widget_set_sensitive (GTK_WIDGET (self->command_entry), TRUE);
gtk_widget_set_sensitive (GTK_WIDGET (self->name_entry), TRUE);

View file

@ -2,60 +2,98 @@
<interface>
<requires lib="gtk+" version="3.20"/>
<template class="CcKeyboardShortcutEditor" parent="GtkDialog">
<property name="can_focus">False</property>
<property name="resizable">False</property>
<property name="modal">True</property>
<property name="width_request">400</property>
<property name="height_request">300</property>
<property name="window_position">center</property>
<property name="type_hint">dialog</property>
<property name="hide-on-close">True</property>
<signal name="close" handler="cancel_button_clicked_cb" object="CcKeyboardShortcutEditor" swapped="no" />
<signal name="delete-event" handler="gtk_widget_hide_on_delete" object="CcKeyboardShortcutEditor" swapped="yes"/>
<child internal-child="vbox">
<child>
<object class="GtkEventControllerKey">
<property name="propagation-phase">capture</property>
<signal name="key-pressed" handler="on_key_pressed_cb" object="CcKeyboardShortcutEditor" swapped="no" />
</object>
</child>
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar">
<property name="show_title_buttons">True</property>
<child>
<object class="GtkButton" id="cancel_button">
<property name="label" translatable="yes">Cancel</property>
<signal name="clicked" handler="cancel_button_clicked_cb" object="CcKeyboardShortcutEditor" swapped="no" />
</object>
</child>
<child>
<object class="GtkButton" id="remove_button">
<property name="label" translatable="yes">Remove</property>
<property name="valign">end</property>
<signal name="clicked" handler="remove_button_clicked_cb" object="CcKeyboardShortcutEditor" swapped="yes" />
<style>
<class name="destructive-action" />
</style>
</object>
</child>
<child type="end">
<object class="GtkButton" id="add_button">
<property name="label" translatable="yes">Add</property>
<property name="sensitive">False</property>
<signal name="clicked" handler="add_button_clicked_cb" object="CcKeyboardShortcutEditor" swapped="yes" />
</object>
</child>
<child type="end">
<object class="GtkButton" id="replace_button">
<property name="label" translatable="yes">Replace</property>
<signal name="clicked" handler="replace_button_clicked_cb" object="CcKeyboardShortcutEditor" swapped="yes" />
</object>
</child>
<child type="end">
<object class="GtkButton" id="set_button">
<property name="label" translatable="yes">Set</property>
<signal name="clicked" handler="set_button_clicked_cb" object="CcKeyboardShortcutEditor" swapped="yes" />
</object>
</child>
</object>
</child>
<child>
<object class="GtkBox">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">18</property>
<property name="border_width">12</property>
<property name="margin-top">12</property>
<property name="margin-bottom">12</property>
<property name="margin-start">12</property>
<property name="margin-end">12</property>
<child>
<object class="GtkLabel" id="top_info_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="wrap">True</property>
<property name="wrap_mode">word-char</property>
<property name="width_chars">15</property>
<property name="max_width_chars">20</property>
</object>
<packing>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkStack" id="stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<child>
<object class="GtkBox" id="edit_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">18</property>
<property name="expand">True</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="halign">center</property>
<property name="valign">center</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="resource">/org/gnome/control-center/keyboard/enter-keyboard-shortcut.svg</property>
<object class="GtkPicture">
<property name="halign">center</property>
<property name="valign">center</property>
<property name="can-shrink">False</property>
<property name="file">resource:///org/gnome/control-center/keyboard/enter-keyboard-shortcut.svg</property>
</object>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="wrap">True</property>
<property name="label" translatable="yes">Press Esc to cancel or Backspace to disable the keyboard shortcut.</property>
<style>
@ -67,49 +105,33 @@
</child>
<child>
<object class="GtkBox" id="standard_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="orientation">vertical</property>
<property name="spacing">18</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">18</property>
<object class="GtkCenterBox">
<child type="center">
<object class="GtkShortcutLabel" id="shortcut_accel_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin-start">18</property>
<property name="margin-end">18</property>
<property name="halign">center</property>
<property name="disabled-text" translatable="yes">Disabled</property>
</object>
</child>
<child>
<child type="end">
<object class="GtkButton" id="reset_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="relief">none</property>
<property name="halign">end</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon-name">edit-clear-symbolic</property>
</object>
</child>
<property name="halign">end</property>
<signal name="clicked" handler="reset_item_clicked_cb" object="CcKeyboardShortcutEditor" swapped="yes" />
<style>
<class name="flat" />
</style>
</object>
<packing>
<property name="pack_type">end</property>
</packing>
</child>
</object>
</child>
<child>
<object class="GtkLabel" id="shortcut_conflict_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="wrap">True</property>
<property name="wrap_mode">word-char</property>
@ -122,220 +144,119 @@
</child>
<child>
<object class="GtkGrid" id="custom_grid">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="row_spacing">12</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Name</property>
<property name="xalign">1</property>
<layout>
<property name="column">0</property>
<property name="row">0</property>
</layout>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Command</property>
<property name="xalign">1</property>
<layout>
<property name="column">0</property>
<property name="row">1</property>
</layout>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Shortcut</property>
<property name="xalign">1</property>
<layout>
<property name="column">0</property>
<property name="row">2</property>
</layout>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="new_shortcut_conflict_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
<property name="wrap">True</property>
<property name="wrap_mode">word-char</property>
<property name="width_chars">15</property>
<property name="max_width_chars">20</property>
<property name="xalign">0</property>
<layout>
<property name="column">0</property>
<property name="row">3</property>
<property name="column-span">2</property>
</layout>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="name_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<signal name="notify::text" handler="name_entry_changed_cb" object="CcKeyboardShortcutEditor" swapped="yes" />
<layout>
<property name="column">1</property>
<property name="row">0</property>
<property name="column-span">2</property>
</layout>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkEntry" id="command_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<signal name="notify::text" handler="command_entry_changed_cb" object="CcKeyboardShortcutEditor" swapped="yes" />
<layout>
<property name="column">1</property>
<property name="row">1</property>
<property name="column-span">2</property>
</layout>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="reset_custom_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="relief">none</property>
<property name="halign">end</property>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon-name">edit-clear-symbolic</property>
</object>
</child>
<signal name="clicked" handler="reset_custom_clicked_cb" object="CcKeyboardShortcutEditor" swapped="yes" />
<layout>
<property name="column">2</property>
<property name="row">2</property>
</layout>
<style>
<class name="flat" />
</style>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkStack" id="custom_shortcut_stack">
<property name="visible">True</property>
<property name="can_focus">False</property>
<layout>
<property name="column">1</property>
<property name="row">2</property>
</layout>
<child>
<object class="GtkButton" id="change_custom_shortcut_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="label" translatable="yes">Set Shortcut…</property>
<signal name="clicked" handler="change_custom_shortcut_button_clicked_cb" object="CcKeyboardShortcutEditor" swapped="yes" />
</object>
</child>
<child>
<object class="GtkShortcutLabel" id="custom_shortcut_accel_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="disabled-text" translatable="yes">None</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<child type="titlebar">
<object class="GtkHeaderBar" id="headerbar">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="show_close_button">True</property>
<child>
<object class="GtkButton" id="cancel_button">
<property name="label" translatable="yes">Cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="cancel_button_clicked_cb" object="CcKeyboardShortcutEditor" swapped="no" />
</object>
</child>
<child>
<object class="GtkButton" id="remove_button">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Remove</property>
<property name="valign">end</property>
<signal name="clicked" handler="remove_button_clicked_cb" object="CcKeyboardShortcutEditor" swapped="yes" />
<style>
<class name="destructive-action" />
</style>
</object>
</child>
<child>
<object class="GtkButton" id="add_button">
<property name="label" translatable="yes">Add</property>
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="add_button_clicked_cb" object="CcKeyboardShortcutEditor" swapped="yes" />
</object>
<packing>
<property name="pack_type">end</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="replace_button">
<property name="label" translatable="yes">Replace</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="replace_button_clicked_cb" object="CcKeyboardShortcutEditor" swapped="yes" />
</object>
<packing>
<property name="pack_type">end</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="set_button">
<property name="label" translatable="yes">Set</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
<signal name="clicked" handler="set_button_clicked_cb" object="CcKeyboardShortcutEditor" swapped="yes" />
</object>
<packing>
<property name="pack_type">end</property>
<property name="position">3</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="cancel">cancel_button</action-widget>
<action-widget response="accept">replace_button</action-widget>

View file

@ -24,7 +24,7 @@
struct _CcKeyboardShortcutRow
{
HdyActionRow parent_instance;
AdwActionRow parent_instance;
GtkLabel *accelerator_label;
GtkButton *reset_button;
@ -35,7 +35,7 @@ struct _CcKeyboardShortcutRow
CcKeyboardShortcutEditor *shortcut_editor;
};
G_DEFINE_TYPE (CcKeyboardShortcutRow, cc_keyboard_shortcut_row, HDY_TYPE_ACTION_ROW)
G_DEFINE_TYPE (CcKeyboardShortcutRow, cc_keyboard_shortcut_row, ADW_TYPE_ACTION_ROW)
static void
reset_shortcut_cb (CcKeyboardShortcutRow *self)
@ -115,7 +115,7 @@ cc_keyboard_shortcut_row_new (CcKeyboardItem *item,
self->manager = manager;
self->shortcut_editor = shortcut_editor;
hdy_preferences_row_set_title (HDY_PREFERENCES_ROW (self), cc_keyboard_item_get_description (item));
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (self), cc_keyboard_item_get_description (item));
g_object_bind_property_full (item,
"key-combos",

View file

@ -20,8 +20,7 @@
#pragma once
#include <gtk/gtk.h>
#include <handy.h>
#include <adwaita.h>
#include "cc-keyboard-item.h"
#include "cc-keyboard-manager.h"
#include "cc-keyboard-shortcut-editor.h"
@ -29,10 +28,11 @@
G_BEGIN_DECLS
#define CC_TYPE_KEYBOARD_SHORTCUT_ROW (cc_keyboard_shortcut_row_get_type())
G_DECLARE_FINAL_TYPE (CcKeyboardShortcutRow, cc_keyboard_shortcut_row, CC, KEYBOARD_SHORTCUT_ROW, AdwActionRow)
G_DECLARE_FINAL_TYPE (CcKeyboardShortcutRow, cc_keyboard_shortcut_row, CC, KEYBOARD_SHORTCUT_ROW, HdyActionRow)
CcKeyboardShortcutRow *cc_keyboard_shortcut_row_new (CcKeyboardItem*, CcKeyboardManager*, CcKeyboardShortcutEditor*, GtkSizeGroup*);
CcKeyboardShortcutRow *cc_keyboard_shortcut_row_new (CcKeyboardItem *item,
CcKeyboardManager *manager,
CcKeyboardShortcutEditor *editor,
GtkSizeGroup *size_group);
G_END_DECLS

View file

@ -1,13 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<template class="CcKeyboardShortcutRow" parent="HdyActionRow">
<property name="visible">True</property>
<template class="CcKeyboardShortcutRow" parent="AdwActionRow">
<property name="selectable">False</property>
<property name="activatable">True</property>
<child>
<object class="GtkLabel" id="accelerator_label">
<property name="visible">True</property>
<property name="xalign">1.0</property>
<property name="use-markup">True</property>
<style>
@ -17,20 +15,13 @@
</child>
<child>
<object class="GtkRevealer" id = "reset_revealer">
<property name="visible">True</property>
<property name="transition-type">slide-right</property>
<child>
<object class="GtkButton" id="reset_button">
<property name="visible">True</property>
<property name="valign">center</property>
<property name="relief">none</property>
<property name="icon-name">edit-clear-symbolic</property>
<property name="tooltip-text" translatable="yes">Reset the shortcut to its default value</property>
<signal name="clicked" handler="reset_shortcut_cb" swapped="true"/>
<child>
<object class="GtkImage">
<property name="visible">True</property>
<property name="icon-name">edit-clear-symbolic</property>
<property name="icon-size">1</property>
<style>
<class name="flat" />
<class name="circular" />
@ -40,7 +31,5 @@
</child>
</object>
</child>
</object>
</child>
</template>
</interface>

View file

@ -19,11 +19,9 @@
*/
#include <glib/gi18n.h>
#define HANDY_USE_UNSTABLE_API
#include <handy.h>
#include <adwaita.h>
#include "cc-xkb-modifier-dialog.h"
#include "list-box-helper.h"
struct _CcXkbModifierDialog
{
@ -33,7 +31,7 @@ struct _CcXkbModifierDialog
GtkSwitch *enabled_switch;
GtkListBox *listbox;
GtkListBox *switch_listbox;
HdyActionRow *switch_row;
AdwActionRow *switch_row;
GSettings *input_source_settings;
const CcXkbModifier *modifier;
@ -44,7 +42,7 @@ G_DEFINE_TYPE (CcXkbModifierDialog, cc_xkb_modifier_dialog, GTK_TYPE_DIALOG)
static const gchar *custom_css =
".xkb-option-button {"
" padding: 12px"
" padding: 12px;"
"}";
static const CcXkbOption*
@ -62,7 +60,7 @@ get_xkb_option_from_name (const CcXkbModifier *modifier, const gchar* name)
return NULL;
}
static GtkRadioButton *
static GtkCheckButton *
get_radio_button_from_xkb_option_name (CcXkbModifierDialog *self,
const gchar *name)
{
@ -83,7 +81,7 @@ static void
update_active_radio (CcXkbModifierDialog *self)
{
g_auto(GStrv) options = NULL;
GtkRadioButton *rightalt_radio;
GtkCheckButton *rightalt_radio;
const CcXkbOption *default_option;
guint i;
@ -91,7 +89,7 @@ update_active_radio (CcXkbModifierDialog *self)
for (i = 0; options != NULL && options[i] != NULL; i++)
{
GtkRadioButton *radio;
GtkCheckButton *radio;
if (!g_str_has_prefix (options[i], self->modifier->prefix))
continue;
@ -101,7 +99,7 @@ update_active_radio (CcXkbModifierDialog *self)
if (!radio)
continue;
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio), TRUE);
gtk_check_button_set_active (GTK_CHECK_BUTTON (radio), TRUE);
gtk_switch_set_active (self->enabled_switch, TRUE);
return;
}
@ -110,7 +108,7 @@ update_active_radio (CcXkbModifierDialog *self)
{
default_option = get_xkb_option_from_name(self->modifier, self->modifier->default_option);
rightalt_radio = get_radio_button_from_xkb_option_name (self, default_option->xkb_option);
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (rightalt_radio), TRUE);
gtk_check_button_set_active (GTK_CHECK_BUTTON (rightalt_radio), TRUE);
gtk_switch_set_active (self->enabled_switch, TRUE);
}
else
@ -161,11 +159,11 @@ set_xkb_option (CcXkbModifierDialog *self,
static void
on_active_radio_changed_cb (CcXkbModifierDialog *self,
GtkRadioButton *radio)
GtkCheckButton *radio)
{
gchar *xkb_option;
if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio)))
if (!gtk_check_button_get_active (GTK_CHECK_BUTTON (radio)))
return;
if (!gtk_switch_get_state (self->enabled_switch))
@ -197,7 +195,7 @@ enable_switch_changed_cb (GtkSwitch *widget,
{
for (l = self->radio_group; l != NULL; l = l->next)
{
if (gtk_toggle_button_get_active (l->data))
if (gtk_check_button_get_active (l->data))
{
xkb_option = (gchar *)g_object_get_data (l->data, "xkb-option");
set_xkb_option (self, xkb_option);
@ -245,7 +243,8 @@ cc_xkb_modifier_dialog_class_init (CcXkbModifierDialogClass *klass)
static void
add_radio_buttons (CcXkbModifierDialog *self)
{
GtkWidget *row, *radio_button, *label, *last_button = NULL;
g_autoptr (GSList) group = NULL;
GtkWidget *row, *radio_button, *last_button = NULL;
CcXkbOption *options = self->modifier->options;
int i;
@ -255,32 +254,24 @@ add_radio_buttons (CcXkbModifierDialog *self)
"visible", TRUE,
"selectable", FALSE,
NULL);
gtk_container_add (GTK_CONTAINER (self->listbox), row);
gtk_list_box_append (self->listbox, row);
radio_button = g_object_new (GTK_TYPE_RADIO_BUTTON,
"visible", TRUE,
"can_focus", TRUE,
"receives_default", FALSE,
"draw_indicator", TRUE,
NULL);
label = g_object_new (GTK_TYPE_LABEL,
"visible", TRUE,
"margin_left", 6,
radio_button = g_object_new (GTK_TYPE_CHECK_BUTTON,
"label", g_dpgettext2 (NULL, "keyboard key", options[i].label),
"group", last_button,
NULL);
gtk_container_add (GTK_CONTAINER (radio_button), label);
gtk_style_context_add_class (gtk_widget_get_style_context (radio_button), "xkb-option-button");
gtk_radio_button_join_group (GTK_RADIO_BUTTON (radio_button), GTK_RADIO_BUTTON (last_button));
gtk_widget_add_css_class (radio_button, "xkb-option-button");
g_object_set_data (G_OBJECT (radio_button), "xkb-option", options[i].xkb_option);
g_signal_connect_object (radio_button, "toggled", (GCallback)on_active_radio_changed_cb, self, G_CONNECT_SWAPPED);
gtk_container_add (GTK_CONTAINER (row), radio_button);
gtk_list_box_row_set_child (GTK_LIST_BOX_ROW (row), radio_button);
last_button = radio_button;
group = g_slist_prepend (group, radio_button);
}
self->radio_group = NULL;
if (last_button != NULL)
self->radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (last_button));
self->radio_group = g_steal_pointer (&group);
}
static void
@ -291,9 +282,9 @@ cc_xkb_modifier_dialog_init (CcXkbModifierDialog *self)
gtk_widget_init_template (GTK_WIDGET (self));
provider = gtk_css_provider_new ();
gtk_css_provider_load_from_data (provider, custom_css, -1, NULL);
gtk_css_provider_load_from_data (provider, custom_css, -1);
gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
gtk_style_context_add_provider_for_display (gdk_display_get_default (),
GTK_STYLE_PROVIDER (provider),
GTK_STYLE_PROVIDER_PRIORITY_APPLICATION + 1);
@ -319,7 +310,7 @@ cc_xkb_modifier_dialog_new (GSettings *input_settings,
self->modifier = modifier;
gtk_window_set_title (GTK_WINDOW (self), gettext (modifier->title));
hdy_preferences_row_set_title (HDY_PREFERENCES_ROW (self->switch_row), gettext (modifier->title));
adw_preferences_row_set_title (ADW_PREFERENCES_ROW (self->switch_row), gettext (modifier->title));
gtk_label_set_markup (self->description_label, gettext (modifier->description));
gtk_widget_set_visible (GTK_WIDGET (self->switch_listbox), modifier->default_option == NULL);
add_radio_buttons (self);

View file

@ -2,27 +2,23 @@
<interface>
<template class="CcXkbModifierDialog" parent="GtkDialog">
<property name="modal">True</property>
<property name="can_focus">False</property>
<property name="resizable">False</property>
<property name="default_width">500</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<child>
<object class="GtkBox">
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin">18</property>
<property name="margin-top">18</property>
<property name="margin-bottom">18</property>
<property name="margin-start">18</property>
<property name="margin-end">18</property>
<property name="spacing">18</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkLabel" id="description_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="margin_top">6</property>
<property name="wrap">True</property>
<property name="width_chars">40</property>
@ -33,19 +29,15 @@
<child>
<object class="GtkListBox" id="switch_listbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<style>
<class name="content"/>
</style>
<child>
<object class="HdyActionRow" id="switch_row">
<property name="visible">True</property>
<object class="AdwActionRow" id="switch_row">
<property name="activatable">False</property>
<property name="selectable">False</property>
<child>
<object class="GtkSwitch" id="enabled_switch">
<property name="visible">True</property>
<property name="valign">center</property>
<signal name="state-set" handler="enable_switch_changed_cb" object="CcXkbModifierDialog" swapped="no"/>
</object>
@ -57,8 +49,6 @@
<child>
<object class="GtkListBox" id="listbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<style>
<class name="content"/>
</style>
@ -73,8 +63,7 @@
<child internal-child="headerbar">
<object class="GtkHeaderBar">
<property name="can_focus">False</property>
<property name="show_close_button">True</property>
<property name="show-title-buttons">True</property>
</object>
</child>
</template>

View file

@ -63,7 +63,6 @@ sources = files(
'cc-keyboard-item.c',
'cc-keyboard-manager.c',
'cc-keyboard-shortcut-editor.c',
'wm-common.c',
'keyboard-shortcuts.c',
'cc-ibus-utils.c',
'cc-input-chooser.c',

View file

@ -1,261 +0,0 @@
#include <X11/Xatom.h>
#include <gdk/gdkx.h>
#include <gdk/gdk.h>
#include <string.h>
#include <glib.h>
#include <glib-object.h>
#include "wm-common.h"
typedef struct _WMCallbackData
{
GFunc func;
gpointer data;
} WMCallbackData;
/* Our WM Window */
static Window wm_window = None;
/*
* These push/pop implementations are based on the GDK versions, except that they
* use only non-deprecated API.
*/
static GPtrArray*
push_error_traps (void)
{
GdkDisplayManager *manager;
g_autoptr(GPtrArray) trapped_displays = NULL;
g_autoptr(GSList) displays = NULL;
GSList *l;
manager = gdk_display_manager_get ();
displays = gdk_display_manager_list_displays (manager);
trapped_displays = g_ptr_array_new ();
for (l = displays; l != NULL; l = l->next)
{
GdkDisplay *display = l->data;
#ifdef GDK_WINDOWING_X11
if (GDK_IS_X11_DISPLAY (display))
{
gdk_x11_display_error_trap_push (display);
g_ptr_array_add (trapped_displays, display);
}
#endif
}
return g_steal_pointer (&trapped_displays);
}
static gint
pop_error_traps (GPtrArray *displays)
{
guint i;
gint result;
result = 0;
for (i = 0; displays && i < displays->len; i++)
{
GdkDisplay *display;
gint code = 0;
display = g_ptr_array_index (displays, i);
#ifdef GDK_WINDOWING_X11
code = gdk_x11_display_error_trap_pop (display);
#endif
if (code != 0)
result = code;
}
return result;
}
static char *
wm_common_get_window_manager_property (Atom atom)
{
g_autoptr(GPtrArray) trapped_displays = NULL;
Atom utf8_string, type;
int result;
char *retval;
int format;
gulong nitems;
gulong bytes_after;
gchar *val;
if (wm_window == None)
return NULL;
utf8_string = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "UTF8_STRING", False);
trapped_displays = push_error_traps ();
val = NULL;
result = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()),
wm_window,
atom,
0, G_MAXLONG,
False, utf8_string,
&type, &format, &nitems,
&bytes_after, (guchar **) &val);
if (pop_error_traps (trapped_displays) ||
result != Success ||
type != utf8_string ||
format != 8 ||
nitems == 0 ||
!g_utf8_validate (val, nitems, NULL))
{
retval = NULL;
}
else
{
retval = g_strndup (val, nitems);
}
g_clear_pointer (&val, XFree);
return retval;
}
static gchar*
wm_common_get_current_window_manager (void)
{
Atom atom = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "_NET_WM_NAME", False);
char *result;
result = wm_common_get_window_manager_property (atom);
if (result)
return result;
else
return g_strdup (WM_COMMON_UNKNOWN);
}
GStrv
wm_common_get_current_keybindings (void)
{
g_autofree gchar* keybindings = NULL;
g_auto(GStrv) results = NULL;
Atom keybindings_atom;
keybindings_atom = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "_GNOME_WM_KEYBINDINGS", False);
keybindings = wm_common_get_window_manager_property (keybindings_atom);
if (keybindings)
{
GStrv p;
results = g_strsplit (keybindings, ",", -1);
for (p = results; p && *p; p++)
g_strstrip (*p);
}
else
{
g_autofree gchar *wm_name = NULL;
Atom wm_atom;
gchar *to_copy[2] = { NULL, NULL };
wm_atom = XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "_NET_WM_NAME", False);
wm_name = wm_common_get_window_manager_property (wm_atom);
to_copy[0] = wm_name ? wm_name : WM_COMMON_UNKNOWN;
results = g_strdupv (to_copy);
}
return g_steal_pointer (&results);
}
static void
update_wm_window (void)
{
g_autoptr(GPtrArray) trapped_displays = NULL;
Window *xwindow;
Atom type;
gint format;
gulong nitems;
gulong bytes_after;
XGetWindowProperty (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), GDK_ROOT_WINDOW (),
XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "_NET_SUPPORTING_WM_CHECK", False),
0, G_MAXLONG, False, XA_WINDOW, &type, &format,
&nitems, &bytes_after, (guchar **) &xwindow);
if (type != XA_WINDOW)
{
wm_window = None;
return;
}
trapped_displays = push_error_traps ();
XSelectInput (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), *xwindow, StructureNotifyMask | PropertyChangeMask);
XSync (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), False);
if (pop_error_traps (trapped_displays))
{
XFree (xwindow);
wm_window = None;
return;
}
wm_window = *xwindow;
XFree (xwindow);
}
static GdkFilterReturn
wm_window_event_filter (GdkXEvent *xev,
GdkEvent *event,
gpointer data)
{
WMCallbackData *ncb_data = (WMCallbackData*) data;
XEvent *xevent = (XEvent *)xev;
if ((xevent->type == DestroyNotify &&
wm_window != None && xevent->xany.window == wm_window) ||
(xevent->type == PropertyNotify &&
xevent->xany.window == GDK_ROOT_WINDOW () &&
xevent->xproperty.atom == (XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "_NET_SUPPORTING_WM_CHECK", False))) ||
(xevent->type == PropertyNotify &&
wm_window != None && xevent->xany.window == wm_window &&
xevent->xproperty.atom == (XInternAtom (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), "_NET_WM_NAME", False))))
{
update_wm_window ();
(* ncb_data->func) ((gpointer) wm_common_get_current_window_manager (), ncb_data->data);
}
return GDK_FILTER_CONTINUE;
}
gpointer
wm_common_register_window_manager_change (GFunc func,
gpointer data)
{
WMCallbackData *ncb_data;
ncb_data = g_new0 (WMCallbackData, 1);
ncb_data->func = func;
ncb_data->data = data;
gdk_window_add_filter (NULL, wm_window_event_filter, ncb_data);
update_wm_window ();
XSelectInput (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), GDK_ROOT_WINDOW (), PropertyChangeMask);
XSync (GDK_DISPLAY_XDISPLAY (gdk_display_get_default ()), False);
return ncb_data;
}
void
wm_common_unregister_window_manager_change (gpointer id)
{
g_return_if_fail (id != NULL);
gdk_window_remove_filter (NULL, wm_window_event_filter, id);
g_free (id);
}

View file

@ -1,14 +0,0 @@
#pragma once
#define WM_COMMON_METACITY "Metacity"
#define WM_COMMON_SAWFISH "Sawfish"
#define WM_COMMON_UNKNOWN "Unknown"
/* Returns a strv of keybinding names for the window manager;
* using _GNOME_WM_KEYBINDINGS if available, _NET_WM_NAME otherwise. */
GStrv wm_common_get_current_keybindings (void);
gpointer wm_common_register_window_manager_change (GFunc func,
gpointer data);
void wm_common_unregister_window_manager_change (gpointer id);

View file

@ -10,7 +10,7 @@ panels = [
'diagnostics',
# 'display',
'info-overview',
# 'keyboard',
'keyboard',
'location',
'lock',
'microphone',

View file

@ -41,7 +41,7 @@ extern GType cc_bluetooth_panel_get_type (void);
extern GType cc_default_apps_panel_get_type (void);
//extern GType cc_display_panel_get_type (void);
extern GType cc_info_overview_panel_get_type (void);
//extern GType cc_keyboard_panel_get_type (void);
extern GType cc_keyboard_panel_get_type (void);
extern GType cc_mouse_panel_get_type (void);
extern GType cc_multitasking_panel_get_type (void);
#ifdef BUILD_NETWORK
@ -109,7 +109,7 @@ static CcPanelLoaderVtable default_panels[] =
PANEL_TYPE("diagnostics", cc_diagnostics_panel_get_type, cc_diagnostics_panel_static_init_func),
//PANEL_TYPE("display", cc_display_panel_get_type, NULL),
PANEL_TYPE("info-overview", cc_info_overview_panel_get_type, NULL),
//PANEL_TYPE("keyboard", cc_keyboard_panel_get_type, NULL),
PANEL_TYPE("keyboard", cc_keyboard_panel_get_type, NULL),
PANEL_TYPE("location", cc_location_panel_get_type, NULL),
PANEL_TYPE("lock", cc_lock_panel_get_type, NULL),
PANEL_TYPE("microphone", cc_microphone_panel_get_type, NULL),