Skip to content

Commit 79e2356

Browse files
committed
Flatpak: use the OpenURI portal to launch external applications
1 parent 66c8e61 commit 79e2356

9 files changed

Lines changed: 446 additions & 50 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ You'll need the following dependencies:
1515
* libgtkspell3-3-dev
1616
* libgranite-dev >= 5.2.0
1717
* libhandy-1-dev >= 0.90.0
18+
* libportal-dev
1819
* libpeas-dev
1920
* libsoup2.4-dev
2021
* libvala-0.34-dev (or higher)

io.elementary.code.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,15 @@ modules:
119119
url: https://github.com/universal-ctags/ctags.git
120120
tag: p5.9.20201101.0
121121

122+
- name: libportal
123+
buildsystem: meson
124+
config-opts:
125+
- '-Dgtk_doc=false'
126+
sources:
127+
- type: git
128+
url: https://github.com/flatpak/libportal.git
129+
tag: '0.4'
130+
122131
- name: code
123132
buildsystem: meson
124133
config-opts:

meson.build

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ gee_dep = dependency('gee-0.8', version: '>=0.8.5')
3131
gtk_dep = dependency('gtk+-3.0', version: '>=3.6.0')
3232
granite_dep = dependency('granite', version: '>=6.0.0')
3333
handy_dep = dependency('libhandy-1', version: '>=0.90.0')
34+
libportal_dep = dependency ('libportal')
3435
gtksourceview_dep = dependency('gtksourceview-4')
3536
peas_dep = dependency('libpeas-1.0')
3637
peasgtk_dep = dependency('libpeas-gtk-1.0')
@@ -51,6 +52,7 @@ dependencies = [
5152
gtk_dep,
5253
granite_dep,
5354
handy_dep,
55+
libportal_dep,
5456
gtksourceview_dep,
5557
peas_dep,
5658
peasgtk_dep,

src/Application.vala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,13 @@ namespace Scratch {
2525
public GLib.Settings settings;
2626
public GLib.Settings service_settings;
2727
public GLib.Settings privacy_settings;
28+
public bool in_sandbox;
2829

2930
public class Application : Gtk.Application {
3031
public string app_cmd_name { get { return _app_cmd_name; } }
3132
public string data_home_folder_unsaved { get { return _data_home_folder_unsaved; } }
3233
public string default_font { get; set; }
34+
public Xdp.Portal portal;
3335
private static string _app_cmd_name;
3436
private static string _data_home_folder_unsaved;
3537
private static bool create_new_tab = false;
@@ -67,6 +69,11 @@ namespace Scratch {
6769
settings = new GLib.Settings (Constants.PROJECT_NAME + ".settings");
6870
service_settings = new GLib.Settings (Constants.PROJECT_NAME + ".services");
6971
privacy_settings = new GLib.Settings ("org.gnome.desktop.privacy");
72+
in_sandbox = FileUtils.test ("/.flatpak-info", FileTest.EXISTS);
73+
74+
if (in_sandbox) {
75+
portal = new Xdp.Portal ();
76+
}
7077
}
7178

7279
public override int handle_local_options (VariantDict options) {

src/FolderManager/FileItem.vala

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,24 @@ namespace Scratch.FolderManager {
3636
new_window.open_document (doc, true);
3737
});
3838

39-
var files_appinfo = AppInfo.get_default_for_type ("inode/directory", true);
39+
Gtk.MenuItem files_menuitem = null;
4040

41-
var files_item_icon = new Gtk.Image.from_gicon (files_appinfo.get_icon (), Gtk.IconSize.MENU);
42-
files_item_icon.pixel_size = 16;
41+
if (in_sandbox) {
42+
files_menuitem = new Gtk.MenuItem.with_label (_("File Manager"));
43+
files_menuitem.activate.connect (() => open_on_file_manager (file));
44+
} else {
45+
var files_appinfo = AppInfo.get_default_for_type ("inode/directory", true);
4346

44-
var files_item_grid = new Gtk.Grid ();
45-
files_item_grid.add (files_item_icon);
46-
files_item_grid.add (new Gtk.Label (files_appinfo.get_name ()));
47+
var files_item_icon = new Gtk.Image.from_gicon (files_appinfo.get_icon (), Gtk.IconSize.MENU);
48+
files_item_icon.pixel_size = 16;
4749

48-
var files_menuitem = new Gtk.MenuItem ();
49-
files_menuitem.add (files_item_grid);
50-
files_menuitem.activate.connect (() => launch_app_with_file (files_appinfo, file.file));
50+
var files_item_grid = new Gtk.Grid ();
51+
files_item_grid.add (files_item_icon);
52+
files_item_grid.add (new Gtk.Label (files_appinfo.get_name ()));
53+
54+
files_menuitem = new Gtk.MenuItem ();
55+
files_menuitem.add (files_item_grid);
56+
}
5157

5258
var other_menuitem = new Gtk.MenuItem.with_label (_("Other Application…"));
5359
other_menuitem.activate.connect (() => show_app_chooser (file));
@@ -135,5 +141,18 @@ namespace Scratch.FolderManager {
135141

136142
return menu;
137143
}
144+
145+
public void open_on_file_manager (File file) {
146+
var portal = ((Scratch.Application) GLib.Application.get_default ()).portal;
147+
var parent = new Xdp.Gtk3.Parent (((Gtk.Application) GLib.Application.get_default ()).active_window);
148+
149+
portal.open_directory.begin (parent, file.file.get_uri (), Xdp.OpenUriFlags.NONE, null, (obj, res) => {
150+
try {
151+
portal.open_directory.end (res);
152+
} catch (Error e) {
153+
warning (e.message);
154+
}
155+
});
156+
}
138157
}
139158
}

src/FolderManager/FolderItem.vala

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ namespace Scratch.FolderManager {
109109
};
110110

111111
var menu = new Gtk.Menu ();
112-
menu.append (create_submenu_for_open_in (info, file_type));
112+
menu.append (create_open_in_menuitem (info, file_type));
113113
menu.append (contractor_item);
114114
menu.append (new Gtk.SeparatorMenuItem ());
115115
menu.append (create_submenu_for_new ());
@@ -122,49 +122,56 @@ namespace Scratch.FolderManager {
122122
return menu;
123123
}
124124

125-
protected Gtk.MenuItem create_submenu_for_open_in (GLib.FileInfo? info, string? file_type) {
126-
var other_menuitem = new Gtk.MenuItem.with_label (_("Other Application…"));
127-
other_menuitem.activate.connect (() => show_app_chooser (file));
125+
protected Gtk.MenuItem create_open_in_menuitem (GLib.FileInfo? info, string? file_type) {
126+
Gtk.MenuItem open_in_item = null;
128127

129-
file_type = file_type ?? "inode/directory";
128+
if (in_sandbox) {
129+
open_in_item = new Gtk.MenuItem.with_label (_("Open In…"));
130+
open_in_item.activate.connect (() => show_app_chooser (file));
131+
} else {
132+
var other_menuitem = new Gtk.MenuItem.with_label (_("Other Application…"));
133+
other_menuitem.activate.connect (() => show_app_chooser (file));
130134

131-
var open_in_menu = new Gtk.Menu ();
135+
file_type = file_type ?? "inode/directory";
132136

133-
if (info != null) {
134-
List<AppInfo> external_apps = GLib.AppInfo.get_all_for_type (file_type);
137+
var open_in_menu = new Gtk.Menu ();
135138

136-
string this_id = GLib.Application.get_default ().application_id + ".desktop";
139+
if (info != null) {
140+
List<AppInfo> external_apps = GLib.AppInfo.get_all_for_type (file_type);
137141

138-
foreach (AppInfo app_info in external_apps) {
139-
if (app_info.get_id () == this_id) {
140-
continue;
141-
}
142+
string this_id = GLib.Application.get_default ().application_id + ".desktop";
143+
144+
foreach (AppInfo app_info in external_apps) {
145+
if (app_info.get_id () == this_id) {
146+
continue;
147+
}
142148

143-
var menuitem_icon = new Gtk.Image.from_gicon (app_info.get_icon (), Gtk.IconSize.MENU);
144-
menuitem_icon.pixel_size = 16;
149+
var menuitem_icon = new Gtk.Image.from_gicon (app_info.get_icon (), Gtk.IconSize.MENU);
150+
menuitem_icon.pixel_size = 16;
145151

146-
var menuitem_grid = new Gtk.Grid ();
147-
menuitem_grid.add (menuitem_icon);
148-
menuitem_grid.add (new Gtk.Label (app_info.get_name ()));
152+
var menuitem_grid = new Gtk.Grid ();
153+
menuitem_grid.add (menuitem_icon);
154+
menuitem_grid.add (new Gtk.Label (app_info.get_name ()));
149155

150-
var item_app = new Gtk.MenuItem ();
151-
item_app.add (menuitem_grid);
156+
var item_app = new Gtk.MenuItem ();
157+
item_app.add (menuitem_grid);
152158

153-
item_app.activate.connect (() => {
154-
launch_app_with_file (app_info, file.file);
155-
});
156-
open_in_menu.add (item_app);
159+
item_app.activate.connect (() => {
160+
launch_app_with_file (app_info, file.file);
161+
});
162+
open_in_menu.add (item_app);
163+
}
157164
}
158-
}
159165

160-
if (open_in_menu.get_children ().length () > 0) {
161-
open_in_menu.add (new Gtk.SeparatorMenuItem ());
162-
}
166+
if (open_in_menu.get_children ().length () > 0) {
167+
open_in_menu.add (new Gtk.SeparatorMenuItem ());
168+
}
163169

164-
open_in_menu.add (other_menuitem);
170+
open_in_menu.add (other_menuitem);
165171

166-
var open_in_item = new Gtk.MenuItem.with_label (_("Open In"));
167-
open_in_item.submenu = open_in_menu;
172+
open_in_item = new Gtk.MenuItem.with_label (_("Open In"));
173+
open_in_item.submenu = open_in_menu;
174+
}
168175

169176
return open_in_item;
170177
}

src/FolderManager/Item.vala

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,30 @@ namespace Scratch.FolderManager {
6969
}
7070

7171
public void show_app_chooser (File file) {
72-
var dialog = new Gtk.AppChooserDialog (new Gtk.Window (), Gtk.DialogFlags.MODAL, file.file);
73-
dialog.deletable = false;
74-
75-
if (dialog.run () == Gtk.ResponseType.OK) {
76-
var app_info = dialog.get_app_info ();
77-
if (app_info != null) {
78-
launch_app_with_file (app_info, file.file);
72+
if (in_sandbox) {
73+
var portal = ((Scratch.Application) GLib.Application.get_default ()).portal;
74+
var parent = new Xdp.Gtk3.Parent (((Gtk.Application) GLib.Application.get_default ()).active_window);
75+
76+
portal.open_uri.begin (parent, file.file.get_uri (), Xdp.OpenUriFlags.ASK, null, (obj, res) => {
77+
try {
78+
portal.open_uri.end (res);
79+
} catch (Error e) {
80+
warning (e.message);
81+
}
82+
});
83+
} else {
84+
var dialog = new Gtk.AppChooserDialog (new Gtk.Window (), Gtk.DialogFlags.MODAL, file.file);
85+
dialog.deletable = false;
86+
87+
if (dialog.run () == Gtk.ResponseType.OK) {
88+
var app_info = dialog.get_app_info ();
89+
if (app_info != null) {
90+
launch_app_with_file (app_info, file.file);
91+
}
7992
}
80-
}
8193

82-
dialog.destroy ();
94+
dialog.destroy ();
95+
}
8396
}
8497

8598
public void launch_app_with_file (AppInfo app_info, GLib.File file) {

src/FolderManager/ProjectFolderItem.vala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ namespace Scratch.FolderManager {
131131
}
132132

133133
var menu = new Gtk.Menu ();
134-
menu.append (create_submenu_for_open_in (info, file_type));
134+
menu.append (create_open_in_menuitem (info, file_type));
135135
menu.append (new Gtk.SeparatorMenuItem ());
136136
menu.append (create_submenu_for_new ());
137137

0 commit comments

Comments
 (0)