[Xfce4-commits] [panel-plugins/xfce4-whiskermenu-plugin] 218/473: Defer loading applications until window is shown.
noreply at xfce.org
noreply at xfce.org
Mon Feb 16 23:56:28 CET 2015
This is an automated email from the git hooks/post-receive script.
gottcode pushed a commit to branch master
in repository panel-plugins/xfce4-whiskermenu-plugin.
commit 88b811937ace62cb7d35f1f202d5003042b79e68
Author: Graeme Gott <graeme at gottcode.org>
Date: Sun Nov 3 18:48:22 2013 -0500
Defer loading applications until window is shown.
---
panel-plugin/applications-page.cpp | 172 +++++++++++++++++++++++-------------
panel-plugin/applications-page.h | 19 +++-
panel-plugin/window.cpp | 47 +++++++---
panel-plugin/window.h | 6 ++
4 files changed, 172 insertions(+), 72 deletions(-)
diff --git a/panel-plugin/applications-page.cpp b/panel-plugin/applications-page.cpp
index 275d86b..36ea47e 100644
--- a/panel-plugin/applications-page.cpp
+++ b/panel-plugin/applications-page.cpp
@@ -30,10 +30,20 @@ using namespace WhiskerMenu;
//-----------------------------------------------------------------------------
+enum
+{
+ STATUS_INVALID,
+ STATUS_LOADING,
+ STATUS_LOADED
+};
+
+//-----------------------------------------------------------------------------
+
ApplicationsPage::ApplicationsPage(Window* window) :
Page(window),
m_garcon_menu(NULL),
- m_loaded(false)
+ m_load_thread(NULL),
+ m_load_status(STATUS_INVALID)
{
// Set desktop environment for applications
const gchar* desktop = g_getenv("XDG_CURRENT_DESKTOP");
@@ -52,6 +62,12 @@ ApplicationsPage::ApplicationsPage(Window* window) :
ApplicationsPage::~ApplicationsPage()
{
+ if (m_load_thread)
+ {
+ g_thread_join(m_load_thread);
+ m_load_thread = NULL;
+ }
+
clear_applications();
}
@@ -98,62 +114,40 @@ void ApplicationsPage::apply_filter(GtkToggleButton* togglebutton)
void ApplicationsPage::invalidate_applications()
{
- m_loaded = false;
+ m_load_status = STATUS_INVALID;
}
//-----------------------------------------------------------------------------
-void ApplicationsPage::load_applications()
+bool ApplicationsPage::load_applications()
{
- if (m_loaded)
+ // Check if already loaded
+ if (m_load_status == STATUS_LOADED)
{
- return;
+ return false;
}
-
- // Remove previous menu data
- clear_applications();
-
- // Populate map of menu data
- m_garcon_menu = garcon_menu_new_applications();
- if (garcon_menu_load(m_garcon_menu, NULL, NULL))
+ // Check if currently loading
+ else if (m_load_status == STATUS_LOADING)
{
- g_signal_connect_swapped(m_garcon_menu, "reload-required", G_CALLBACK(ApplicationsPage::invalidate_applications_slot), this);
- load_menu(m_garcon_menu, NULL);
+ return true;
}
- else
+ // Check if loading garcon
+ else if (m_load_thread)
{
- return;
+ return true;
}
+ m_load_status = STATUS_LOADING;
- // Sort items and categories
- if (!wm_settings->load_hierarchy)
- {
- for (std::vector<Category*>::const_iterator i = m_categories.begin(), end = m_categories.end(); i != end; ++i)
- {
- (*i)->sort();
- }
- std::sort(m_categories.begin(), m_categories.end(), &Element::less_than);
- }
+ clear_applications();
- // Create all items category
- Category* category = new Category(NULL);
- for (std::map<std::string, Launcher*>::const_iterator i = m_items.begin(), end = m_items.end(); i != end; ++i)
+ // Load garcon menu in thread if possible
+ m_load_thread = g_thread_try_new(NULL, (GThreadFunc)&ApplicationsPage::load_garcon_menu_slot, this, NULL);
+ if (!m_load_thread)
{
- category->append_item(i->second);
+ load_garcon_menu();
}
- category->sort();
- m_categories.insert(m_categories.begin(), category);
-
- get_view()->set_fixed_height_mode(true);
- get_view()->set_model(category->get_model());
-
- // Update filters
- load_categories();
-
- // Update menu items of other panels
- get_window()->set_items();
- m_loaded = true;
+ return true;
}
//-----------------------------------------------------------------------------
@@ -197,6 +191,84 @@ void ApplicationsPage::clear_applications()
//-----------------------------------------------------------------------------
+void ApplicationsPage::load_garcon_menu()
+{
+ m_garcon_menu = garcon_menu_new_applications();
+
+ if (!garcon_menu_load(m_garcon_menu, NULL, NULL))
+ {
+ g_object_unref(m_garcon_menu);
+ m_garcon_menu = NULL;
+ }
+
+ g_idle_add((GSourceFunc)&ApplicationsPage::load_contents_slot, this);
+}
+
+//-----------------------------------------------------------------------------
+
+bool ApplicationsPage::load_contents()
+{
+ if (!m_garcon_menu)
+ {
+ get_window()->set_loaded();
+
+ m_load_status = STATUS_INVALID;
+ m_load_thread = NULL;
+
+ return false;
+ }
+
+ // Populate map of menu data
+ g_signal_connect_swapped(m_garcon_menu, "reload-required", G_CALLBACK(ApplicationsPage::invalidate_applications_slot), this);
+ load_menu(m_garcon_menu, NULL);
+
+ // Sort items and categories
+ if (!wm_settings->load_hierarchy)
+ {
+ for (std::vector<Category*>::const_iterator i = m_categories.begin(), end = m_categories.end(); i != end; ++i)
+ {
+ (*i)->sort();
+ }
+ std::sort(m_categories.begin(), m_categories.end(), &Element::less_than);
+ }
+
+ // Create all items category
+ Category* category = new Category(NULL);
+ for (std::map<std::string, Launcher*>::const_iterator i = m_items.begin(), end = m_items.end(); i != end; ++i)
+ {
+ category->append_item(i->second);
+ }
+ category->sort();
+ m_categories.insert(m_categories.begin(), category);
+
+ // Set all applications category
+ get_view()->set_fixed_height_mode(true);
+ get_view()->set_model(category->get_model());
+
+ // Add buttons for categories
+ std::vector<SectionButton*> category_buttons;
+ for (std::vector<Category*>::const_iterator i = m_categories.begin(), end = m_categories.end(); i != end; ++i)
+ {
+ SectionButton* category_button = (*i)->get_button();
+ g_signal_connect(category_button->get_button(), "toggled", G_CALLBACK(ApplicationsPage::apply_filter_slot), this);
+ category_buttons.push_back(category_button);
+ }
+
+ // Add category buttons to window
+ get_window()->set_categories(category_buttons);
+
+ // Update menu items of other panels
+ get_window()->set_items();
+ get_window()->set_loaded();
+
+ m_load_status = STATUS_LOADED;
+ m_load_thread = NULL;
+
+ return false;
+}
+
+//-----------------------------------------------------------------------------
+
void ApplicationsPage::load_menu(GarconMenu* menu, Category* parent_category)
{
GarconMenuDirectory* directory = garcon_menu_get_directory(menu);
@@ -287,21 +359,3 @@ void ApplicationsPage::load_menu_item(GarconMenuItem* menu_item, Category* categ
}
//-----------------------------------------------------------------------------
-
-void ApplicationsPage::load_categories()
-{
- std::vector<SectionButton*> category_buttons;
-
- // Add buttons for categories
- for (std::vector<Category*>::const_iterator i = m_categories.begin(), end = m_categories.end(); i != end; ++i)
- {
- SectionButton* category_button = (*i)->get_button();
- g_signal_connect(category_button->get_button(), "toggled", G_CALLBACK(ApplicationsPage::apply_filter_slot), this);
- category_buttons.push_back(category_button);
- }
-
- // Add category buttons to window
- get_window()->set_categories(category_buttons);
-}
-
-//-----------------------------------------------------------------------------
diff --git a/panel-plugin/applications-page.h b/panel-plugin/applications-page.h
index 5559508..7bcb0cb 100644
--- a/panel-plugin/applications-page.h
+++ b/panel-plugin/applications-page.h
@@ -47,22 +47,24 @@ public:
Launcher* get_application(const std::string& desktop_id) const;
void invalidate_applications();
- void load_applications();
+ bool load_applications();
void reload_category_icon_size();
private:
void apply_filter(GtkToggleButton* togglebutton);
bool on_filter(GtkTreeModel* model, GtkTreeIter* iter);
void clear_applications();
+ void load_garcon_menu();
+ bool load_contents();
void load_menu(GarconMenu* menu, Category* parent_category);
void load_menu_item(GarconMenuItem* menu_item, Category* category);
- void load_categories();
private:
GarconMenu* m_garcon_menu;
std::vector<Category*> m_categories;
std::map<std::string, Launcher*> m_items;
- bool m_loaded;
+ GThread* m_load_thread;
+ gint m_load_status;
private:
@@ -75,6 +77,17 @@ private:
{
obj->apply_filter(togglebutton);
}
+
+ static gpointer load_garcon_menu_slot(ApplicationsPage *obj)
+ {
+ obj->load_garcon_menu();
+ return NULL;
+ }
+
+ static gboolean load_contents_slot(ApplicationsPage* obj)
+ {
+ return obj->load_contents();
+ }
};
}
diff --git a/panel-plugin/window.cpp b/panel-plugin/window.cpp
index 01e5011..520166c 100644
--- a/panel-plugin/window.cpp
+++ b/panel-plugin/window.cpp
@@ -71,10 +71,25 @@ Window::Window() :
g_signal_connect(m_window, "map-event", G_CALLBACK(Window::on_map_event_slot), this);
g_signal_connect(m_window, "configure-event", G_CALLBACK(Window::on_configure_event_slot), this);
+ m_window_box = GTK_BOX(gtk_vbox_new(false, 0));
+ gtk_container_add(GTK_CONTAINER(m_window), GTK_WIDGET(m_window_box));
+
+ // Create loading message
+ m_window_load_contents = gtk_frame_new(NULL);
+ gtk_frame_set_shadow_type(GTK_FRAME(m_window_load_contents), GTK_SHADOW_OUT);
+ gtk_box_pack_start(m_window_box, m_window_load_contents, true, true, 0);
+
+ m_window_load_spinner = GTK_SPINNER(gtk_spinner_new());
+
+ GtkAlignment* alignment = GTK_ALIGNMENT(gtk_alignment_new(0.5, 0.5, 0.1, 0.1));
+ gtk_container_add(GTK_CONTAINER(alignment), GTK_WIDGET(m_window_load_spinner));
+
+ gtk_container_add(GTK_CONTAINER(m_window_load_contents), GTK_WIDGET(alignment));
+
// Create the border of the window
- GtkWidget* frame = gtk_frame_new(NULL);
- gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
- gtk_container_add(GTK_CONTAINER(m_window), frame);
+ m_window_contents = gtk_frame_new(NULL);
+ gtk_frame_set_shadow_type(GTK_FRAME(m_window_contents), GTK_SHADOW_OUT);
+ gtk_box_pack_start(m_window_box, m_window_contents, true, true, 0);
// Create the username label
const gchar* name = g_get_real_name();
@@ -142,7 +157,7 @@ Window::Window() :
// Create box for packing children
m_vbox = GTK_BOX(gtk_vbox_new(false, 6));
- gtk_container_add(GTK_CONTAINER(frame), GTK_WIDGET(m_vbox));
+ gtk_container_add(GTK_CONTAINER(m_window_contents), GTK_WIDGET(m_vbox));
gtk_container_set_border_width(GTK_CONTAINER(m_vbox), 2);
// Create box for packing commands
@@ -198,17 +213,14 @@ Window::Window() :
gtk_size_group_add_widget(sidebar_size_group, GTK_WIDGET(m_sidebar));
gtk_size_group_add_widget(sidebar_size_group, GTK_WIDGET(m_commands_align));
- // Populate app menu
- m_applications->load_applications();
-
// Show widgets
- gtk_widget_show_all(GTK_WIDGET(m_vbox));
+ gtk_widget_show_all(GTK_WIDGET(m_window_box));
gtk_widget_hide(m_favorites->get_widget());
gtk_widget_hide(m_recent->get_widget());
gtk_widget_hide(m_applications->get_widget());
gtk_widget_hide(m_search_results->get_widget());
m_default_button->set_active(true);
- gtk_widget_show(frame);
+ gtk_widget_hide(m_window_contents);
// Resize to last known size
gtk_window_set_default_size(m_window, m_geometry.width, m_geometry.height);
@@ -269,7 +281,12 @@ void Window::show(GtkWidget* parent, bool horizontal)
m_logout_button->check();
// Make sure applications list is current; does nothing unless list has changed
- m_applications->load_applications();
+ if (m_applications->load_applications())
+ {
+ gtk_widget_hide(m_window_contents);
+ gtk_widget_show(m_window_load_contents);
+ gtk_spinner_start(m_window_load_spinner);
+ }
// Reset mouse cursor by forcing default page to hide
gtk_widget_show(m_default_page->get_widget());
@@ -572,6 +589,16 @@ void Window::set_items()
//-----------------------------------------------------------------------------
+void Window::set_loaded()
+{
+ gtk_spinner_stop(m_window_load_spinner);
+ gtk_widget_hide(m_window_load_contents);
+ gtk_widget_show(m_window_contents);
+ gtk_widget_grab_focus(GTK_WIDGET(m_search_entry));
+}
+
+//-----------------------------------------------------------------------------
+
void Window::set_modified()
{
m_modified = true;
diff --git a/panel-plugin/window.h b/panel-plugin/window.h
index 45be561..da3200e 100644
--- a/panel-plugin/window.h
+++ b/panel-plugin/window.h
@@ -81,6 +81,7 @@ public:
void save();
void set_categories(const std::vector<SectionButton*>& categories);
void set_items();
+ void set_loaded();
void set_modified();
void unset_items();
@@ -103,6 +104,11 @@ private:
private:
GtkWindow* m_window;
+ GtkBox* m_window_box;
+ GtkWidget* m_window_contents;
+ GtkSpinner* m_window_load_spinner;
+ GtkWidget* m_window_load_contents;
+
GtkBox* m_vbox;
GtkBox* m_title_box;
GtkBox* m_commands_box;
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the Xfce4-commits
mailing list