Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
- name: Install Dependencies
run: |
apt update
apt install -y libgranite-7-dev libgtk-4-dev libpantheon-wayland-1-dev meson valac
apt install -y libaccountsservice-dev libadwaita-1-dev libgranite-7-dev libgtk-4-dev libpantheon-wayland-1-dev meson valac
- name: Build
run: |
meson build
Expand Down
5 changes: 5 additions & 0 deletions data/Application.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,8 @@
.dialog toolbox .bottom button {
min-width: 5em;
}

.flat avatar {
border: none;
box-shadow: none;
}
3 changes: 3 additions & 0 deletions data/gresource.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
<file compressed="true">Application.css</file>
</gresource>
<gresource prefix="/io/elementary/xdg-desktop-portal-pantheon/icons">
<file alias="48x48/emblems/emblem-portal-account.svg" compressed="true" preprocess="xml-stripblanks">icons/account.svg</file>
<file alias="48x48@2/emblems/emblem-portal-account.svg" compressed="true" preprocess="xml-stripblanks">icons/account.svg</file>

<file alias="48x48/emblems/emblem-portal-screencast.svg" compressed="true" preprocess="xml-stripblanks">icons/screencast.svg</file>
<file alias="48x48@2/emblems/emblem-portal-screencast.svg" compressed="true" preprocess="xml-stripblanks">icons/screencast.svg</file>

Expand Down
42 changes: 42 additions & 0 deletions data/icons/account.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion data/pantheon.portal
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[portal]
DBusName=org.freedesktop.impl.portal.desktop.pantheon
Interfaces=org.freedesktop.impl.portal.Access;org.freedesktop.impl.portal.AppChooser;org.freedesktop.impl.portal.Background;org.freedesktop.impl.portal.Screenshot;org.freedesktop.impl.portal.Wallpaper;org.freedesktop.impl.portal.ScreenCast
Interfaces=org.freedesktop.impl.portal.Access;org.freedesktop.impl.portal.Account;org.freedesktop.impl.portal.AppChooser;org.freedesktop.impl.portal.Background;org.freedesktop.impl.portal.Screenshot;org.freedesktop.impl.portal.Wallpaper;org.freedesktop.impl.portal.ScreenCast
UseIn=pantheon
2 changes: 2 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ localedir = prefix / get_option('localedir')

systemd_dep = dependency('systemd')

act_dep = dependency('accountsservice')
adw_dep = dependency('libadwaita-1')
glib_dep = dependency('glib-2.0')
gobject_dep = dependency('gobject-2.0')
gio_dep = dependency('gio-2.0')
Expand Down
2 changes: 2 additions & 0 deletions po/POTFILES
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ src/XdgDesktopPortalPantheon.vala
src/ExternalWindow.vala
src/Access/Portal.vala
src/Access/Dialog.vala
src/Account/Dialog.vala
src/Account/Portal.vala
src/AppChooser/Portal.vala
src/AppChooser/Dialog.vala
src/AppChooser/AppButton.vala
Expand Down
17 changes: 6 additions & 11 deletions src/Access/Portal.vala
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,10 @@ public class Access.Portal : Object {
}

var _results = new HashTable<string, Variant> (str_hash, str_equal);
var _response = 2;
uint32 _response = 2;

dialog.response.connect ((id) => {
switch (id) {
dialog.response.connect ((response) => {
switch (response) {
case ALLOW:
var choices_builder = new VariantBuilder (new VariantType ("a(ss)"));

Expand All @@ -81,18 +81,13 @@ public class Access.Portal : Object {
});

_results["choices"] = choices_builder.end ();
_response = 0;
break;

case CANCEL:
_response = 1;
break;

case DELETE_EVENT:
_response = 2;
default:
break;
}

_response = response.to_id ();

access_dialog.callback ();
});

Expand Down
108 changes: 108 additions & 0 deletions src/Account/Dialog.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* SPDX-FileCopyrigthText: 2026 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: LGPL-2.1-or-later
*/

[DBus (name = "org.freedesktop.impl.portal.Request")]
public class Account.Dialog : PortalDialog {
// The ID used to register this dialog on the DBusConnection
public uint register_id { get; set; default = 0; }

// The ID of the app sending the request
public string app_id { get; construct; }

public string user_name;
public string image_filename;
public string real_name;

private Adw.Avatar avatar;

public string reason {
set {
secondary_text = _("It provided the following reason, “%s”").printf (value);
}
}

public Dialog (string app_id) {
Object (app_id: app_id);
}

construct {
default_height = -1;
title = _("An application wants to access your name and photo");
secondary_icon = new ThemedIcon ("emblem-portal-account");
secondary_text = _("It did not provide a reason for this request.");

if (app_id != "") {
var app_info = new DesktopAppInfo (app_id + ".desktop");
if (app_info != null) {
primary_icon = app_info.get_icon ();
title = _("“%s” wants to access your name and photo").printf (app_info.get_display_name ());
}
}

user_name = Environment.get_user_name ();
real_name = Environment.get_real_name ();

avatar = new Adw.Avatar (32, null, false);
avatar.add_css_class (Granite.STYLE_CLASS_FLAT);

var username_label = new Gtk.Label (user_name) {
halign = START
};
username_label.add_css_class (Granite.CssClass.DIM);
username_label.add_css_class (Granite.CssClass.SMALL);

var name_box = new Granite.Box (VERTICAL, NONE) {
valign = CENTER
};
name_box.append (new Gtk.Label (real_name));
name_box.append (username_label);

var box = new Granite.Box (HORIZONTAL, SINGLE);
box.append (avatar);
box.append (name_box);

var listitem = new Granite.ListItem () {
child = box,
margin_top = 12,
margin_end = 12,
margin_bottom = 12,
margin_start = 12
};
listitem.add_css_class (Granite.CssClass.CARD);

content = listitem;

var usermanager = Act.UserManager.get_default ();
if (usermanager.is_loaded) {
on_usermanager_loaded (usermanager);
} else {
usermanager.notify["is-loaded"].connect (() => on_usermanager_loaded (usermanager));
}
}

private void on_usermanager_loaded (Act.UserManager usermanager) {
var user = usermanager.get_user (user_name);
if (user.is_loaded) {
on_user_loaded (user);
} else {
user.notify["is-loaded"].connect (() => on_user_loaded (user));
}

}

private void on_user_loaded (Act.User user) {
image_filename = user.get_icon_file ();
try {
avatar.custom_image = Gdk.Texture.from_filename (image_filename);
} catch {
debug ("unable to set avatar");
}
}

[DBus (name = "Close")]
public void on_close () throws DBusError, IOError {
response (DELETE_EVENT);
}
}
65 changes: 65 additions & 0 deletions src/Account/Portal.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* SPDX-FileCopyrigthText: 2026 elementary, Inc. (https://elementary.io)
* SPDX-License-Identifier: LGPL-2.1-or-later
*/

[DBus (name = "org.freedesktop.impl.portal.Account")]
public class Account.Portal : Object {
private DBusConnection connection;

public Portal (DBusConnection connection) {
this.connection = connection;
}

[DBus (name = "GetUserInformation")]
public async void get_user_information (
ObjectPath handle,
string app_id,
string parent_window,
HashTable<string, Variant> options,
out uint response,
out HashTable<string, Variant> results
) throws DBusError, IOError {
var dialog = new Dialog (app_id) {
parent_handle = parent_window
};

if ("reason" in options) {
dialog.reason = options["reason"].get_string ();
}

try {
dialog.register_id = connection.register_object<Dialog> (handle, dialog);
} catch (Error e) {
critical (e.message);
}

var _results = new HashTable<string, Variant> (str_hash, str_equal);
uint _response = 2;

dialog.response.connect ((response) => {
switch (response) {
case ALLOW:
_results["id"] = dialog.user_name;
_results["name"] = dialog.real_name;
_results["image"] = Filename.to_uri (dialog.image_filename);
break;
default:
break;
}

_response = response.to_id ();

get_user_information.callback ();
});

dialog.present ();
yield;

connection.unregister_object (dialog.register_id);
dialog.destroy ();

results = _results;
response = _response;
}
}
15 changes: 14 additions & 1 deletion src/PortalDialog.vala
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,20 @@ public class PortalDialog : Gtk.Window, PantheonWayland.ExtendedBehavior {
public enum ResponseType {
ALLOW,
CANCEL,
DELETE_EVENT
DELETE_EVENT;

// Convert to response ID expected by portal backends
public uint32 to_id () {
switch (this) {
case ALLOW:
return 0;
case CANCEL:
return 1;
default:
case DELETE_EVENT:
return 2;
}
}
}

/**
Expand Down
3 changes: 3 additions & 0 deletions src/XdgDesktopPortalPantheon.vala
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ private void on_bus_acquired (DBusConnection connection, string name) {
connection.register_object ("/org/freedesktop/portal/desktop", new Access.Portal (connection));
debug ("Access Portal registered!");

connection.register_object ("/org/freedesktop/portal/desktop", new Account.Portal (connection));
debug ("Account Portal registered!");

connection.register_object ("/org/freedesktop/portal/desktop", new AppChooser.Portal (connection));
debug ("AppChooser Portal registered!");

Expand Down
4 changes: 4 additions & 0 deletions src/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ executable(
'Access/Choice.vala',
'Access/Dialog.vala',
'Access/Portal.vala',
'Account' / 'Dialog.vala',
'Account' / 'Portal.vala',
'AppChooser/AppButton.vala',
'AppChooser/Dialog.vala',
'AppChooser/Portal.vala',
Expand All @@ -26,6 +28,8 @@ executable(
'XdgDesktopPortalPantheon.vala',
icon_res,
dependencies: [
act_dep,
adw_dep,
glib_dep,
gobject_dep,
gio_dep,
Expand Down
Loading