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
1 change: 0 additions & 1 deletion po/POTFILES
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ src/Views/GridView.vala
src/Views/SearchView.vala

src/Widgets/AppButton.vala
src/Widgets/AppContextMenu.vala
src/Widgets/PageChecker.vala
src/Widgets/SearchItem.vala
src/Widgets/Switcher.vala
Expand Down
204 changes: 204 additions & 0 deletions src/Backend/App.vala
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@ public class Slingshot.Backend.App : Object {
SYNAPSE
}

public const string ACTION_GROUP_PREFIX = "app-actions";
private const string ACTION_PREFIX = ACTION_GROUP_PREFIX + ".";
private const string APP_ACTION = "action.%s";
private const string PINNED_ACTION = "pinned";
private const string SWITCHEROO_ACTION = "switcheroo";
private const string UNINSTALL_ACTION = "uninstall";
private const string VIEW_ACTION = "view-in-appcenter";

public SimpleActionGroup action_group { get; private set; }
public string name { get; construct set; }
public string description { get; private set; default = ""; }
public string desktop_id { get; construct set; }
Expand All @@ -49,6 +58,12 @@ public class Slingshot.Backend.App : Object {
public Synapse.Match? target { get; private set; default = null; }

private Slingshot.Backend.SwitcherooControl switcheroo_control;
private GLib.SimpleAction pinned_action;
private GLib.SimpleAction uninstall_action;
private GLib.SimpleAction view_action;

private bool has_system_item = false;
private string appstream_comp_id = "";

construct {
switcheroo_control = new Slingshot.Backend.SwitcherooControl ();
Expand Down Expand Up @@ -174,4 +189,193 @@ public class Slingshot.Backend.App : Object {
current_count = 0;
}
}

public GLib.Menu get_menu_model () {
var actions_section = new GLib.Menu ();
var shell_section = new GLib.Menu ();

action_group = new SimpleActionGroup ();

var app_info = new DesktopAppInfo (desktop_id);
foreach (unowned var action in app_info.list_actions ()) {
var simple_action = new SimpleAction (APP_ACTION.printf (action), null);
simple_action.activate.connect (() => {
var context = Gdk.Display.get_default ().get_app_launch_context ();
context.set_timestamp (Gdk.CURRENT_TIME);

app_info.launch_action (action, context);
launched (this);
});
action_group.add_action (simple_action);

actions_section.append (
app_info.get_action_name (action),
ACTION_PREFIX + APP_ACTION.printf (action)
);
}

if (switcheroo_control != null && switcheroo_control.has_dual_gpu) {
bool prefers_non_default_gpu = app_info.get_boolean ("PrefersNonDefaultGPU");

var switcheroo_action = new SimpleAction (SWITCHEROO_ACTION, null);
switcheroo_action.activate.connect (() => {
try {
var context = Gdk.Display.get_default ().get_app_launch_context ();
context.set_timestamp (Gdk.CURRENT_TIME);

switcheroo_control.apply_gpu_environment (context, prefers_non_default_gpu);

app_info.launch (null, context);
launched (this);
} catch (Error e) {
warning ("Failed to launch %s: %s", name, e.message);
}
});
action_group.add_action (switcheroo_action);

actions_section.append (
_("Open with %s Graphics").printf (switcheroo_control.get_gpu_name (prefers_non_default_gpu)),
ACTION_PREFIX + SWITCHEROO_ACTION
);
}

if (Environment.find_program_in_path ("io.elementary.dock") != null) {
has_system_item = true;

var dock = Backend.Dock.get_default ();
var pinned_variant = new Variant.boolean (false);
try {
pinned_variant = new Variant.boolean (desktop_id in dock.dbus.list_launchers ());
} catch (GLib.Error e) {
critical (e.message);
}

pinned_action = new SimpleAction.stateful (PINNED_ACTION, null, pinned_variant);
pinned_action.change_state.connect (pinned_action_change_state);

action_group.add_action (pinned_action);

shell_section.append (
_("Keep in _Dock"),
ACTION_PREFIX + PINNED_ACTION
);

dock.notify["dbus"].connect (() => on_dock_dbus_changed (dock));
on_dock_dbus_changed (dock);
}

if (Environment.find_program_in_path ("io.elementary.appcenter") != null) {
uninstall_action = new SimpleAction (UNINSTALL_ACTION, null);
uninstall_action.activate.connect (action_uninstall);

view_action = new SimpleAction (VIEW_ACTION, null);
view_action.activate.connect (open_in_appcenter);

action_group.add_action (uninstall_action);
action_group.add_action (view_action);

shell_section.append (
_("Uninstall"),
ACTION_PREFIX + UNINSTALL_ACTION
);

shell_section.append (
_("View in AppCenter"),
ACTION_PREFIX + VIEW_ACTION
);

var appcenter = Backend.AppCenter.get_default ();
appcenter.notify["dbus"].connect (() => on_appcenter_dbus_changed.begin (appcenter));
on_appcenter_dbus_changed.begin (appcenter);
}

var model = new GLib.Menu ();
model.append_section (null, actions_section);
model.append_section (null, shell_section);

return model;
}

private void action_uninstall () {
var appcenter = Backend.AppCenter.get_default ();
if (appcenter.dbus == null || appstream_comp_id == "") {
return;
}

launched (this);

appcenter.dbus.uninstall.begin (appstream_comp_id, (obj, res) => {
try {
appcenter.dbus.uninstall.end (res);
} catch (GLib.Error e) {
warning (e.message);
}
});
}

private void open_in_appcenter () {
AppInfo.launch_default_for_uri_async.begin ("appstream://" + appstream_comp_id, null, null, (obj, res) => {
try {
AppInfo.launch_default_for_uri_async.end (res);
} catch (Error error) {
var app_info = new DesktopAppInfo (desktop_id);
var message_dialog = new Granite.MessageDialog.with_image_from_icon_name (
"Unable to open %s in AppCenter".printf (app_info.get_display_name ()),
"",
"dialog-error",
Gtk.ButtonsType.CLOSE
);
message_dialog.show_error_details (error.message);
message_dialog.response.connect (message_dialog.destroy);
message_dialog.present ();
} finally {
launched (this);
}
});
}

private async void on_appcenter_dbus_changed (Backend.AppCenter appcenter) {
if (appcenter.dbus != null) {
try {
appstream_comp_id = yield appcenter.dbus.get_component_from_desktop_id (desktop_id);
} catch (GLib.Error e) {
appstream_comp_id = "";
warning (e.message);
}
} else {
appstream_comp_id = "";
}

uninstall_action.set_enabled (appstream_comp_id != "");
view_action.set_enabled (appstream_comp_id != "");
}

private void on_dock_dbus_changed (Backend.Dock dock) {
pinned_action.set_enabled (dock.dbus != null);

if (dock.dbus == null) {
return;
}

try {
pinned_action.change_state (new Variant.boolean (desktop_id in dock.dbus.list_launchers ()));
} catch (GLib.Error e) {
critical (e.message);
}
}

private void pinned_action_change_state (Variant? value) {
pinned_action.set_state (value);

try {
var dock = Backend.Dock.get_default ();
if (value.get_boolean ()) {
dock.dbus.add_launcher (desktop_id);
} else {
dock.dbus.remove_launcher (desktop_id);
}
} catch (GLib.Error e) {
critical (e.message);
}
}
}
10 changes: 4 additions & 6 deletions src/Views/CategoryView.vala
Original file line number Diff line number Diff line change
Expand Up @@ -155,12 +155,10 @@ public class Slingshot.Widgets.CategoryView : Gtk.EventBox {
private Gtk.Menu create_context_menu () {
var selected_row = (AppListRow) listbox.get_selected_row ();

var menu = new Slingshot.AppContextMenu (selected_row.app_id, selected_row.desktop_path);
menu.app_launched.connect (() => {
view.close_indicator ();
});
var context_menu = new Gtk.Menu.from_model (selected_row.app.get_menu_model ());
context_menu.insert_action_group (Backend.App.ACTION_GROUP_PREFIX, selected_row.app.action_group);

return menu;
return context_menu;
}

public void page_down () {
Expand Down Expand Up @@ -190,7 +188,7 @@ public class Slingshot.Widgets.CategoryView : Gtk.EventBox {
listbox.foreach ((app_list_row) => listbox.remove (app_list_row));

foreach (unowned Backend.App app in view.app_system.get_apps_by_name ()) {
listbox.add (new AppListRow (app.desktop_id, app.desktop_path));
listbox.add (new AppListRow (app));
}
listbox.show_all ();

Expand Down
2 changes: 2 additions & 0 deletions src/Views/SearchView.vala
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,8 @@ public class Slingshot.Widgets.SearchView : Gtk.Bin {
var search_item = new SearchItem (app, search_term, result_type);
app.start_search.connect ((search, target) => start_search (search, target));

app.launched.connect (() => app_launched ());

list_box.add (search_item);
search_item.show_all ();
}
Expand Down
12 changes: 7 additions & 5 deletions src/Widgets/AppButton.vala
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,7 @@ public class Slingshot.Widgets.AppButton : Gtk.Button {

child = box;

var context_menu = new Slingshot.AppContextMenu (app.desktop_id, app.desktop_path);
context_menu.app_launched.connect (() => {
app_launched ();
});
app.launched.connect (() => app_launched ());

this.clicked.connect (launch_app);

Expand All @@ -92,6 +89,8 @@ public class Slingshot.Widgets.AppButton : Gtk.Button {
var event = click_controller.get_last_event (sequence);

if (event.triggers_context_menu ()) {
var context_menu = new Gtk.Menu.from_model (app.get_menu_model ());
context_menu.insert_action_group (Backend.App.ACTION_GROUP_PREFIX, app.action_group);
context_menu.popup_at_pointer ();

click_controller.set_state (CLAIMED);
Expand All @@ -105,11 +104,15 @@ public class Slingshot.Widgets.AppButton : Gtk.Button {
switch (keyval) {
case Gdk.Key.F10:
if (mods == Gdk.ModifierType.SHIFT_MASK) {
var context_menu = new Gtk.Menu.from_model (app.get_menu_model ());
context_menu.insert_action_group (Backend.App.ACTION_GROUP_PREFIX, app.action_group);
context_menu.popup_at_widget (this, EAST, CENTER);
}
break;
case Gdk.Key.Menu:
case Gdk.Key.MenuKB:
var context_menu = new Gtk.Menu.from_model (app.get_menu_model ());
context_menu.insert_action_group (Backend.App.ACTION_GROUP_PREFIX, app.action_group);
context_menu.popup_at_widget (this, EAST, CENTER);
break;
default:
Expand Down Expand Up @@ -141,7 +144,6 @@ public class Slingshot.Widgets.AppButton : Gtk.Button {

public void launch_app () {
app.launch ();
app_launched ();
}

private void update_badge_count () {
Expand Down
Loading