Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add context menu #182

Merged
merged 8 commits into from
Nov 10, 2023
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
74 changes: 60 additions & 14 deletions src/Launcher.vala
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ public class Dock.Launcher : Gtk.Button {

private static Gtk.CssProvider css_provider;

private Gtk.PopoverMenu popover;

public Launcher (GLib.DesktopAppInfo app_info) {
Object (app_info: app_info);
}
Expand All @@ -28,6 +30,32 @@ public class Dock.Launcher : Gtk.Button {
windows = new GLib.List<AppWindow> ();
get_style_context ().add_provider (css_provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);

var action_section = new Menu ();
foreach (var action in app_info.list_actions ()) {
action_section.append (
app_info.get_action_name (action),
MainWindow.ACTION_PREFIX + MainWindow.LAUNCHER_ACTION_TEMPLATE.printf (app_info.get_id (), action)
);
}

var pinned_section = new Menu ();
pinned_section.append (
_("Keep in Dock"),
MainWindow.ACTION_PREFIX + MainWindow.LAUNCHER_PINNED_ACTION_TEMPLATE.printf (app_info.get_id ())
);

var model = new Menu ();
if (action_section.get_n_items () > 0) {
model.append_section (null, action_section);
}
model.append_section (null, pinned_section);

popover = new Gtk.PopoverMenu.from_model (model) {
autohide = true,
position = TOP
};
popover.set_parent (this);

var image = new Gtk.Image () {
gicon = app_info.get_icon ()
};
Expand All @@ -36,33 +64,51 @@ public class Dock.Launcher : Gtk.Button {
child = image;
tooltip_text = app_info.get_display_name ();

clicked.connect (() => {
try {
add_css_class ("bounce");
notify["pinned"].connect (() => ((MainWindow) get_root ()).sync_pinned ());

var context = Gdk.Display.get_default ().get_app_launch_context ();
context.set_timestamp (Gdk.CURRENT_TIME);
var gesture_click = new Gtk.GestureClick () {
button = Gdk.BUTTON_SECONDARY
};
add_controller (gesture_click);
gesture_click.released.connect (popover.popup);

clicked.connect (() => launch ());
}

~Launcher () {
popover.unparent ();
popover.dispose ();
}

public void launch (string? action = null) {
try {
add_css_class ("bounce");

var context = Gdk.Display.get_default ().get_app_launch_context ();
context.set_timestamp (Gdk.CURRENT_TIME);

if (action != null) {
app_info.launch_action (action, context);
} else {
app_info.launch (null, context);
} catch (Error e) {
critical (e.message);
}
Timeout.add (400, () => {
remove_css_class ("bounce");
} catch (Error e) {
critical (e.message);
}

return Source.REMOVE;
});
Timeout.add (400, () => {
remove_css_class ("bounce");

return Source.REMOVE;
});
}

public void update_windows (owned GLib.List<AppWindow>? new_windows) {
if (new_windows == null) {
windows = new GLib.List<AppWindow> ();
return;
} else {
windows = (owned) new_windows;
}

windows = (owned) new_windows;
}

public AppWindow? find_window (uint64 window_uid) {
Expand Down
64 changes: 59 additions & 5 deletions src/MainWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@
*/

public class Dock.MainWindow : Gtk.ApplicationWindow {
// First %s is the app id second %s the action name
public const string LAUNCHER_ACTION_TEMPLATE = "%s.%s";
// %s is the app id
public const string LAUNCHER_PINNED_ACTION_TEMPLATE = "%s-pinned";
public const string ACTION_GROUP_PREFIX = "win";
public const string ACTION_PREFIX = ACTION_GROUP_PREFIX + ".";

private static Gtk.CssProvider css_provider;

private Gtk.Box box;
Expand Down Expand Up @@ -67,6 +74,22 @@ public class Dock.MainWindow : Gtk.ApplicationWindow {
unowned var app_id = app_info.get_id ();
app_to_launcher.insert (app_id, launcher);
box.append (launcher);

var pinned_action = new SimpleAction.stateful (
LAUNCHER_PINNED_ACTION_TEMPLATE.printf (app_id),
null,
new Variant.boolean (launcher.pinned)
);
launcher.notify["pinned"].connect (() => pinned_action.set_state (launcher.pinned));
pinned_action.change_state.connect ((new_state) => launcher.pinned = (bool) new_state);
add_action (pinned_action);

foreach (var action in app_info.list_actions ()) {
var simple_action = new SimpleAction (LAUNCHER_ACTION_TEMPLATE.printf (app_id, action), null);
simple_action.activate.connect (() => launcher.launch (action));
add_action (simple_action);
}

return app_to_launcher[app_id];
}

Expand Down Expand Up @@ -110,14 +133,45 @@ public class Dock.MainWindow : Gtk.ApplicationWindow {
app_to_launcher.foreach_remove ((app_id, launcher) => {
var window_list = launcher_window_list.take (launcher);
launcher.update_windows ((owned) window_list);
if (launcher.windows.is_empty ()) {
if (!launcher.pinned) {
launcher.unparent ();
return true;
}
if (launcher.windows.is_empty () && !launcher.pinned) {
remove_launcher (launcher, false);
return true;
}

return false;
});
}

public void remove_launcher (Launcher launcher, bool from_map = true) {
foreach (var action in list_actions ()) {
if (action.has_prefix (launcher.app_info.get_id ())) {
remove_action (action);
}
}
box.remove (launcher);

if (from_map) {
app_to_launcher.remove (launcher.app_info.get_id ());
}
}

public void sync_pinned () {
string[] new_pinned_ids = {};

unowned Launcher child = (Launcher) box.get_first_child ();
while (child != null) {
unowned var current_child = child;
child = (Launcher) child.get_next_sibling ();

if (current_child.pinned) {
new_pinned_ids += current_child.app_info.get_id ();
} else if (!current_child.pinned && current_child.windows.is_empty ()) {
remove_launcher (current_child);
}
}


var settings = new Settings ("io.elementary.dock");
settings.set_strv ("launchers", new_pinned_ids);
}
}