Skip to content

Commit 6f9699b

Browse files
authored
Merge pull request #773 from mjakeman/fix-focus-loss
installed-page: Save extension's toggle focus on state changes
2 parents 5841d83 + 4bb993b commit 6f9699b

7 files changed

+123
-26
lines changed

src/exm-extension-row.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,12 @@ on_state_changed (GtkSwitch *toggle,
323323
return TRUE;
324324
}
325325

326+
void
327+
exm_search_row_focus_toggle (ExmExtensionRow *self)
328+
{
329+
gtk_widget_grab_focus (GTK_WIDGET (self->ext_toggle));
330+
}
331+
326332
static void
327333
exm_extension_row_class_init (ExmExtensionRowClass *klass)
328334
{

src/exm-extension-row.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ G_BEGIN_DECLS
1111

1212
G_DECLARE_FINAL_TYPE (ExmExtensionRow, exm_extension_row, EXM, EXTENSION_ROW, AdwExpanderRow)
1313

14-
ExmExtensionRow *
15-
exm_extension_row_new (ExmExtension *extension,
16-
ExmManager *manager);
14+
ExmExtensionRow *exm_extension_row_new (ExmExtension *extension,
15+
ExmManager *manager);
16+
17+
void exm_search_row_focus_toggle (ExmExtensionRow *self);
1718

1819
G_END_DECLS

src/exm-installed-page.blp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ template $ExmInstalledPage: Gtk.Widget {
3838
Gtk.ListBox user_list_box {
3939
styles [
4040
"boxed-list",
41-
"boxed-list-placeholder"
41+
"boxed-list-placeholder",
4242
]
4343

4444
selection-mode: none;
@@ -73,7 +73,7 @@ template $ExmInstalledPage: Gtk.Widget {
7373
Gtk.ListBox system_list_box {
7474
styles [
7575
"boxed-list",
76-
"boxed-list-placeholder"
76+
"boxed-list-placeholder",
7777
]
7878

7979
selection-mode: none;
@@ -104,7 +104,7 @@ template $ExmInstalledPage: Gtk.Widget {
104104
Adw.PreferencesGroup {
105105
Gtk.ListBox search_list_box {
106106
styles [
107-
"boxed-list"
107+
"boxed-list",
108108
]
109109

110110
selection-mode: none;
@@ -128,7 +128,7 @@ template $ExmInstalledPage: Gtk.Widget {
128128

129129
child: Gtk.Button {
130130
styles [
131-
"pill"
131+
"pill",
132132
]
133133

134134
label: _("_Search Online");

src/exm-installed-page.c

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ struct _ExmInstalledPage
4646
GtkFilterListModel *search_list_model;
4747

4848
gboolean sort_enabled_first;
49+
guint signal_id;
4950
};
5051

5152
G_DEFINE_FINAL_TYPE (ExmInstalledPage, exm_installed_page, GTK_TYPE_WIDGET)
@@ -305,6 +306,72 @@ on_updates_available (ExmManager *manager G_GNUC_UNUSED,
305306
g_timeout_add (500, G_SOURCE_FUNC (show_updates_banner), self);
306307
}
307308

309+
static gboolean
310+
focus_matching_extension (GtkListBox *list_box,
311+
ExmExtension *extension)
312+
{
313+
int index = 0;
314+
ExmExtensionRow *row;
315+
316+
while ((row = EXM_EXTENSION_ROW (gtk_list_box_get_row_at_index (list_box, index))))
317+
{
318+
ExmExtension *row_extension;
319+
320+
g_object_get (row, "extension", &row_extension, NULL);
321+
322+
if (is_extension_equal (extension, row_extension))
323+
{
324+
exm_search_row_focus_toggle (row);
325+
g_object_unref (row_extension);
326+
327+
return TRUE;
328+
}
329+
330+
g_object_unref (row_extension);
331+
index++;
332+
}
333+
334+
return FALSE;
335+
}
336+
337+
static void
338+
on_extensions_changed (GListModel *model,
339+
guint position,
340+
guint removed,
341+
guint added,
342+
ExmInstalledPage *self)
343+
{
344+
if (!self->sort_enabled_first || (removed > 0 && added > 0))
345+
return;
346+
347+
ExmExtension *extension = EXM_EXTENSION (g_list_model_get_object (model, position));
348+
349+
if (!extension)
350+
return;
351+
352+
GtkRoot *toplevel = gtk_widget_get_root (GTK_WIDGET (self));
353+
GtkWidget *focused_widget = gtk_window_get_focus (GTK_WINDOW (toplevel));
354+
355+
if (g_list_store_find_with_equal_func (G_LIST_STORE (model), extension, (GEqualFunc)is_extension_equal, &position))
356+
g_list_model_items_changed (model, position, 1, 1);
357+
358+
if (focused_widget && gtk_widget_has_focus (focused_widget)
359+
&& gtk_widget_get_child_visible (GTK_WIDGET (self)))
360+
{
361+
if (g_strcmp0 (gtk_stack_get_visible_child_name (self->stack), "page_results") == 0)
362+
{
363+
focus_matching_extension (self->search_list_box, extension);
364+
}
365+
else
366+
{
367+
if (!focus_matching_extension (self->user_list_box, extension))
368+
focus_matching_extension (self->system_list_box, extension);
369+
}
370+
}
371+
372+
g_object_unref (extension);
373+
}
374+
308375
static void
309376
invalidate_model_bindings (ExmInstalledPage *self)
310377
{
@@ -318,7 +385,17 @@ invalidate_model_bindings (ExmInstalledPage *self)
318385
NULL);
319386

320387
if (ext_model)
388+
{
321389
bind_list_box (ext_model, self);
390+
391+
if (self->signal_id > 0)
392+
g_signal_handler_disconnect (ext_model, self->signal_id);
393+
394+
self->signal_id = g_signal_connect (ext_model,
395+
"items-changed",
396+
G_CALLBACK (on_extensions_changed),
397+
self);
398+
}
322399
}
323400

324401
static void

src/local/exm-extension.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,25 @@ exm_extension_set_property (GObject *object,
199199
}
200200
}
201201

202+
gint
203+
compare_extension (ExmExtension *a,
204+
ExmExtension *b,
205+
gpointer user_data G_GNUC_UNUSED)
206+
{
207+
const gchar *uuid_a, *uuid_b;
208+
g_object_get (a, "uuid", &uuid_a, NULL);
209+
g_object_get (b, "uuid", &uuid_b, NULL);
210+
211+
return g_strcmp0 (uuid_a, uuid_b);
212+
}
213+
214+
gboolean
215+
is_extension_equal (ExmExtension *a,
216+
ExmExtension *b)
217+
{
218+
return compare_extension (a, b, NULL) == 0;
219+
}
220+
202221
static void
203222
exm_extension_class_init (ExmExtensionClass *klass)
204223
{

src/local/exm-extension.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ G_BEGIN_DECLS
88

99
G_DECLARE_FINAL_TYPE (ExmExtension, exm_extension, EXM, EXTENSION, GObject)
1010

11-
ExmExtension *exm_extension_new (const gchar *uuid);
11+
ExmExtension *exm_extension_new (const gchar *uuid);
12+
13+
gint compare_extension (ExmExtension *a,
14+
ExmExtension *b,
15+
gpointer user_data);
16+
17+
gboolean is_extension_equal (ExmExtension *a,
18+
ExmExtension *b);
1219

1320
G_END_DECLS

src/local/exm-manager.c

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -746,17 +746,6 @@ update_extension_list (ExmManager *self)
746746
queue_notify_extension_updates (self);
747747
}
748748

749-
static gboolean
750-
is_extension_equal (ExmExtension *a,
751-
ExmExtension *b)
752-
{
753-
const gchar *uuid_a, *uuid_b;
754-
g_object_get (a, "uuid", &uuid_a, NULL);
755-
g_object_get (b, "uuid", &uuid_b, NULL);
756-
757-
return g_strcmp0 (uuid_a, uuid_b) == 0;
758-
}
759-
760749
static void
761750
on_state_changed (ShellExtensions *object G_GNUC_UNUSED,
762751
const gchar *arg_uuid,
@@ -787,25 +776,23 @@ on_state_changed (ShellExtensions *object G_GNUC_UNUSED,
787776

788777
if (is_new)
789778
{
790-
g_list_store_append (list_store, extension);
779+
g_list_store_insert_sorted (list_store, extension, (GCompareDataFunc)compare_extension, NULL);
791780
return;
792781
}
793782

783+
guint position;
784+
794785
if (is_uninstall_operation)
795786
{
796-
guint position;
797787
if (g_list_store_find_with_equal_func (list_store, extension, (GEqualFunc)is_extension_equal, &position))
798788
g_list_store_remove (list_store, position);
799789

800790
return;
801791
}
802792

803793
// Emit items-changed signal to re-sort extension list
804-
{
805-
guint position;
806-
if (g_list_store_find_with_equal_func (list_store, extension, (GEqualFunc)is_extension_equal, &position))
807-
g_list_model_items_changed (G_LIST_MODEL (list_store), position, 1, 1);
808-
}
794+
if (g_list_store_find_with_equal_func (list_store, extension, (GEqualFunc)is_extension_equal, &position))
795+
g_list_model_items_changed (G_LIST_MODEL (list_store), position, 0, 0);
809796

810797
// If the extension that has changed has an update, then
811798
// one or more extensions have updates available. Lazily

0 commit comments

Comments
 (0)