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

Icon load time optimization #71

Merged
merged 2 commits into from
May 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
33 changes: 31 additions & 2 deletions src/DialogWindow.vala
Original file line number Diff line number Diff line change
Expand Up @@ -103,14 +103,23 @@ namespace Ilia {
return true;
}
}
if (key.keyval == KEY_CODE_PLUS) { // Expand dialog
if (key.keyval == '+') { // Expand dialog
change_size(128);
return true;
}
if (key.keyval == KEY_CODE_MINUS) { // Contract dialog
if (key.keyval == '-') { // Contract dialog
change_size(-128);
return true;
}
} else if ((key.state & Gdk.ModifierType.CONTROL_MASK) == Gdk.ModifierType.CONTROL_MASK) {
if (key.keyval == 'c') { // Expand dialog
clipboard_copy();
return true;
}
if (key.keyval== 'v') {
clipboard_paste();
return true;
}
}

bool key_handled = false;
Expand Down Expand Up @@ -399,6 +408,26 @@ namespace Ilia {
dialog_pages[active_page].on_entry_activated ();
}

void clipboard_copy() {
var display = this.get_screen ().get_display ();
var clipboard = Clipboard.get_for_display (display, Gdk.SELECTION_CLIPBOARD);

clipboard.set_text(entry.get_text(), entry.get_text().length);
clipboard.store();
}

void clipboard_paste() {
var display = this.get_screen ().get_display ();
var clipboard = Clipboard.get_for_display (display, Gdk.SELECTION_CLIPBOARD);

string text = clipboard.wait_for_text ();

if (text != null) {
int pos = entry.cursor_position;
entry.get_buffer().insert_text(pos, text.data);
}
}

public void quit() {
if (seat != null) seat.ungrab ();
hide ();
Expand Down
2 changes: 1 addition & 1 deletion src/IconLoader.vala
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ namespace Ilia {
try {
return new Gdk.Pixbuf.from_file_at_size (icon_name, size, size);
} catch (Error e) {
stderr.printf ("1Error loading icon: %s\n", e.message);
stderr.printf ("Error loading icon: %s\n", e.message);
}
}
}
Expand Down
68 changes: 49 additions & 19 deletions src/apps/DesktopAppPage.vala
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ namespace Ilia {

private Gtk.TreePath path;

private Thread<void> iconLoadThread;

public string get_name () {
return "<u>A</u>pplications";
}
Expand Down Expand Up @@ -98,6 +100,9 @@ namespace Ilia {
scrolled.expand = true;

root_widget = scrolled;

// Load app icons in background thread
iconLoadThread = new Thread<void> ("iconLoadThread", loadAppIcons);
}

public Gtk.Widget get_root () {
Expand Down Expand Up @@ -165,6 +170,9 @@ namespace Ilia {

// filter selection based on contents of Entry
void on_entry_changed () {
// Cause resorting
// TODO: find cleaner way of causing re-sort
model.set_sort_func (1, app_sort_func);
filter.refilter ();
set_selection ();
}
Expand All @@ -177,23 +185,28 @@ namespace Ilia {
}

private int app_sort_func (TreeModel model, TreeIter a, TreeIter b) {
string query_string = entry.get_text ().down ().strip ();
string query_string = entry.get_text ().down ();
DesktopAppInfo app_a;
model.@get (a, ITEM_VIEW_COLUMN_APPINFO, out app_a);
DesktopAppInfo app_b;
model.@get (b, ITEM_VIEW_COLUMN_APPINFO, out app_b);

var app_a_has_prefix = app_a.get_name ().down ().has_prefix (query_string);
var app_b_has_prefix = app_b.get_name ().down ().has_prefix (query_string);
var app_a_name = app_a.get_name ().down ();
var app_b_name = app_b.get_name ().down ();

if (query_string.length > 1 && (app_a_has_prefix || app_b_has_prefix)) {
if (app_b_has_prefix && !app_b_has_prefix) {
// stdout.printf ("boosted %s\n", app_a.get_name ());
return -1;
} else if (!app_a_has_prefix && app_b_has_prefix) {
// stdout.printf ("boosted %s\n", app_b.get_name ());
return 1;
}
if (query_string.length > 0) {
var app_a_has_prefix = app_a_name.has_prefix (query_string);
var app_b_has_prefix = app_b_name.has_prefix (query_string);

if (query_string.length > 1 && (app_a_has_prefix || app_b_has_prefix)) {
if (app_b_has_prefix && !app_b_has_prefix) {
// stdout.printf ("boosted %s for %s\n", app_a.get_name (), query_string);
return -1;
} else if (!app_a_has_prefix && app_b_has_prefix) {
// stdout.printf ("boosted %s for %s\n", app_b.get_name (), query_string);
return 1;
}
}
}

var a_count = launch_counts.get (app_a.get_id ());
Expand All @@ -209,7 +222,7 @@ namespace Ilia {
}
}

return app_a.get_name ().ascii_casecmp (app_b.get_name ());
return app_a_name.ascii_casecmp (app_b_name);
}

private HashTable<string, int> load_launch_counts (string[] history) {
Expand Down Expand Up @@ -258,27 +271,25 @@ namespace Ilia {
// var start_time = get_monotonic_time();
// determine theme for icons
icon_theme = Gtk.IconTheme.get_default ();
// Set a blank icon to avoid visual jank as real icons are loaded
Gdk.Pixbuf blank_icon = new Gdk.Pixbuf (Gdk.Colorspace.RGB, false, 8, icon_size, icon_size);

var app_list = AppInfo.get_all ();
foreach (AppInfo appinfo in app_list) {
read_desktop_file(appinfo);
read_desktop_file(appinfo, blank_icon);
}
// stdout.printf("time cost: %" + int64.FORMAT + "\n", (get_monotonic_time() - start_time));
}

private void read_desktop_file (AppInfo appInfo) {
private void read_desktop_file (AppInfo appInfo, Gdk.Pixbuf? icon_img) {
DesktopAppInfo app_info = new DesktopAppInfo (appInfo.get_id ());

if (app_info != null && app_info.should_show ()) {
model.append (out iter);

var keywords = app_info.get_string ("Comment") + app_info.get_string ("Keywords");

Gdk.Pixbuf icon_img = null;

if (icon_size > 0) {
icon_img = Ilia.load_icon_from_info (icon_theme, app_info, icon_size);

if (icon_size > 0) {
model.set (
iter,
ITEM_VIEW_COLUMN_ICON, icon_img,
Expand All @@ -297,6 +308,25 @@ namespace Ilia {
}
}

// Iterate over model and load icons
void loadAppIcons() {
// stdout.printf("loadAppIcons start: %" + int64.FORMAT + "\n", (get_monotonic_time() - start_time));
TreeIter app_iter;
Value app_info_val;

for (bool next = model.get_iter_first (out app_iter); next; next = model.iter_next (ref app_iter)) {
model.get_value(app_iter, ITEM_VIEW_COLUMN_APPINFO, out app_info_val);

Gdk.Pixbuf icon = Ilia.load_icon_from_info (icon_theme, (DesktopAppInfo) app_info_val, icon_size);

model.set (
app_iter,
ITEM_VIEW_COLUMN_ICON, icon
);
}
// stdout.printf("loadAppIcons end : %" + int64.FORMAT + "\n", (get_monotonic_time() - start_time));
}

// In the case that neither success or failure signals are received, exit after a timeout
private async void launch_failure_exit() {
GLib.Timeout.add (post_launch_sleep, () => {
Expand Down