From 73e4c58e52fd48c83642c0d7d137677ef97377ef Mon Sep 17 00:00:00 2001 From: Ryo Nakano Date: Sat, 29 Nov 2025 17:02:36 +0900 Subject: [PATCH 1/9] Introduce own AppChooserButton instead of deprecated Gtk.AppChooserButton --- README.md | 2 +- src/Defaults/AppChooserButton.vala | 321 ++++++++++++++++++++++++++ src/Defaults/AppChooserButtonRow.vala | 29 +++ src/Defaults/DefaultPlug.vala | 247 +------------------- src/meson.build | 4 +- 5 files changed, 356 insertions(+), 247 deletions(-) create mode 100644 src/Defaults/AppChooserButton.vala create mode 100644 src/Defaults/AppChooserButtonRow.vala diff --git a/README.md b/README.md index 8cef0031..82c25221 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ You'll need the following dependencies: * libadwaita-1-dev * libswitchboard-3-dev * libflatpak-dev -* libgranite-7-dev >= 7.4.0 +* libgranite-7-dev >= 7.6.0 * libgtk-4-dev * meson * valac diff --git a/src/Defaults/AppChooserButton.vala b/src/Defaults/AppChooserButton.vala new file mode 100644 index 00000000..f4218510 --- /dev/null +++ b/src/Defaults/AppChooserButton.vala @@ -0,0 +1,321 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2011-2025 elementary, Inc. (https://elementary.io) + */ + +public class Defaults.AppChooserButton : Granite.Bin { + public string content_type { get; construct; } + + public AppChooserButton (string content_type) { + Object ( + content_type: content_type + ); + } + + construct { + var apps_store = new ListStore (typeof (AppInfo)); + + load_apps (apps_store, content_type); + + var factory = new Gtk.SignalListItemFactory (); + factory.setup.connect (factory_setup); + factory.bind.connect (factory_bind); + + var app_info_expr = new Gtk.ObjectExpression (apps_store); + + var app_name_expr = new Gtk.CClosureExpression ( + typeof (string), null, { app_info_expr }, + (Callback) get_app_name, + null, null + ); + + var dropdown = new Gtk.DropDown (apps_store, app_name_expr) { + factory = factory + }; + + dropdown.notify["selected-item"].connect ((obj, pspec) => run_in_thread (() => { + change_default ((AppInfo) obj, content_type); + return null; + })); + + apps_store.bind_property ("n-items", dropdown, "sensitive", DEFAULT | SYNC_CREATE, + (binding, _n_items, ref _sensitive) => { + _sensitive = ((uint) _n_items > 0); + return true; + } + ); + + child = dropdown; + } + + private void load_apps (ListStore store, string content_type) { + store.remove_all (); + + var apps = AppInfo.get_all_for_type (content_type); + if (apps == null) { + warning ("AppInfo.get_all_for_type() error. content_type=%s", content_type); + return; + } + + apps.foreach ((item) => { + store.append (item); + }); + } + + private void factory_setup (Object object) { + var item = object as Gtk.ListItem; + + var row = new AppChooserButtonRow (); + item.child = row; + } + + private void factory_bind (Object object) { + var item = object as Gtk.ListItem; + var model = item.item as AppInfo; + var row = item.child as AppChooserButtonRow; + + row.app_icon = model.get_icon (); + row.app_name = model.get_name (); + } + + private string get_app_name (AppInfo app_info) { + return app_info.get_name (); + } + + private void run_in_thread (owned ThreadFunc func) { + try { + new Thread.try (null, (owned) func); + } catch (Error e) { + warning ("Could not create a new thread: %s", e.message); + } + } + + private void change_default (AppInfo app, string content_type) { + var types = get_types_for_app (content_type); + var supported_types = app.get_supported_types (); + + foreach (unowned var type in types) { + AppInfo.reset_type_associations (type); + if (type in supported_types) { + try { + app.set_as_default_for_type (type); + debug ("%s now default for content type %s", app.get_name (), type); + } catch (Error e) { + critical ("Error setting default app: %s", e.message); + } + } else { + critical ("%s does not support content type %s", app.get_name (), type); + } + } + } + + private string[] get_types_for_app (string app) { + switch (app) { + case "x-scheme-handler/geo": + return { "x-scheme-handler/geo" }; + + case "x-scheme-handler/https": + return { + "x-scheme-handler/http", + "x-scheme-handler/https", + "text/html", + "application/xhtml+xml", + }; + + case "x-scheme-handler/mailto": + return { "x-scheme-handler/mailto" }; + + case "text/calendar": + return { "text/calendar" }; + + case "video/x-ogm+ogg": + return { + "application/x-quicktimeplayer", + "application/vnd.rn-realmedia", + "application/asx", + "application/x-mplayer2", + "application/x-ms-wmv", + "video/quicktime", + "video/x-quicktime", + "video/vnd.rn-realvideo", + "video/x-ms-asf-plugin", + "video/x-msvideo", + "video/msvideo", + "video/x-ms-asf", + "video/x-ms-wm", + "video/x-ms-wmv", + "video/x-ms-wmp", + "video/x-ms-wvx", + "video/mpeg", + "video/x-mpeg", + "video/x-mpeg2", + "video/mp4", + "video/3gpp", + "video/fli", + "video/x-fli", + "video/x-flv", + "video/vnd.vivo", + "video/x-matroska", + "video/matroska", + "video/x-mng", + "video/webm", + "video/x-webm", + "video/mp2t", + "video/vnd.mpegurl", + "video/x-ogm+ogg" + }; + + case "audio/x-vorbis+ogg": + return { + "audio/ogg", + "audio/mpeg", + "audio/mp4", + "audio/flac", + "application/x-musepack", + "application/musepack", + "application/x-ape", + "application/x-id3", + "application/ogg", + "application/x-ogg", + "application/x-vorbis+ogg", + "application/x-flac", + "application/vnd.rn-realaudio", + "application/x-nsv-vp3-mp3", + "audio/x-musepack", + "audio/musepack", + "audio/ape", + "audio/x-ape", + "audio/x-mp3", + "audio/mpeg", + "audio/x-mpeg", + "audio/x-mpeg-3", + "audio/mpeg3", + "audio/mp3", + "audio/mp4", + "audio/x-m4a", + "audio/mpc", + "audio/x-mpc", + "audio/mp", + "audio/x-mp", + "audio/x-vorbis+ogg", + "audio/vorbis", + "audio/x-vorbis", + "audio/ogg", + "audio/x-ogg", + "audio/x-flac", + "audio/flac", + "audio/x-s3m", + "audio/x-mod", + "audio/x-xm", + "audio/x-it", + "audio/x-pn-realaudio", + "audio/x-realaudio", + "audio/x-pn-realaudio-plugin", + "audio/x-ms-wmv", + "audio/x-ms-wax", + "audio/x-ms-wma", + "audio/wav", + "audio/x-wav", + "audio/mpeg2", + "audio/x-mpeg2", + "audio/x-mpeg3", + "audio/x-mpegurl", + "audio/basic", + "audio/x-basic", + "audio/midi", + "audio/x-scpls", + "audio/webm", + "audio/x-webm", + "x-content/audio-player" + }; + + case "image/jpeg": + return { + "image/jpeg", + "image/jpg", + "image/pjpeg", + "image/png", + "image/tiff", + "image/x-3fr", + "image/x-adobe-dng", + "image/x-arw", + "image/x-bay", + "image/x-bmp", + "image/x-canon-cr2", + "image/x-canon-crw", + "image/x-cap", + "image/x-cr2", + "image/x-crw", + "image/x-dcr", + "image/x-dcraw", + "image/x-dcs", + "image/x-dng", + "image/x-drf", + "image/x-eip", + "image/x-erf", + "image/x-fff", + "image/x-fuji-raf", + "image/x-iiq", + "image/x-k25", + "image/x-kdc", + "image/x-mef", + "image/x-minolta-mrw", + "image/x-mos", + "image/x-mrw", + "image/x-nef", + "image/x-nikon-nef", + "image/x-nrw", + "image/x-olympus-orf", + "image/x-orf", + "image/x-panasonic-raw", + "image/x-pef", + "image/x-pentax-pef", + "image/x-png", + "image/x-ptx", + "image/x-pxn", + "image/x-r3d", + "image/x-raf", + "image/x-raw", + "image/x-raw", + "image/x-rw2", + "image/x-rwl", + "image/x-rwz", + "image/x-sigma-x3f", + "image/x-sony-arw", + "image/x-sony-sr2", + "image/x-sony-srf", + "image/x-sr2", + "image/x-srf", + "image/x-x3f" + }; + + case "text/plain": + return { + "application/xml", + "application/x-perl", + "text/mathml", + "text/plain", + "text/xml", + "text/x-c++hdr", + "text/x-c++src", + "text/x-xsrc", + "text/x-chdr", + "text/x-csrc", + "text/x-dtd", + "text/x-java", + "text/x-python", + "text/x-sql" + }; + + case "inode/directory": + return { + "inode/directory", + "x-directory/normal", + "x-directory/gnome-default-handler" + }; + + default: + return {}; + } + } +} diff --git a/src/Defaults/AppChooserButtonRow.vala b/src/Defaults/AppChooserButtonRow.vala new file mode 100644 index 00000000..db62f5e1 --- /dev/null +++ b/src/Defaults/AppChooserButtonRow.vala @@ -0,0 +1,29 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2011-2025 elementary, Inc. (https://elementary.io) + */ + +public class AppChooserButtonRow : Gtk.Box { + public Icon app_icon { get; set; } + public string app_name { get; set; } + + construct { + orientation = HORIZONTAL; + + var icon = new Gtk.Image () { + halign = START + }; + + var label = new Gtk.Label (null) { + halign = START, + hexpand = true, + ellipsize = END + }; + + bind_property ("app-icon", icon, "gicon"); + bind_property ("app-name", label, "label"); + + append (icon); + append (label); + } +} diff --git a/src/Defaults/DefaultPlug.vala b/src/Defaults/DefaultPlug.vala index 487fd7f1..133fd29a 100644 --- a/src/Defaults/DefaultPlug.vala +++ b/src/Defaults/DefaultPlug.vala @@ -102,9 +102,8 @@ public class Defaults.Plug : Switchboard.SettingsPage { construct { var setting_label = new Granite.HeaderLabel (label); - var app_chooser = new Gtk.AppChooserButton (content_type) { - hexpand = true, - show_default_item = true + var app_chooser = new AppChooserButton (content_type) { + hexpand = true }; setting_label.mnemonic_widget = app_chooser.get_first_child (); @@ -116,248 +115,6 @@ public class Defaults.Plug : Switchboard.SettingsPage { child = box; size_group.add_widget (setting_label); - - app_chooser.changed.connect (() => run_in_thread (() => { - change_default (app_chooser.get_app_info (), content_type); - return null; - })); - } - - private void run_in_thread (owned ThreadFunc func) { - try { - new Thread.try (null, (owned) func); - } catch (Error e) { - warning ("Could not create a new thread: %s", e.message); - } - } - - private void change_default (AppInfo app, string content_type) { - var types = get_types_for_app (content_type); - var supported_types = app.get_supported_types (); - - foreach (unowned var type in types) { - AppInfo.reset_type_associations (type); - if (type in supported_types) { - try { - app.set_as_default_for_type (type); - debug ("%s now default for content type %s", app.get_name (), type); - } catch (Error e) { - critical ("Error setting default app: %s", e.message); - } - } else { - critical ("%s does not support content type %s", app.get_name (), type); - } - } - } - - private string[] get_types_for_app (string app) { - switch (app) { - case "x-scheme-handler/geo": - return { "x-scheme-handler/geo" }; - - case "x-scheme-handler/https": - return { - "x-scheme-handler/http", - "x-scheme-handler/https", - "text/html", - "application/xhtml+xml", - }; - - case "x-scheme-handler/mailto": - return { "x-scheme-handler/mailto" }; - - case "text/calendar": - return { "text/calendar" }; - - case "video/x-ogm+ogg": - return { - "application/x-quicktimeplayer", - "application/vnd.rn-realmedia", - "application/asx", - "application/x-mplayer2", - "application/x-ms-wmv", - "video/quicktime", - "video/x-quicktime", - "video/vnd.rn-realvideo", - "video/x-ms-asf-plugin", - "video/x-msvideo", - "video/msvideo", - "video/x-ms-asf", - "video/x-ms-wm", - "video/x-ms-wmv", - "video/x-ms-wmp", - "video/x-ms-wvx", - "video/mpeg", - "video/x-mpeg", - "video/x-mpeg2", - "video/mp4", - "video/3gpp", - "video/fli", - "video/x-fli", - "video/x-flv", - "video/vnd.vivo", - "video/x-matroska", - "video/matroska", - "video/x-mng", - "video/webm", - "video/x-webm", - "video/mp2t", - "video/vnd.mpegurl", - "video/x-ogm+ogg" - }; - - case "audio/x-vorbis+ogg": - return { - "audio/ogg", - "audio/mpeg", - "audio/mp4", - "audio/flac", - "application/x-musepack", - "application/musepack", - "application/x-ape", - "application/x-id3", - "application/ogg", - "application/x-ogg", - "application/x-vorbis+ogg", - "application/x-flac", - "application/vnd.rn-realaudio", - "application/x-nsv-vp3-mp3", - "audio/x-musepack", - "audio/musepack", - "audio/ape", - "audio/x-ape", - "audio/x-mp3", - "audio/mpeg", - "audio/x-mpeg", - "audio/x-mpeg-3", - "audio/mpeg3", - "audio/mp3", - "audio/mp4", - "audio/x-m4a", - "audio/mpc", - "audio/x-mpc", - "audio/mp", - "audio/x-mp", - "audio/x-vorbis+ogg", - "audio/vorbis", - "audio/x-vorbis", - "audio/ogg", - "audio/x-ogg", - "audio/x-flac", - "audio/flac", - "audio/x-s3m", - "audio/x-mod", - "audio/x-xm", - "audio/x-it", - "audio/x-pn-realaudio", - "audio/x-realaudio", - "audio/x-pn-realaudio-plugin", - "audio/x-ms-wmv", - "audio/x-ms-wax", - "audio/x-ms-wma", - "audio/wav", - "audio/x-wav", - "audio/mpeg2", - "audio/x-mpeg2", - "audio/x-mpeg3", - "audio/x-mpegurl", - "audio/basic", - "audio/x-basic", - "audio/midi", - "audio/x-scpls", - "audio/webm", - "audio/x-webm", - "x-content/audio-player" - }; - - case "image/jpeg": - return { - "image/jpeg", - "image/jpg", - "image/pjpeg", - "image/png", - "image/tiff", - "image/x-3fr", - "image/x-adobe-dng", - "image/x-arw", - "image/x-bay", - "image/x-bmp", - "image/x-canon-cr2", - "image/x-canon-crw", - "image/x-cap", - "image/x-cr2", - "image/x-crw", - "image/x-dcr", - "image/x-dcraw", - "image/x-dcs", - "image/x-dng", - "image/x-drf", - "image/x-eip", - "image/x-erf", - "image/x-fff", - "image/x-fuji-raf", - "image/x-iiq", - "image/x-k25", - "image/x-kdc", - "image/x-mef", - "image/x-minolta-mrw", - "image/x-mos", - "image/x-mrw", - "image/x-nef", - "image/x-nikon-nef", - "image/x-nrw", - "image/x-olympus-orf", - "image/x-orf", - "image/x-panasonic-raw", - "image/x-pef", - "image/x-pentax-pef", - "image/x-png", - "image/x-ptx", - "image/x-pxn", - "image/x-r3d", - "image/x-raf", - "image/x-raw", - "image/x-raw", - "image/x-rw2", - "image/x-rwl", - "image/x-rwz", - "image/x-sigma-x3f", - "image/x-sony-arw", - "image/x-sony-sr2", - "image/x-sony-srf", - "image/x-sr2", - "image/x-srf", - "image/x-x3f" - }; - - case "text/plain": - return { - "application/xml", - "application/x-perl", - "text/mathml", - "text/plain", - "text/xml", - "text/x-c++hdr", - "text/x-c++src", - "text/x-xsrc", - "text/x-chdr", - "text/x-csrc", - "text/x-dtd", - "text/x-java", - "text/x-python", - "text/x-sql" - }; - - case "inode/directory": - return { - "inode/directory", - "x-directory/normal", - "x-directory/gnome-default-handler" - }; - - default: - return {}; - } } } } diff --git a/src/meson.build b/src/meson.build index 1dca946b..2eff291f 100644 --- a/src/meson.build +++ b/src/meson.build @@ -12,6 +12,8 @@ plug_files = files( 'Startup/Widgets/AppRow.vala', 'Startup/Widgets/AppChooserRow.vala', 'Startup/Widgets/AppChooser.vala', + 'Defaults/AppChooserButton.vala', + 'Defaults/AppChooserButtonRow.vala', 'Defaults/DefaultPlug.vala', 'Permissions/Backend/App.vala', 'Permissions/Backend/AppManager.vala', @@ -36,7 +38,7 @@ shared_module( dependency('glib-2.0', version: '>=2.34'), dependency('gio-2.0'), dependency('gobject-2.0'), - dependency('granite-7', version: '>=7.4.0'), + dependency('granite-7', version: '>=7.6.0'), dependency('gtk4'), dependency('libadwaita-1', version: '>=1.4'), switchboard_dep From f96282f77f5786246ffda33b37175b3146ecf8e0 Mon Sep 17 00:00:00 2001 From: Ryo Nakano Date: Sat, 29 Nov 2025 17:13:17 +0900 Subject: [PATCH 2/9] Fix wrong cast from DropDown to AppInfo --- src/Defaults/AppChooserButton.vala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Defaults/AppChooserButton.vala b/src/Defaults/AppChooserButton.vala index f4218510..43028ecf 100644 --- a/src/Defaults/AppChooserButton.vala +++ b/src/Defaults/AppChooserButton.vala @@ -33,8 +33,9 @@ public class Defaults.AppChooserButton : Granite.Bin { factory = factory }; - dropdown.notify["selected-item"].connect ((obj, pspec) => run_in_thread (() => { - change_default ((AppInfo) obj, content_type); + dropdown.notify["selected-item"].connect (() => run_in_thread (() => { + var app_info = (AppInfo) dropdown.selected_item; + change_default (app_info, content_type); return null; })); From 94cf99dac231e59edb4e4c22b0dfabb835cf6ae9 Mon Sep 17 00:00:00 2001 From: Ryo Nakano Date: Sat, 29 Nov 2025 17:39:57 +0900 Subject: [PATCH 3/9] Setup initial selection --- src/Defaults/AppChooserButton.vala | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/Defaults/AppChooserButton.vala b/src/Defaults/AppChooserButton.vala index 43028ecf..c4cc85e9 100644 --- a/src/Defaults/AppChooserButton.vala +++ b/src/Defaults/AppChooserButton.vala @@ -33,6 +33,8 @@ public class Defaults.AppChooserButton : Granite.Bin { factory = factory }; + dropdown.selected = find_default_app_pos (apps_store, content_type); + dropdown.notify["selected-item"].connect (() => run_in_thread (() => { var app_info = (AppInfo) dropdown.selected_item; change_default (app_info, content_type); @@ -63,6 +65,29 @@ public class Defaults.AppChooserButton : Granite.Bin { }); } + private uint find_default_app_pos (ListStore store, string content_type) { + var default_app = AppInfo.get_default_for_type (content_type, false); + if (default_app == null) { + warning ("AppInfo.get_default_for_type() error. content_type=%s", content_type); + return Gtk.INVALID_LIST_POSITION; + } + + uint pos; + bool found = store.find_with_equal_func (default_app, + ((a, b) => { + return ((AppInfo) a).get_id () == ((AppInfo) b).get_id (); + }), + out pos + ); + if (!found) { + // Wouldn't happen, probably all apps store is not initialized + warning ("BUG: default app not found in all apps store! default_app=%s", default_app.get_id ()); + return Gtk.INVALID_LIST_POSITION; + } + + return pos; + } + private void factory_setup (Object object) { var item = object as Gtk.ListItem; From 51cac8b7591161132b61f06bf03c7ec14190b38a Mon Sep 17 00:00:00 2001 From: Ryo Nakano Date: Sat, 29 Nov 2025 17:42:33 +0900 Subject: [PATCH 4/9] Only list recommended apps --- src/Defaults/AppChooserButton.vala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Defaults/AppChooserButton.vala b/src/Defaults/AppChooserButton.vala index c4cc85e9..fea7adce 100644 --- a/src/Defaults/AppChooserButton.vala +++ b/src/Defaults/AppChooserButton.vala @@ -54,7 +54,7 @@ public class Defaults.AppChooserButton : Granite.Bin { private void load_apps (ListStore store, string content_type) { store.remove_all (); - var apps = AppInfo.get_all_for_type (content_type); + var apps = AppInfo.get_recommended_for_type (content_type); if (apps == null) { warning ("AppInfo.get_all_for_type() error. content_type=%s", content_type); return; From 4ecc116970dde4becdb0d4b474c93ed07813868c Mon Sep 17 00:00:00 2001 From: Ryo Nakano Date: Sat, 29 Nov 2025 17:47:21 +0900 Subject: [PATCH 5/9] Consistent variable name with the existing code --- src/Defaults/AppChooserButton.vala | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Defaults/AppChooserButton.vala b/src/Defaults/AppChooserButton.vala index fea7adce..48065a83 100644 --- a/src/Defaults/AppChooserButton.vala +++ b/src/Defaults/AppChooserButton.vala @@ -21,10 +21,10 @@ public class Defaults.AppChooserButton : Granite.Bin { factory.setup.connect (factory_setup); factory.bind.connect (factory_bind); - var app_info_expr = new Gtk.ObjectExpression (apps_store); + var app_expr = new Gtk.ObjectExpression (apps_store); var app_name_expr = new Gtk.CClosureExpression ( - typeof (string), null, { app_info_expr }, + typeof (string), null, { app_expr }, (Callback) get_app_name, null, null ); @@ -36,8 +36,8 @@ public class Defaults.AppChooserButton : Granite.Bin { dropdown.selected = find_default_app_pos (apps_store, content_type); dropdown.notify["selected-item"].connect (() => run_in_thread (() => { - var app_info = (AppInfo) dropdown.selected_item; - change_default (app_info, content_type); + var app = (AppInfo) dropdown.selected_item; + change_default (app, content_type); return null; })); @@ -104,8 +104,8 @@ public class Defaults.AppChooserButton : Granite.Bin { row.app_name = model.get_name (); } - private string get_app_name (AppInfo app_info) { - return app_info.get_name (); + private string get_app_name (AppInfo app) { + return app.get_name (); } private void run_in_thread (owned ThreadFunc func) { From 29a67bce33b93d3084977ee76147fb785dae72cd Mon Sep 17 00:00:00 2001 From: Ryo Nakano Date: Sun, 30 Nov 2025 01:04:33 +0900 Subject: [PATCH 6/9] Correct line order, leave comment --- src/Defaults/AppChooserButton.vala | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/Defaults/AppChooserButton.vala b/src/Defaults/AppChooserButton.vala index 48065a83..98ce66f1 100644 --- a/src/Defaults/AppChooserButton.vala +++ b/src/Defaults/AppChooserButton.vala @@ -13,14 +13,15 @@ public class Defaults.AppChooserButton : Granite.Bin { } construct { - var apps_store = new ListStore (typeof (AppInfo)); - - load_apps (apps_store, content_type); - var factory = new Gtk.SignalListItemFactory (); factory.setup.connect (factory_setup); factory.bind.connect (factory_bind); + var apps_store = new ListStore (typeof (AppInfo)); + + // Ignore result of load so that we always continue to setup the UI widgets + load_apps (apps_store, content_type); + var app_expr = new Gtk.ObjectExpression (apps_store); var app_name_expr = new Gtk.CClosureExpression ( From 35accaedf9c6122d2e6f0873e980a2f5db90e830 Mon Sep 17 00:00:00 2001 From: Ryo Nakano Date: Sun, 30 Nov 2025 01:06:53 +0900 Subject: [PATCH 7/9] Update variable name for consistency --- src/Defaults/AppChooserButton.vala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Defaults/AppChooserButton.vala b/src/Defaults/AppChooserButton.vala index 98ce66f1..87dbe5bc 100644 --- a/src/Defaults/AppChooserButton.vala +++ b/src/Defaults/AppChooserButton.vala @@ -98,11 +98,11 @@ public class Defaults.AppChooserButton : Granite.Bin { private void factory_bind (Object object) { var item = object as Gtk.ListItem; - var model = item.item as AppInfo; + var app = item.item as AppInfo; var row = item.child as AppChooserButtonRow; - row.app_icon = model.get_icon (); - row.app_name = model.get_name (); + row.app_icon = app.get_icon (); + row.app_name = app.get_name (); } private string get_app_name (AppInfo app) { From d08b060f6ae872330267caa4fd603de9e5edf465 Mon Sep 17 00:00:00 2001 From: Ryo Nakano Date: Sat, 6 Dec 2025 10:48:00 +0900 Subject: [PATCH 8/9] Leave comments, increase reference count --- src/Defaults/AppChooserButton.vala | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/Defaults/AppChooserButton.vala b/src/Defaults/AppChooserButton.vala index f198a871..5500fe9f 100644 --- a/src/Defaults/AppChooserButton.vala +++ b/src/Defaults/AppChooserButton.vala @@ -19,11 +19,14 @@ public class Defaults.AppChooserButton : Granite.Bin { var apps_store = new ListStore (typeof (AppInfo)); - // Ignore result of load so that we always continue to setup the UI widgets + // Ignore result of load so that we always continue to setup UI + // with blank app_store load_apps (apps_store, content_type); - var app_expr = new Gtk.ObjectExpression (apps_store); + // Expression to retrieve a reference of app_store + var app_expr = new Gtk.ConstantExpression (typeof (ListStore), apps_store); + // Expression to retrieve a name of each AppInfo element in app_store var app_name_expr = new Gtk.CClosureExpression ( typeof (string), null, { app_expr }, (Callback) get_app_name, @@ -81,7 +84,7 @@ public class Defaults.AppChooserButton : Granite.Bin { out pos ); if (!found) { - // Wouldn't happen, probably all apps store is not initialized + // Wouldn't happen, probably store is not initialized warning ("BUG: default app not found in all apps store! default_app=%s", default_app.get_id ()); return Gtk.INVALID_LIST_POSITION; } From 6b2443ab9dadd435b7032c8143226c0708e8937b Mon Sep 17 00:00:00 2001 From: Ryo Nakano Date: Fri, 19 Dec 2025 21:18:01 +0900 Subject: [PATCH 9/9] Add spacing between icon and label --- src/Defaults/AppChooserButtonRow.vala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Defaults/AppChooserButtonRow.vala b/src/Defaults/AppChooserButtonRow.vala index db62f5e1..58293571 100644 --- a/src/Defaults/AppChooserButtonRow.vala +++ b/src/Defaults/AppChooserButtonRow.vala @@ -9,6 +9,7 @@ public class AppChooserButtonRow : Gtk.Box { construct { orientation = HORIZONTAL; + spacing = 6; var icon = new Gtk.Image () { halign = START