diff options
| author | Neil Jagdish Patel <neil.patel@canonical.com> | 2010-12-15 17:49:31 +0000 |
|---|---|---|
| committer | Neil Jagdish Patel <neil.patel@canonical.com> | 2010-12-15 17:49:31 +0000 |
| commit | f7002672fe68fbc14f72dcd92f57082c8579ccb2 (patch) | |
| tree | e130352a9d55d129f601dfc9bcbcef0f39a37ef4 /src | |
| parent | 3c334f733bc2b6d0186f8e9587eee807357fc0bc (diff) | |
| parent | f7c5941bf0726cf999588dfc894708c450add15b (diff) | |
[merge] trunk
(bzr r669.3.9)
Diffstat (limited to 'src')
| -rw-r--r-- | src/BamfLauncherIcon.cpp | 325 | ||||
| -rw-r--r-- | src/BamfLauncherIcon.h | 27 | ||||
| -rw-r--r-- | src/FavoriteStore.h | 1 | ||||
| -rw-r--r-- | src/FavoriteStoreGSettings.cpp | 30 | ||||
| -rw-r--r-- | src/FavoriteStoreGSettings.h | 1 | ||||
| -rw-r--r-- | src/Launcher.cpp | 1011 | ||||
| -rw-r--r-- | src/Launcher.h | 144 | ||||
| -rw-r--r-- | src/LauncherController.cpp | 93 | ||||
| -rw-r--r-- | src/LauncherController.h | 2 | ||||
| -rw-r--r-- | src/LauncherDragWindow.cpp | 63 | ||||
| -rw-r--r-- | src/LauncherDragWindow.h | 50 | ||||
| -rw-r--r-- | src/LauncherIcon.cpp | 76 | ||||
| -rw-r--r-- | src/LauncherIcon.h | 24 | ||||
| -rw-r--r-- | src/LauncherModel.cpp | 10 | ||||
| -rw-r--r-- | src/LauncherModel.h | 6 | ||||
| -rw-r--r-- | src/PluginAdapter.cpp | 43 | ||||
| -rw-r--r-- | src/PluginAdapter.h | 15 | ||||
| -rw-r--r-- | src/QuicklistManager.cpp | 109 | ||||
| -rw-r--r-- | src/QuicklistManager.h | 52 | ||||
| -rw-r--r-- | src/QuicklistMenuItemRadio.cpp | 70 | ||||
| -rw-r--r-- | src/QuicklistMenuItemRadio.h | 13 | ||||
| -rw-r--r-- | src/QuicklistView.cpp | 125 | ||||
| -rw-r--r-- | src/QuicklistView.h | 13 | ||||
| -rw-r--r-- | src/SimpleLauncherIcon.h | 2 | ||||
| -rw-r--r-- | src/TrashLauncherIcon.cpp | 67 | ||||
| -rw-r--r-- | src/TrashLauncherIcon.h | 7 | ||||
| -rw-r--r-- | src/unity.cpp | 113 | ||||
| -rw-r--r-- | src/unity.h | 2 |
28 files changed, 1730 insertions, 764 deletions
diff --git a/src/BamfLauncherIcon.cpp b/src/BamfLauncherIcon.cpp index 252bcae5c..d376061dd 100644 --- a/src/BamfLauncherIcon.cpp +++ b/src/BamfLauncherIcon.cpp @@ -25,31 +25,52 @@ #include "FavoriteStore.h" #include <gio/gdesktopappinfo.h> - +#include <libindicator/indicator-desktop-shortcuts.h> #include <core/core.h> #include <core/atoms.h> +struct _ShortcutData +{ + BamfLauncherIcon *self; + IndicatorDesktopShortcuts *shortcuts; + char *nick; +}; +typedef struct _ShortcutData ShortcutData; +static void shortcut_data_destroy (ShortcutData *data) +{ + g_object_unref (data->shortcuts); + g_free (data->nick); + g_slice_free (ShortcutData, data); +} + +static void shortcut_activated (DbusmenuMenuitem* _sender, guint timestamp, gpointer userdata) +{ + ShortcutData *data = (ShortcutData *)userdata; + indicator_desktop_shortcuts_nick_exec (data->shortcuts, data->nick); +} + BamfLauncherIcon::BamfLauncherIcon (Launcher* IconManager, BamfApplication *app, CompScreen *screen) : SimpleLauncherIcon(IconManager) { m_App = app; m_Screen = screen; + _menu_desktop_shortcuts = NULL; char *icon_name = bamf_view_get_icon (BAMF_VIEW (m_App)); SetTooltipText (bamf_view_get_name (BAMF_VIEW (app))); SetIconName (icon_name); SetIconType (LAUNCHER_ICON_TYPE_APPLICATION); - + if (bamf_view_is_sticky (BAMF_VIEW (m_App))) SetQuirk (LAUNCHER_ICON_QUIRK_VISIBLE, true); else SetQuirk (LAUNCHER_ICON_QUIRK_VISIBLE, bamf_view_user_visible (BAMF_VIEW (m_App))); - + SetQuirk (LAUNCHER_ICON_QUIRK_ACTIVE, bamf_view_is_active (BAMF_VIEW (m_App))); SetQuirk (LAUNCHER_ICON_QUIRK_RUNNING, bamf_view_is_running (BAMF_VIEW (m_App))); - + g_free (icon_name); - + g_signal_connect (app, "child-removed", (GCallback) &BamfLauncherIcon::OnChildRemoved, this); g_signal_connect (app, "child-added", (GCallback) &BamfLauncherIcon::OnChildAdded, this); g_signal_connect (app, "urgent-changed", (GCallback) &BamfLauncherIcon::OnUrgentChanged, this); @@ -57,9 +78,9 @@ BamfLauncherIcon::BamfLauncherIcon (Launcher* IconManager, BamfApplication *app, g_signal_connect (app, "active-changed", (GCallback) &BamfLauncherIcon::OnActiveChanged, this); g_signal_connect (app, "user-visible-changed", (GCallback) &BamfLauncherIcon::OnUserVisibleChanged, this); g_signal_connect (app, "closed", (GCallback) &BamfLauncherIcon::OnClosed, this); - + g_object_ref (m_App); - + EnsureWindowState (); UpdateMenus (); } @@ -77,12 +98,43 @@ BamfLauncherIcon::~BamfLauncherIcon() g_object_unref (m_App); } +bool +BamfLauncherIcon::IsSticky () +{ + return bamf_view_is_sticky (BAMF_VIEW (m_App)); +} + +const char* +BamfLauncherIcon::DesktopFile () +{ + return bamf_application_get_desktop_file (m_App); +} + void BamfLauncherIcon::AddProperties (GVariantBuilder *builder) { LauncherIcon::AddProperties (builder); - + g_variant_builder_add (builder, "{sv}", "desktop-file", g_variant_new_string (bamf_application_get_desktop_file (m_App))); + + GList *children, *l; + BamfView *view; + + children = bamf_view_get_children (BAMF_VIEW (m_App)); + GVariant* xids[(int) g_list_length (children)]; + + int i = 0; + for (l = children; l; l = l->next) + { + view = (BamfView *) l->data; + + if (BAMF_IS_WINDOW (view)) + { + xids[i++] = g_variant_new_uint32 (bamf_window_get_xid (BAMF_WINDOW (view))); + } + } + g_list_free (children); + g_variant_builder_add (builder, "{sv}", "xids", g_variant_new_array (G_VARIANT_TYPE_UINT32, xids, i)); } bool @@ -90,6 +142,7 @@ BamfLauncherIcon::IconOwnsWindow (Window w) { GList *children, *l; BamfView *view; + bool owns = false; children = bamf_view_get_children (BAMF_VIEW (m_App)); @@ -100,13 +153,17 @@ BamfLauncherIcon::IconOwnsWindow (Window w) if (BAMF_IS_WINDOW (view)) { guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view)); - + if (xid == w) - return true; + { + owns = true; + break; + } } } - - return false; + + g_list_free (children); + return owns; } void @@ -118,13 +175,13 @@ BamfLauncherIcon::OpenInstance () appInfo = g_desktop_app_info_new_from_filename (bamf_application_get_desktop_file (BAMF_APPLICATION (m_App))); g_app_info_launch (G_APP_INFO (appInfo), NULL, NULL, &error); g_object_unref (appInfo); - + if (error) { g_warning ("%s\n", error->message); g_error_free (error); } - + UpdateQuirkTime (LAUNCHER_ICON_QUIRK_STARTING); } @@ -133,11 +190,13 @@ BamfLauncherIcon::Focus () { GList *children, *l; BamfView *view; - + bool any_urgent = false; + bool any_on_current = false; + children = bamf_view_get_children (BAMF_VIEW (m_App)); - + CompWindowList windows; - + /* get the list of windows */ for (l = children; l; l = l->next) { @@ -146,17 +205,25 @@ BamfLauncherIcon::Focus () if (BAMF_IS_WINDOW (view)) { guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view)); - + CompWindow *window = m_Screen->findWindow ((Window) xid); - + if (window) + { + if (window->state () & CompWindowStateDemandsAttentionMask) + any_urgent = true; windows.push_back (window); + } } } - + + // not a good sign if (windows.empty ()) + { + g_list_free (children); return; - + } + /* sort the list */ CompWindowList tmp; CompWindowList::iterator it; @@ -166,11 +233,8 @@ BamfLauncherIcon::Focus () tmp.push_back (*it); } windows = tmp; - - + /* filter based on workspace */ - bool any_on_current = false; - for (it = windows.begin (); it != windows.end (); it++) { if ((*it)->defaultViewport () == m_Screen->vp ()) @@ -179,15 +243,24 @@ BamfLauncherIcon::Focus () break; } } - - /* activate our windows */ - - if (any_on_current) + + if (any_urgent) + { + for (it = windows.begin (); it != windows.end (); it++) + { + if ((*it)->state () & CompWindowStateDemandsAttentionMask) + { + (*it)->activate (); + break; + } + } + } + else if (any_on_current) { for (it = windows.begin (); it != windows.end (); it++) { if ((*it)->defaultViewport () == m_Screen->vp ()) - { + { (*it)->activate (); } } @@ -196,7 +269,7 @@ BamfLauncherIcon::Focus () { (*(windows.rbegin ()))->activate (); } - + g_list_free (children); } @@ -206,7 +279,7 @@ BamfLauncherIcon::Spread () BamfView *view; GList *children, *l; children = bamf_view_get_children (BAMF_VIEW (m_App)); - + std::list<Window> windowList; for (l = children; l; l = l->next) { @@ -215,18 +288,18 @@ BamfLauncherIcon::Spread () if (BAMF_IS_WINDOW (view)) { guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view)); - + windowList.push_back ((Window) xid); } } - + if (windowList.size () > 1) { std::string *match = PluginAdapter::Default ()->MatchStringForXids (&windowList); PluginAdapter::Default ()->InitiateScale (match); delete match; } - + g_list_free (children); } @@ -235,14 +308,20 @@ BamfLauncherIcon::OnMouseClick (int button) { if (button != 1) return; - + bool active, running; - + active = bamf_view_is_active (BAMF_VIEW (m_App)); running = bamf_view_is_running (BAMF_VIEW (m_App)); if (!running) + { + if (GetQuirk (LAUNCHER_ICON_QUIRK_STARTING)) + return; + SetQuirk (LAUNCHER_ICON_QUIRK_STARTING, true); OpenInstance (); + return; + } else if (active) Spread (); else @@ -253,7 +332,7 @@ void BamfLauncherIcon::OnClosed (BamfView *view, gpointer data) { BamfLauncherIcon *self = (BamfLauncherIcon *) data; - + if (!bamf_view_is_sticky (BAMF_VIEW (self->m_App))) self->Remove (); } @@ -262,7 +341,7 @@ void BamfLauncherIcon::OnUserVisibleChanged (BamfView *view, gboolean visible, gpointer data) { BamfLauncherIcon *self = (BamfLauncherIcon *) data; - + if (!bamf_view_is_sticky (BAMF_VIEW (self->m_App))) self->SetQuirk (LAUNCHER_ICON_QUIRK_VISIBLE, visible); } @@ -272,7 +351,7 @@ BamfLauncherIcon::OnRunningChanged (BamfView *view, gboolean running, gpointer d { BamfLauncherIcon *self = (BamfLauncherIcon *) data; self->SetQuirk (LAUNCHER_ICON_QUIRK_RUNNING, running); - + if (running) { self->EnsureWindowState (); @@ -299,16 +378,16 @@ BamfLauncherIcon::EnsureWindowState () { GList *children, *l; int count = 0; - + children = bamf_view_get_children (BAMF_VIEW (m_App)); for (l = children; l; l = l->next) { if (BAMF_IS_WINDOW (l->data)) count++; } - + SetRelatedWindows (count); - + g_list_free (children); } @@ -332,7 +411,8 @@ void BamfLauncherIcon::UpdateMenus () { GList *children, *l; - + IndicatorDesktopShortcuts *desktop_shortcuts; + children = bamf_view_get_children (BAMF_VIEW (m_App)); for (l = children; l; l = l->next) { @@ -341,16 +421,59 @@ BamfLauncherIcon::UpdateMenus () BamfIndicator *indicator = BAMF_INDICATOR (l->data); std::string path = bamf_indicator_get_dbus_menu_path (indicator); - + // we already have this if (_menu_clients.find (path) != _menu_clients.end ()) continue; - + DbusmenuClient *client = dbusmenu_client_new (bamf_indicator_get_remote_address (indicator), path.c_str ()); _menu_clients[path] = client; } - + g_list_free (children); + + // make a client for desktop file actions + if (!DBUSMENU_IS_MENUITEM (_menu_desktop_shortcuts) && + bamf_application_get_desktop_file (m_App) != NULL) + { + + DbusmenuMenuitem *root = dbusmenu_menuitem_new (); + dbusmenu_menuitem_set_root (root, TRUE); + desktop_shortcuts = indicator_desktop_shortcuts_new (bamf_application_get_desktop_file (m_App), + "Unity"); + const gchar **nicks = indicator_desktop_shortcuts_get_nicks (desktop_shortcuts); + + int index = 0; + if (nicks) { + while (((gpointer*) nicks)[index]) { + const char* name; + DbusmenuMenuitem *item; + name = g_strdup (indicator_desktop_shortcuts_nick_get_name (desktop_shortcuts, + nicks[index])); + ShortcutData *data = g_slice_new0 (ShortcutData); + data->self = this; + data->shortcuts = INDICATOR_DESKTOP_SHORTCUTS (g_object_ref (desktop_shortcuts)); + data->nick = g_strdup (nicks[index]); + + item = dbusmenu_menuitem_new (); + dbusmenu_menuitem_property_set (item, DBUSMENU_MENUITEM_PROP_LABEL, name); + dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); + dbusmenu_menuitem_property_set_bool (item, DBUSMENU_MENUITEM_PROP_VISIBLE, TRUE); + g_signal_connect_data (item, "item-activated", + (GCallback) shortcut_activated, (gpointer) data, + (GClosureNotify) shortcut_data_destroy, (GConnectFlags)0); + + dbusmenu_menuitem_child_append (root, item); + + index++; + + g_free ((void *)name); + } + } + + _menu_desktop_shortcuts = root; + } + } void @@ -375,12 +498,12 @@ BamfLauncherIcon::OnQuit (DbusmenuMenuitem *item, int time, BamfLauncherIcon *se { guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view)); CompWindow *window = self->m_Screen->findWindow ((Window) xid); - + if (window) window->close (self->m_Screen->getCurrentTime ()); } } - + g_list_free (children); } @@ -390,20 +513,20 @@ BamfLauncherIcon::OnTogglePin (DbusmenuMenuitem *item, int time, BamfLauncherIco BamfView *view = BAMF_VIEW (self->m_App); bool sticky = bamf_view_is_sticky (view); const gchar *desktop_file = bamf_application_get_desktop_file (self->m_App); - + if (sticky) { bamf_view_set_sticky (view, false); if (bamf_view_is_closed (view)) self->Remove (); - + if (desktop_file && strlen (desktop_file) > 0) FavoriteStore::GetDefault ()->RemoveFavorite (desktop_file); } else { bamf_view_set_sticky (view, true); - + if (desktop_file && strlen (desktop_file) > 0) FavoriteStore::GetDefault ()->AddFavorite (desktop_file, -1); //self->SortPriority ()); } @@ -419,12 +542,12 @@ BamfLauncherIcon::EnsureMenuItemsReady () { menu_item = dbusmenu_menuitem_new (); g_object_ref (menu_item); - + dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_LABEL, "Open New Window"); dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); - + g_signal_connect (menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, (GCallback) &BamfLauncherIcon::OnLaunch, this); - + _menu_items["Launch"] = menu_item; } @@ -433,34 +556,34 @@ BamfLauncherIcon::EnsureMenuItemsReady () { menu_item = dbusmenu_menuitem_new (); g_object_ref (menu_item); - + dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, DBUSMENU_MENUITEM_TOGGLE_CHECK); dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_LABEL, "Keep In Launcher"); dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); - + g_signal_connect (menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, (GCallback) &BamfLauncherIcon::OnTogglePin, this); - + _menu_items["Pin"] = menu_item; } - int checked = !bamf_view_is_sticky (BAMF_VIEW (m_App)) ? + int checked = !bamf_view_is_sticky (BAMF_VIEW (m_App)) ? DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED : DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED; - - dbusmenu_menuitem_property_set_int (_menu_items["Pin"], - DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, + + dbusmenu_menuitem_property_set_int (_menu_items["Pin"], + DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, checked); - - + + /* Quit */ if (_menu_items.find ("Quit") == _menu_items.end ()) { menu_item = dbusmenu_menuitem_new (); g_object_ref (menu_item); - + dbusmenu_menuitem_property_set (menu_item, DBUSMENU_MENUITEM_PROP_LABEL, "Quit"); dbusmenu_menuitem_property_set_bool (menu_item, DBUSMENU_MENUITEM_PROP_ENABLED, true); - + g_signal_connect (menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, (GCallback) &BamfLauncherIcon::OnQuit, this); - + _menu_items["Quit"] = menu_item; } } @@ -470,32 +593,72 @@ BamfLauncherIcon::GetMenus () { std::map<std::string, DbusmenuClient *>::iterator it; std::list<DbusmenuMenuitem *> result; - + for (it = _menu_clients.begin (); it != _menu_clients.end (); it++) { GList * child = NULL; DbusmenuClient *client = (*it).second; DbusmenuMenuitem *root = dbusmenu_client_get_root (client); - + for (child = dbusmenu_menuitem_get_children(root); child != NULL; child = g_list_next(child)) { DbusmenuMenuitem *item = (DbusmenuMenuitem *) child->data; - + if (!item) continue; - + result.push_back (item); } } - + + if (DBUSMENU_IS_MENUITEM (_menu_desktop_shortcuts)) + { + GList * child = NULL; + DbusmenuMenuitem *root = _menu_desktop_shortcuts; + + for (child = dbusmenu_menuitem_get_children(root); child != NULL; child = g_list_next(child)) + { + DbusmenuMenuitem *item = (DbusmenuMenuitem *) child->data; + + if (!item) + continue; + + result.push_back (item); + } + + } + EnsureMenuItemsReady (); - result.push_back (_menu_items["Launch"]); - result.push_back (_menu_items["Pin"]); - - if (bamf_view_is_running (BAMF_VIEW (m_App))) - result.push_back (_menu_items["Quit"]); - + std::map<std::string, DbusmenuMenuitem *>::iterator it_m; + std::list<DbusmenuMenuitem *>::iterator it_l; + bool exists; + for (it_m = _menu_items.begin (); it_m != _menu_items.end (); it_m++) + { + const char* key = ((*it_m).first).c_str(); + if (g_strcmp0 (key , "Quit") == 0 && !bamf_view_is_running (BAMF_VIEW (m_App))) + continue; + + exists = false; + std::string label_default = dbusmenu_menuitem_property_get ((*it_m).second, DBUSMENU_MENUITEM_PROP_LABEL); + for(it_l = result.begin(); it_l != result.end(); it_l++) + { + const gchar* type = dbusmenu_menuitem_property_get (*it_l, DBUSMENU_MENUITEM_PROP_TYPE); + if (type == NULL)//(g_strcmp0 (type, DBUSMENU_MENUITEM_PROP_LABEL) == 0) + { + std::string label_menu = dbusmenu_menuitem_property_get (*it_l, DBUSMENU_MENUITEM_PROP_LABEL); + if (label_menu.compare(label_default) == 0) + { + exists = true; + break; + } + } + } + + if (!exists) + result.push_back((*it_m).second); + } + return result; } @@ -521,17 +684,17 @@ BamfLauncherIcon::UpdateIconGeometries (nux::Point3 center) if (BAMF_IS_WINDOW (view)) { guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view)); - + XChangeProperty (m_Screen->dpy (), xid, Atoms::wmIconGeometry, XA_CARDINAL, 32, PropModeReplace, (unsigned char *) data, 4); } } - + g_list_free (children); } -void +void BamfLauncherIcon::OnCenterStabilized (nux::Point3 center) { UpdateIconGeometries (center); diff --git a/src/BamfLauncherIcon.h b/src/BamfLauncherIcon.h index 3a323a500..0550e9257 100644 --- a/src/BamfLauncherIcon.h +++ b/src/BamfLauncherIcon.h @@ -36,18 +36,20 @@ class BamfLauncherIcon : public SimpleLauncherIcon { public: BamfLauncherIcon(Launcher* IconManager, BamfApplication *app, CompScreen *screen); - ~BamfLauncherIcon(); - - + virtual ~BamfLauncherIcon(); + + const char* DesktopFile (); + bool IsSticky (); + protected: void OnMouseClick (int button); std::list<DbusmenuMenuitem *> GetMenus (); - + void UpdateIconGeometries (nux::Point3 center); void OnCenterStabilized (nux::Point3 center); - + bool IconOwnsWindow (Window w); - + void AddProperties (GVariantBuilder *builder); private: @@ -55,17 +57,18 @@ private: CompScreen *m_Screen; std::map<std::string, DbusmenuClient *> _menu_clients; std::map<std::string, DbusmenuMenuitem *> _menu_items; - + DbusmenuMenuitem *_menu_desktop_shortcuts; + void EnsureWindowState (); - + void UpdateMenus (); - + void OpenInstance (); void Focus (); void Spread (); - + void EnsureMenuItemsReady (); - + static void OnClosed (BamfView *view, gpointer data); static void OnUserVisibleChanged (BamfView *view, gboolean visible, gpointer data); static void OnActiveChanged (BamfView *view, gboolean active, gpointer data); @@ -73,7 +76,7 @@ private: static void OnUrgentChanged (BamfView *view, gboolean urgent, gpointer data); static void OnChildAdded (BamfView *view, BamfView *child, gpointer data); static void OnChildRemoved (BamfView *view, BamfView *child, gpointer data); - + static void OnLaunch (DbusmenuMenuitem *item, int time, BamfLauncherIcon *self); static void OnQuit (DbusmenuMenuitem *item, int time, BamfLauncherIcon *self); static void OnTogglePin (DbusmenuMenuitem *item, int time, BamfLauncherIcon *self); diff --git a/src/FavoriteStore.h b/src/FavoriteStore.h index b67fda7b1..de8b13659 100644 --- a/src/FavoriteStore.h +++ b/src/FavoriteStore.h @@ -54,6 +54,7 @@ public: virtual void AddFavorite (const char *desktop_path, gint position) = 0; virtual void RemoveFavorite (const char *desktop_path) = 0; virtual void MoveFavorite (const char *desktop_path, gint position) = 0; + virtual void SetFavorites (std::list<const char*> desktop_paths) = 0; // Signals // Therse only emit if something has changed the GSettings object externally diff --git a/src/FavoriteStoreGSettings.cpp b/src/FavoriteStoreGSettings.cpp index 9c09cb3a8..6ba2c32d0 100644 --- a/src/FavoriteStoreGSettings.cpp +++ b/src/FavoriteStoreGSettings.cpp @@ -323,6 +323,36 @@ FavoriteStoreGSettings::MoveFavorite (const char *desktop_path, Refresh (); } +void +FavoriteStoreGSettings::SetFavorites (std::list<const char *> desktop_paths) +{ + char *favs[desktop_paths.size () + 1]; + favs[desktop_paths.size ()] = NULL; + + int i = 0; + std::list<const char*>::iterator it; + for (it = desktop_paths.begin (); it != desktop_paths.end (); it++) + { + favs[i] = get_basename_or_path (*it); + i++; + } + + m_ignore_signals = true; + if (!g_settings_set_strv (m_settings, "favorites", favs)) + g_warning ("Unable to set favorites from list"); + m_ignore_signals = false; + + i = 0; + while (favs[i] != NULL) + { + g_free (favs[i]); + favs[i] = NULL; + i++; + } + + Refresh (); +} + void FavoriteStoreGSettings::Changed (const gchar *key) { diff --git a/src/FavoriteStoreGSettings.h b/src/FavoriteStoreGSettings.h index dbc2f9e3a..f88fd0b1e 100644 --- a/src/FavoriteStoreGSettings.h +++ b/src/FavoriteStoreGSettings.h @@ -39,6 +39,7 @@ public: void AddFavorite (const char *desktop_path, gint position); void RemoveFavorite (const char *desktop_path); void MoveFavorite (const char *desktop_path, gint position); + void SetFavorites (std::list<const char *> desktop_paths); void Changed (const char *key); diff --git a/src/Launcher.cpp b/src/Launcher.cpp index 90765f830..a732f9c7b 100644 --- a/src/Launcher.cpp +++ b/src/Launcher.cpp @@ -35,6 +35,7 @@ #include "Launcher.h" #include "LauncherIcon.h" #include "LauncherModel.h" +#include "QuicklistManager.h" #include "QuicklistView.h" #define ANIM_DURATION_SHORT 125 @@ -55,7 +56,7 @@ TimeDelta (struct timespec const *x, struct timespec const *y) } static bool USE_ARB_SHADERS = true; -/* +/* Use this shader to pass vertices in screen coordinates in the C++ code and compute use the fragment shader to perform the texture perspective correct division. This shader assume the following: @@ -67,8 +68,8 @@ static bool USE_ARB_SHADERS = true; The texture coordinates s=u/w, t=v/w and q=1w are interpolated linearly in screen coordinates. In the fragment shader we get the texture coordinates used for the sampling by dividing s and t resulting from the interpolation by q. - - */ + + */ nux::NString gPerspectiveCorrectShader = TEXT ( "[Vertex Shader] \n\ @@ -179,7 +180,7 @@ Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DE _parent = parent; _screen = screen; _active_quicklist = 0; - + m_Layout = new nux::HLayout(NUX_TRACKER_LOCATION); OnMouseDown.connect(sigc::mem_fun(this, &Launcher::RecvMouseDown)); @@ -190,6 +191,9 @@ Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DE OnMouseMove.connect(sigc::mem_fun(this, &Launcher::RecvMouseMove)); OnMouseWheel.connect(sigc::mem_fun(this, &Launcher::RecvMouseWheel)); + QuicklistManager::Default ()->quicklist_opened.connect (sigc::mem_fun(this, &Launcher::RecvQuicklistOpened)); + QuicklistManager::Default ()->quicklist_closed.connect (sigc::mem_fun(this, &Launcher::RecvQuicklistClosed)); + m_ActiveTooltipIcon = NULL; m_ActiveMenuIcon = NULL; @@ -205,7 +209,7 @@ Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DE { _AsmShaderProg = nux::GetThreadGLDeviceFactory()->CreateAsmShaderProgram(); _AsmShaderProg->LoadVertexShader (TCHAR_TO_ANSI (*PerspectiveCorrectVtx) ); - + if ((nux::GetThreadGLDeviceFactory()->SUPPORT_GL_ARB_TEXTURE_NON_POWER_OF_TWO() == false) && (nux::GetThreadGLDeviceFactory()->SUPPORT_GL_EXT_TEXTURE_RECTANGLE () || nux::GetThreadGLDeviceFactory()->SUPPORT_GL_ARB_TEXTURE_RECTANGLE ())) { @@ -230,11 +234,13 @@ Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DE _launcher_action_state = ACTION_NONE; _icon_under_mouse = NULL; _icon_mouse_down = NULL; + _drag_icon = NULL; + _drag_icon_under_mouse = NULL; _icon_image_size = 48; _icon_glow_size = 62; _icon_image_size_delta = 6; _icon_size = _icon_image_size + _icon_image_size_delta; - + _icon_bkg_texture = nux::CreateTextureFromFile (PKGDATADIR"/round_corner_54x54.png"); _icon_outline_texture = nux::CreateTextureFromFile (PKGDATADIR"/round_outline_54x54.png"); _icon_shine_texture = nux::CreateTextureFromFile (PKGDATADIR"/round_shine_54x54.png"); @@ -242,10 +248,12 @@ Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DE _icon_2indicator = nux::CreateTextureFromFile (PKGDATADIR"/2indicate_54x54.png"); _icon_3indicator = nux::CreateTextureFromFile (PKGDATADIR"/3indicate_54x54.png"); _icon_4indicator = nux::CreateTextureFromFile (PKGDATADIR"/4indicate_54x54.png"); - + _enter_y = 0; _dnd_security = 15; - _dnd_delta = 0; + _launcher_drag_delta = 0; + _dnd_delta_y = 0; + _dnd_delta_x = 0; _anim_handle = 0; _autohide_handle = 0; _floating = false; @@ -255,7 +263,8 @@ Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DE _mouse_inside_launcher = false; _mouse_inside_trigger = false; _window_over_launcher = false; - + _render_drag_window = false; + // 0 out timers to avoid wonky startups _enter_time.tv_sec = 0; _enter_time.tv_nsec = 0; @@ -263,8 +272,13 @@ Launcher::Launcher(nux::BaseWindow *parent, CompScreen *screen, NUX_FILE_LINE_DE _exit_time.tv_nsec = 0; _drag_end_time.tv_sec = 0; _drag_end_time.tv_nsec = 0; + _drag_start_time.tv_sec = 0; + _drag_start_time.tv_nsec = 0; _autohide_time.tv_sec = 0; _autohide_time.tv_nsec = 0; + + _drag_window = NULL; + _offscreen_rt_texture = nux::GetThreadGLDeviceFactory()->CreateSystemCapableDeviceTexture (2, 2, 1, nux::BITFMT_R8G8B8A8); } Launcher::~Launcher() @@ -288,8 +302,8 @@ Launcher::AddProperties (GVariantBuilder *builder) g_variant_builder_add (builder, "{sv}", "hover-progress", g_variant_new_double ((double) GetHoverProgress (current))); g_variant_builder_add (builder, "{sv}", "dnd-exit-progress", g_variant_new_double ((double) DnDExitProgress (current))); g_variant_builder_add (builder, "{sv}", "autohide-progress", g_variant_new_double ((double) AutohideProgress (current))); - - g_variant_builder_add (builder, "{sv}", "dnd-delta", g_variant_new_int32 (_dnd_delta)); + + g_variant_builder_add (builder, "{sv}", "dnd-delta", g_variant_new_int32 (_dnd_delta_y)); g_variant_builder_add (builder, "{sv}", "floating", g_variant_new_boolean (_floating)); g_variant_builder_add (builder, "{sv}", "hovered", g_variant_new_boolean (_hovered)); g_variant_builder_add (builder, "{sv}", "autohide", g_variant_new_boolean (_autohide)); @@ -313,11 +327,16 @@ float Launcher::DnDExitProgress (struct timespec const ¤t) return 1.0f - CLAMP ((float) (TimeDelta (¤t, &_drag_end_time)) / (float) ANIM_DURATION_LONG, 0.0f, 1.0f); } +float Launcher::DnDStartProgress (struct timespec const ¤t) +{ + return CLAMP ((float) (TimeDelta (¤t, &_drag_start_time)) / (float) ANIM_DURATION, 0.0f, 1.0f); +} + float Launcher::AutohideProgress (struct timespec const ¤t) { if (!_autohide) return 0.0f; - + if (_hidden) return CLAMP ((float) (TimeDelta (¤t, &_autohide_time)) / (float) ANIM_DURATION_SHORT, 0.0f, 1.0f); else @@ -327,26 +346,13 @@ float Launcher::AutohideProgress (struct timespec const ¤t) gboolean Launcher::AnimationTimeout (gpointer data) { Launcher *self = (Launcher*) data; - self->NeedRedraw (); - - if (self->AnimationInProgress ()) - return true; - - // zero out handle so we know we are done - self->_anim_handle = 0; return false; } void Launcher::EnsureAnimation () { - if (_anim_handle) - return; - NeedRedraw (); - - if (AnimationInProgress ()) - _anim_handle = g_timeout_add (1000 / 60 - 1, &Launcher::AnimationTimeout, this); } bool Launcher::IconNeedsAnimation (LauncherIcon *icon, struct timespec const ¤t) @@ -354,27 +360,32 @@ bool Launcher::IconNeedsAnimation (LauncherIcon *icon, struct timespec const &cu struct timespec time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_VISIBLE); if (TimeDelta (¤t, &time) < ANIM_DURATION_SHORT) return true; - + time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_RUNNING); if (TimeDelta (¤t, &time) < ANIM_DURATION_SHORT) return true; - + time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_STARTING); if (TimeDelta (¤t, &time) < (ANIM_DURATION_LONG * MAX_STARTING_BLINKS * STARTING_BLINK_LAMBDA * 2)) return true; - + time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_URGENT); if (TimeDelta (¤t, &time) < (ANIM_DURATION_LONG * URGENT_BLINKS * 2)) return true; - + time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_PRESENTED); if (TimeDelta (¤t, &time) < ANIM_DURATION) return true; - + time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_SHIMMER); if (TimeDelta (¤t, &time) < ANIM_DURATION_LONG) return true; - + + time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_CENTER_SAVED); + if (TimeDelta (¤t, &time) < ANIM_DURATION) + return true; + + return false; } @@ -386,28 +397,32 @@ bool Launcher::AnimationInProgress () // short circuit to avoid unneeded calculations struct timespec current; clock_gettime (CLOCK_MONOTONIC, ¤t); - + // hover in animation if (TimeDelta (¤t, &_enter_time) < ANIM_DURATION) return true; - + // hover out animation if (TimeDelta (¤t, &_exit_time) < ANIM_DURATION) return true; + // drag start animation + if (TimeDelta (¤t, &_drag_start_time) < ANIM_DURATION) + return true; + // drag end animation if (TimeDelta (¤t, &_drag_end_time) < ANIM_DURATION_LONG) return true; - + if (TimeDelta (¤t, &_autohide_time) < ANIM_DURATION_SHORT) return true; - + // animations happening on specific icons LauncherModel::iterator it; for (it = _model->begin (); it != _model->end (); it++) if (IconNeedsAnimation (*it, current)) return true; - + return false; } @@ -415,17 +430,17 @@ void Launcher::SetTimeStruct (struct timespec *timer, struct timespec *sister, i { struct timespec current; clock_gettime (CLOCK_MONOTONIC, ¤t); - + if (sister) { int diff = TimeDelta (¤t, sister); - + if (diff < sister_relation) { int remove = sister_relation - diff; current.tv_sec -= remove / 1000; remove = remove % 1000; - + if (remove > current.tv_nsec / 1000000) { current.tv_sec--; @@ -434,7 +449,7 @@ void Launcher::SetTimeStruct (struct timespec *timer, struct timespec *sister, i current.tv_nsec -= remove * 1000000; } } - + timer->tv_sec = current.tv_sec; timer->tv_nsec = current.tv_nsec; } @@ -460,7 +475,7 @@ void Launcher::SetDndDelta (float x, float y, nux::Geometry geo, struct timespec LauncherIcon *anchor = 0; LauncherModel::iterator it; anchor = MouseIconIntersection (x, _enter_y); - + if (anchor) { float position = y; @@ -469,11 +484,11 @@ void Launcher::SetDndDelta (float x, float y, nux::Geometry geo, struct timespec if (*it == anchor) { position += _icon_size / 2; - _dnd_delta = _enter_y - position; - - if (position + _icon_size / 2 + _dnd_delta > geo.height) - _dnd_delta -= (position + _icon_size / 2 + _dnd_delta) - geo.height; - + _launcher_drag_delta = _enter_y - position; + + if (position + _icon_size / 2 + _launcher_drag_delta > geo.height) + _launcher_drag_delta -= (position + _icon_size / 2 + _launcher_drag_delta) - geo.height; + break; } position += (_icon_size + _space_between_icons) * IconVisibleProgress (*it, current); @@ -486,7 +501,7 @@ float Launcher::IconPresentProgress (LauncherIcon *icon, struct timespec const & struct timespec icon_present_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_PRESENTED); int ms = TimeDelta (¤t, &icon_present_time); float result = CLAMP ((float) ms / (float) ANIM_DURATION, 0.0f, 1.0f); - + if (icon->GetQuirk (LAUNCHER_ICON_QUIRK_PRESENTED)) return result; else @@ -498,7 +513,7 @@ float Launcher::IconUrgentProgress (LauncherIcon *icon, struct timespec const &c struct timespec urgent_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_URGENT); int urgent_ms = TimeDelta (¤t, &urgent_time); float result = CLAMP ((float) urgent_ms / (float) (ANIM_DURATION_LONG * URGENT_BLINKS * 2), 0.0f, 1.0f); - + if (icon->GetQuirk (LAUNCHER_ICON_QUIRK_URGENT)) return result; else @@ -512,11 +527,18 @@ float Launcher::IconShimmerProgress (LauncherIcon *icon, struct timespec const & return CLAMP ((float) shimmer_ms / (float) ANIM_DURATION_LONG, 0.0f, 1.0f); } +float Launcher::IconCenterTransitionProgress (LauncherIcon *icon, struct timespec const ¤t) +{ + struct timespec save_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_CENTER_SAVED); + int save_ms = TimeDelta (¤t, &save_time); + return CLAMP ((float) save_ms / (float) ANIM_DURATION, 0.0f, 1.0f); +} + float Launcher::IconUrgentPulseValue (LauncherIcon *icon, struct timespec const ¤t) { if (!icon->GetQuirk (LAUNCHER_ICON_QUIRK_URGENT)) return 1.0f; // we are full on in a normal condition - + double urgent_progress = (double) IconUrgentProgress (icon, current); return 0.5f + (float) (std::cos (M_PI * (float) (URGENT_BLINKS * 2) * urgent_progress)) * 0.5f; } @@ -526,7 +548,13 @@ float Launcher::IconStartingPulseValue (LauncherIcon *icon, struct timespec cons struct timespec starting_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_STARTING); int starting_ms = TimeDelta (¤t, &starting_time); double starting_progress = (double) CLAMP ((float) starting_ms / (float) (ANIM_DURATION_LONG * MAX_STARTING_BLINKS * STARTING_BLINK_LAMBDA * 2), 0.0f, 1.0f); - + + if (starting_progress == 1.0f && !icon->GetQuirk (LAUNCHER_ICON_QUIRK_RUNNING)) + { + icon->SetQuirk (LAUNCHER_ICON_QUIRK_STARTING, false); + icon->ResetQuirkTime (LAUNCHER_ICON_QUIRK_STARTING); + } + return 1.0f - (0.5f + (float) (std::cos (M_PI * (float) (MAX_STARTING_BLINKS * 2) * starting_progress)) * 0.5f); } @@ -538,16 +566,19 @@ float Launcher::IconBackgroundIntensity (LauncherIcon *icon, struct timespec con float running_progress = CLAMP ((float) running_ms / (float) ANIM_DURATION_SHORT, 0.0f, 1.0f); // After we finish a fade in from running, we can reset the quirk - if (icon->GetQuirk (LAUNCHER_ICON_QUIRK_RUNNING) && running_progress == 1.0f) - icon->ResetQuirkTime (LAUNCHER_ICON_QUIRK_STARTING); - + if (running_progress == 1.0f && icon->GetQuirk (LAUNCHER_ICON_QUIRK_RUNNING)) + { + icon->SetQuirk (LAUNCHER_ICON_QUIRK_STARTING, false); + icon->ResetQuirkTime (LAUNCHER_ICON_QUIRK_STARTING); + } + result = IconStartingPulseValue (icon, current) * BACKLIGHT_STRENGTH; if (icon->GetQuirk (LAUNCHER_ICON_QUIRK_RUNNING)) { // running progress fades in whatever the pulsing did not fill in already result += running_progress * (BACKLIGHT_STRENGTH - result); - + // urgent serves to bring the total down only if (icon->GetQuirk (LAUNCHER_ICON_QUIRK_URGENT)) result *= 0.2f + 0.8f * IconUrgentPulseValue (icon, current); @@ -557,7 +588,7 @@ float Launcher::IconBackgroundIntensity (LauncherIcon *icon, struct timespec con // modestly evil result += BACKLIGHT_STRENGTH - running_progress * BACKLIGHT_STRENGTH; } - + return result; } @@ -569,34 +600,102 @@ void Launcher::SetupRenderArg (LauncherIcon *icon, struct timespec const ¤ arg.active_arrow = icon->GetQuirk (LAUNCHER_ICON_QUIRK_ACTIVE); arg.running_colored = icon->GetQuirk (LAUNCHER_ICON_QUIRK_URGENT); arg.active_colored = false; - arg.folding_rads = 0.0f; + arg.x_rotation = 0.0f; + arg.y_rotation = 0.0f; + arg.z_rotation = 0.0f; arg.skip = false; - - + + // we dont need to show strays if (!icon->GetQuirk (LAUNCHER_ICON_QUIRK_RUNNING)) arg.window_indicators = 0; else arg.window_indicators = MIN (4, icon->RelatedWindows ()); - + arg.backlight_intensity = IconBackgroundIntensity (icon, current); arg.shimmer_progress = IconShimmerProgress (icon, current); - + float urgent_progress = IconUrgentProgress (icon, current); - urgent_progress = CLAMP (urgent_progress * 3, 0.0f, 1.0f); // we want to go 3x faster than the urgent normal cycle + + if (icon->GetQuirk (LAUNCHER_ICON_QUIRK_URGENT)) + urgent_progress = CLAMP (urgent_progress * 3.0f, 0.0f, 1.0f); // we want to go 3x faster than the urgent normal cycle + else + urgent_progress = CLAMP (urgent_progress * 3.0f - 2.0f, 0.0f, 1.0f); // we want to go 3x faster than the urgent normal cycle arg.glow_intensity = urgent_progress; } +void Launcher::FillRenderArg (LauncherIcon *icon, + RenderArg &arg, + nux::Point3 ¢er, + float folding_threshold, + float folded_size, + float folded_spacing, + float autohide_offset, + float folded_z_distance, + float animation_neg_rads, + struct timespec const ¤t) +{ + SetupRenderArg (icon, current, arg); + + // reset z + center.z = 0; + + float size_modifier = IconVisibleProgress (icon, current); + if (size_modifier < 1.0f) + { + arg.alpha = size_modifier; + center.z = 300.0f * (1.0f - size_modifier); + } + + if (size_modifier <= 0.0f || icon == _drag_icon) + arg.skip = true; + + + // goes for 0.0f when fully unfolded, to 1.0f folded + float folding_progress = CLAMP ((center.y + _icon_size - folding_threshold) / (float) _icon_size, 0.0f, 1.0f); + float present_progress = IconPresentProgress (icon, current); + + folding_progress *= 1.0f - present_progress; + + float half_size = (folded_size / 2.0f) + (_icon_size / 2.0f - folded_size / 2.0f) * (1.0f - folding_progress); + float icon_hide_offset = autohide_offset; + + icon_hide_offset *= 1.0f - (present_progress * icon->PresentUrgency ()); + + // icon is crossing threshold, start folding + center.z += folded_z_distance * folding_progress; + arg.x_rotation = animation_neg_rads * folding_progress; + + float spacing_overlap = CLAMP ((float) (center.y + (2.0f * half_size * size_modifier) + (_space_between_icons * size_modifier) - folding_threshold) / (float) _icon_size, 0.0f, 1.0f); + float spacing = (_space_between_icons * (1.0f - spacing_overlap) + folded_spacing * spacing_overlap) * size_modifier; + + nux::Point3 centerOffset; + float center_transit_progress = IconCenterTransitionProgress (icon, current); + if (center_transit_progress <= 1.0f) + { + centerOffset.y = (icon->_saved_center.y - (center.y + (half_size * size_modifier))) * (1.0f - center_transit_progress); + } + + center.y += half_size * size_modifier; // move to center + + arg.render_center = nux::Point3 (roundf (center.x + icon_hide_offset), roundf (center.y + centerOffset.y), roundf (center.z)); + arg.logical_center = nux::Point3 (roundf (center.x + icon_hide_offset), roundf (center.y), roundf (center.z)); + + icon->SetCenter (nux::Point3 (roundf (center.x), roundf (center.y), roundf (center.z))); + + center.y += (half_size * size_modifier) + spacing; // move to end +} + float Launcher::DragLimiter (float x) { float result = (1 - std::pow (159.0 / 160, std::abs (x))) * 160; - + if (x >= 0.0f) return result; return -result; } -void Launcher::RenderArgs (std::list<Launcher::RenderArg> &launcher_args, +void Launcher::RenderArgs (std::list<Launcher::RenderArg> &launcher_args, nux::Geometry &box_geo) { nux::Geometry geo = GetGeometry (); @@ -604,24 +703,23 @@ void Launcher::RenderArgs (std::list<Launcher::RenderArg> &launcher_args, nux::Point3 center; struct timespec current; clock_gettime (CLOCK_MONOTONIC, ¤t); - + float hover_progress = GetHoverProgress (current); float folded_z_distance = _folded_z_distance * (1.0f - hover_progress); float animation_neg_rads = _neg_folded_angle * (1.0f - hover_progress); - int vertical_offset = _parent->GetGeometry ().y; float folding_constant = 0.25f; float folding_not_constant = folding_constant + ((1.0f - folding_constant) * hover_progress); - + float folded_size = _icon_size * folding_not_constant; float folded_spacing = _space_between_icons * folding_not_constant; - + center.x = geo.width / 2; center.y = _space_between_icons; center.z = 0; - + int launcher_height = geo.height; - + // compute required height of launcher AND folding threshold float sum = 0.0f + center.y; float folding_threshold = launcher_height - _icon_size / 2.5f; @@ -629,69 +727,69 @@ void Launcher::RenderArgs (std::list<Launcher::RenderArg> &launcher_args, { float height = (_icon_size + _space_between_icons) * IconVisibleProgress (*it, current); sum += height; - + // magic constant must some day be explained, for now suffice to say this constant prevents the bottom from "marching"; float magic_constant = 1.2f; - + float present_progress = IconPresentProgress (*it, current); folding_threshold -= CLAMP (sum - launcher_height, 0.0f, height * magic_constant) * (folding_constant + (1.0f - folding_constant) * present_progress); } - + // this happens on hover, basically its a flag and a value in one, we translate this into a dnd offset if (_enter_y != 0 && _enter_y + _icon_size / 2 > folding_threshold) SetDndDelta (center.x, center.y, nux::Geometry (geo.x, geo.y, geo.width, geo.height), current); _enter_y = 0; - if (hover_progress > 0.0f && _dnd_delta != 0) + if (hover_progress > 0.0f && _launcher_drag_delta != 0) { - float delta_y = _dnd_delta; - + float delta_y = _launcher_drag_delta; + // logically dnd exit only restores to the clamped ranges // hover_progress restores to 0 float max = 0.0f; float min = MIN (0.0f, launcher_height - sum); - - if (_dnd_delta > max) + + if (_launcher_drag_delta > max) delta_y = max + DragLimiter (delta_y - max); - else if (_dnd_delta < min) + else if (_launcher_drag_delta < min) delta_y = min + DragLimiter (delta_y - min); - + if (_launcher_action_state != ACTION_DRAG_LAUNCHER) { float dnd_progress = DnDExitProgress (current); - if (_dnd_delta > max) + if (_launcher_drag_delta > max) delta_y = max + (delta_y - max) * dnd_progress; - else if (_dnd_delta < min) + else if (_launcher_drag_delta < min) delta_y = min + (delta_y - min) * dnd_progress; - + if (dnd_progress == 0.0f) - _dnd_delta = (int) delta_y; - } + _launcher_drag_delta = (int) delta_y; + } delta_y *= hover_progress; center.y += delta_y; folding_threshold += delta_y; - } - else + } + else { - _dnd_delta = 0; + _launcher_drag_delta = 0; } - + float autohide_progress = AutohideProgress (current); float autohide_offset = 0.0f; if (_autohide && autohide_progress > 0.0f) { autohide_offset -= geo.width * autohide_progress; } - + // Inform the painter where to paint the box box_geo = geo; if (_autohide) box_geo.x += autohide_offset; - + // The functional position we wish to represent for these icons is not smooth. Rather than introducing // special casing to represent this, we use MIN/MAX functions. This helps ensure that even though our // function is not smooth it is continuous, which is more important for our visual representation (icons @@ -701,122 +799,36 @@ void Launcher::RenderArgs (std::list<Launcher::RenderArg> &launcher_args, { RenderArg arg; LauncherIcon *icon = *it; - - SetupRenderArg (icon, current, arg); - - // reset z - center.z = 0; - - float size_modifier = IconVisibleProgress (icon, current); - if (size_modifier < 1.0f) - { - arg.alpha = size_modifier; - center.z = 300.0f * (1.0f - size_modifier); - } - - if (size_modifier <= 0.0f) - { - arg.skip = true; - continue; - } - - // goes for 0.0f when fully unfolded, to 1.0f folded - float folding_progress = CLAMP ((center.y + _icon_size - folding_threshold) / (float) _icon_size, 0.0f, 1.0f); - float present_progress = IconPresentProgress (icon, current); - - folding_progress *= 1.0f - present_progress; - - float half_size = (folded_size / 2.0f) + (_icon_size / 2.0f - folded_size / 2.0f) * (1.0f - folding_progress); - - float icon_hide_offset = autohide_offset; - - if (icon->PresentUrgency () == 1) - icon_hide_offset *= 0.5f + 0.5f * (1.0f - present_progress); - else if (icon->PresentUrgency () >= 2) - icon_hide_offset *= 1.0f - present_progress; - - // icon is crossing threshold, start folding - center.z += folded_z_distance * folding_progress; - arg.folding_rads = animation_neg_rads * folding_progress; - - center.y += half_size * size_modifier; // move to center - arg.center = nux::Point3 ((int) (center.x + icon_hide_offset), (int) center.y, (int) center.z); // copy center - icon->SetCenter (nux::Point3 ((int) center.x, (int) (center.y + vertical_offset), (int) center.z)); - center.y += half_size * size_modifier; // move to end - - float spacing_overlap = CLAMP ((float) (center.y + (_space_between_icons * size_modifier) - folding_threshold) / (float) _icon_size, 0.0f, 1.0f); - //add spacing - center.y += (_space_between_icons * (1.0f - spacing_overlap) + folded_spacing * spacing_overlap) * size_modifier; - + + FillRenderArg (icon, arg, center, folding_threshold, folded_size, folded_spacing, + autohide_offset, folded_z_distance, animation_neg_rads, current); + launcher_args.push_back (arg); } - + // compute maximum height of shelf float shelf_sum = 0.0f; for (it = _model->shelf_begin (); it != _model->shelf_end (); it++) { float height = (_icon_size + _space_between_icons) * IconVisibleProgress (*it, current); - shelf_sum += height; + shelf_sum += height; } - + // add bottom padding if (shelf_sum > 0.0f) shelf_sum += _space_between_icons; - + float shelf_delta = MAX (((launcher_height - shelf_sum) + _space_between_icons) - center.y, 0.0f); folding_threshold += shelf_delta; center.y += shelf_delta; - + for (it = _model->shelf_begin (); it != _model->shelf_end (); it++) { RenderArg arg; LauncherIcon *icon = *it; - SetupRenderArg (icon, current, arg); - - // reset z - center.z = 0; - - float size_modifier = IconVisibleProgress (icon, current); - if (size_modifier < 1.0f) - { - arg.alpha = size_modifier; - center.z = 300.0f * (1.0f - size_modifier); - } - - if (size_modifier <= 0.0f) - { - arg.skip = true; - continue; - } - - // goes for 0.0f when fully unfolded, to 1.0f folded - float folding_progress = CLAMP ((center.y + _icon_size - folding_threshold) / (float) _icon_size, 0.0f, 1.0f); - float present_progress = IconPresentProgress (icon, current); - - folding_progress *= 1.0f - present_progress; - - float half_size = (folded_size / 2.0f) + (_icon_size / 2.0f - folded_size / 2.0f) * (1.0f - folding_progress); - - float icon_hide_offset = autohide_offset; - - if (icon->PresentUrgency () == 1) - icon_hide_offset *= 0.5f + 0.5f * (1.0f - present_progress); - else if (icon->PresentUrgency () >= 2) - icon_hide_offset *= 1.0f - present_progress; - - // icon is crossing threshold, start folding - center.z += folded_z_distance * folding_progress; - arg.folding_rads = animation_neg_rads * folding_progress; - - center.y += half_size * size_modifier; // move to center - arg.center = nux::Point3 ((int) (center.x + icon_hide_offset), (int) center.y, (int) center.z); // copy center - icon->SetCenter (nux::Point3 ((int) center.x, (int) (center.y + vertical_offset), (int) center.z)); - center.y += half_size * size_modifier; // move to end - - float spacing_overlap = CLAMP ((float) (center.y + (_space_between_icons * size_modifier) - folding_threshold) / (float) _icon_size, 0.0f, 1.0f); - //add spacing - center.y += (_space_between_icons * (1.0f - spacing_overlap) + folded_spacing * spacing_overlap) * size_modifier; + FillRenderArg (icon, arg, center, folding_threshold, folded_size, folded_spacing, + autohide_offset, folded_z_distance, animation_neg_rads, current); launcher_args.push_back (arg); } @@ -828,19 +840,19 @@ void Launcher::SetHidden (bool hidden) { if (hidden == _hidden) return; - + _hidden = hidden; SetTimeStruct (&_autohide_time, &_autohide_time, ANIM_DURATION_SHORT); - + _parent->EnableInputWindow(!hidden); - + EnsureAnimation (); } gboolean Launcher::OnAutohideTimeout (gpointer data) { Launcher *self = (Launcher*) data; - + self->EnsureHiddenState (); self->_autohide_handle = 0; return false; @@ -849,7 +861,11 @@ gboolean Launcher::OnAutohideTimeout (gpointer data) void Launcher::EnsureHiddenState () { - if (!_mouse_inside_trigger && !_mouse_inside_launcher && _window_over_launcher) + if (!_mouse_inside_trigger && + !_mouse_inside_launcher && + _launcher_action_state == ACTION_NONE && + !QuicklistManager::Default ()->Current() && + _window_over_launcher) SetHidden (true); else SetHidden (false); @@ -861,14 +877,14 @@ Launcher::CheckWindowOverLauncher () CompWindowList window_list = _screen->windows (); CompWindowList::iterator it; nux::Geometry geo = GetGeometry (); - + for (it = window_list.begin (); it != window_list.end (); it++) { CompWindow *window = *it; - + if (window->type () != CompWindowTypeNormalMask || window->invisible ()) continue; - + if (CompRegion (window->inputRect ()).intersects (CompRect (geo.x, geo.y, geo.width, geo.height))) { _window_over_launcher = true; @@ -876,7 +892,7 @@ Launcher::CheckWindowOverLauncher () return; } } - + _window_over_launcher = false; EnsureHiddenState (); } @@ -895,6 +911,19 @@ Launcher::OnWindowResized (CompWindow *window) CheckWindowOverLauncher (); } +void +Launcher::OnWindowAppear (CompWindow *window) +{ + if (_autohide) + CheckWindowOverLauncher (); +} +void +Launcher::OnWindowDisappear (CompWindow *window) +{ + if (_autohide) + CheckWindowOverLauncher (); +} + void Launcher::OnTriggerMouseEnter (int x, int y, unsigned long button_flags, unsigned long key_flags) { _mouse_inside_trigger = true; @@ -927,7 +956,7 @@ gboolean Launcher::StrutHack (gpointer data) Launcher *self = (Launcher *) data; self->_parent->InputWindowEnableStruts(false); self->_parent->InputWindowEnableStruts(true); - + return false; } @@ -935,7 +964,7 @@ void Launcher::SetAutohide (bool autohide, nux::View *trigger) { if (_autohide == autohide) return; - + if (autohide) { _parent->InputWindowEnableStruts(false); @@ -949,7 +978,7 @@ void Launcher::SetAutohide (bool autohide, nux::View *trigger) g_timeout_add (1000, &Launcher::StrutHack, this); _parent->InputWindowEnableStruts(true); } - + _autohide = autohide; EnsureAnimation (); } @@ -958,18 +987,31 @@ void Launcher::SetFloating (bool floating) { if (_floating == floating) return; - + _floating = floating; EnsureAnimation (); } +void +Launcher::EnsureHoverState () +{ + if (_mouse_inside_launcher || QuicklistManager::Default ()->Current() || _launcher_action_state != ACTION_NONE) + { + SetHover (); + } + else + { + UnsetHover (); + } +} + void Launcher::SetHover () { if (_hovered) return; - + _enter_y = (int) _mouse_position.y; - + _hovered = true; SetTimeStruct (&_enter_time, &_exit_time, ANIM_DURATION); } @@ -978,7 +1020,7 @@ void Launcher::UnsetHover () { if (!_hovered) return; - + _hovered = false; SetTimeStruct (&_exit_time, &_enter_time, ANIM_DURATION); SetupAutohideTimer (); @@ -987,41 +1029,37 @@ void Launcher::UnsetHover () void Launcher::SetIconSize(int tile_size, int icon_size) { nux::Geometry geo = _parent->GetGeometry (); - + _icon_size = tile_size; _icon_image_size = icon_size; _icon_image_size_delta = tile_size - icon_size; - + // recreate tile textures - + _parent->SetGeometry (nux::Geometry (geo.x, geo.y, tile_size + 12, geo.height)); } -void Launcher::OnIconAdded (void *icon_pointer) +void Launcher::OnIconAdded (LauncherIcon *icon) { - LauncherIcon *icon = (LauncherIcon *) icon_pointer; icon->Reference (); EnsureAnimation(); - + // How to free these properly? icon->_xform_coords["HitArea"] = new nux::Vector4[4]; icon->_xform_coords["Image"] = new nux::Vector4[4]; icon->_xform_coords["Tile"] = new nux::Vector4[4]; icon->_xform_coords["Glow"] = new nux::Vector4[4]; - + // needs to be disconnected icon->needs_redraw.connect (sigc::mem_fun(this, &Launcher::OnIconNeedsRedraw)); - + AddChild (icon); } -void Launcher::OnIconRemoved (void *icon_pointer) +void Launcher::OnIconRemoved (LauncherIcon *icon) { - LauncherIcon *icon = (LauncherIcon *) icon_pointer; icon->UnReference (); - EnsureAnimation(); - RemoveChild (icon); } @@ -1038,7 +1076,7 @@ void Launcher::SetModel (LauncherModel *model) _model->order_changed.connect (sigc::mem_fun (this, &Launcher::OnOrderChanged)); } -void Launcher::OnIconNeedsRedraw (void *icon) +void Launcher::OnIconNeedsRedraw (LauncherIcon *icon) { EnsureAnimation(); } @@ -1055,14 +1093,14 @@ void Launcher::Draw(nux::GraphicsEngine& GfxContext, bool force_draw) } -void Launcher::RenderIndicators (nux::GraphicsEngine& GfxContext, - RenderArg const &arg, - int running, - int active, +void Launcher::RenderIndicators (nux::GraphicsEngine& GfxContext, + RenderArg const &arg, + int running, + int active, nux::Geometry geo) { - int markerCenter = (int) arg.center.y; - + int markerCenter = (int) arg.render_center.y; + if (running > 0) { if (!m_RunningIndicator) @@ -1072,12 +1110,12 @@ void Launcher::RenderIndicators (nux::GraphicsEngine& GfxContext, g_object_unref (pbuf); } nux::TexCoordXForm texxform; - - nux::Color color = nux::Color::White; - + + nux::Color color = nux::Color::LightGrey; + if (arg.running_colored) color = nux::Color::SkyBlue; - + std::vector<int> markers; if (running == 1) { @@ -1094,21 +1132,21 @@ void Launcher::RenderIndicators (nux::GraphicsEngine& GfxContext, markers.push_back (markerCenter); markers.push_back (markerCenter + 4); } - + std::vector<int>::iterator it; for (it = markers.begin (); it != markers.end (); it++) { int center = *it; GfxContext.QRP_GLSL_1Tex (geo.x, - center - (m_RunningIndicator->GetHeight () / 2), - (float) m_RunningIndicator->GetWidth(), - (float) m_RunningIndicator->GetHeight(), - m_RunningIndicator->GetDeviceTexture(), - texxform, + center - (m_RunningIndicator->GetHeight () / 2), + (float) m_RunningIndicator->GetWidth(), + (float) m_RunningIndicator->GetHeight(), + m_RunningIndicator->GetDeviceTexture(), + texxform, color); } } - + if (active > 0) { if (!m_ActiveIndicator) @@ -1118,32 +1156,35 @@ void Launcher::RenderIndicators (nux::GraphicsEngine& GfxContext, g_object_unref (pbuf); } nux::TexCoordXForm texxform; - - nux::Color color = nux::Color::White; - GfxContext.QRP_GLSL_1Tex ((geo.x + geo.width) - m_ActiveIndicator->GetWidth (), + + nux::Color color = nux::Color::LightGrey; + GfxContext.QRP_GLSL_1Tex ((geo.x + geo.width) - m_ActiveIndicator->GetWidth (), markerCenter - (m_ActiveIndicator->GetHeight () / 2), - (float) m_ActiveIndicator->GetWidth(), - (float) m_ActiveIndicator->GetHeight(), - m_ActiveIndicator->GetDeviceTexture(), - texxform, + (float) m_ActiveIndicator->GetWidth(), + (float) m_ActiveIndicator->GetHeight(), + m_ActiveIndicator->GetDeviceTexture(), + texxform, color); } } -void Launcher::RenderIcon(nux::GraphicsEngine& GfxContext, - RenderArg const &arg, - nux::BaseTexture *icon, - nux::Color bkg_color, - float alpha, - nux::Vector4 xform_coords[], +void Launcher::RenderIcon(nux::GraphicsEngine& GfxContext, + RenderArg const &arg, + nux::BaseTexture *icon, + nux::Color bkg_color, + float alpha, + nux::Vector4 xform_coords[], nux::Geometry geo) { + if (icon == NULL || icon->IsNull ()) + return; + nux::Matrix4 ObjectMatrix; nux::Matrix4 ViewMatrix; nux::Matrix4 ProjectionMatrix; nux::Matrix4 ViewProjectionMatrix; - - if(nux::Abs (arg.folding_rads) < 0.01f) + + if(nux::Abs (arg.x_rotation) < 0.01f) icon->GetDeviceTexture()->SetFiltering(GL_NEAREST, GL_NEAREST); else icon->GetDeviceTexture()->SetFiltering(GL_LINEAR, GL_LINEAR); @@ -1172,7 +1213,7 @@ void Launcher::RenderIcon(nux::GraphicsEngine& GfxContext, float s0, t0, s1, t1, s2, t2, s3, t3; nux::Color color = nux::Color::White; - + if (icon->Type ().IsDerivedFromType(nux::TextureRectangle::StaticObjectType)) { s0 = 0.0f; t0 = 0.0f; @@ -1214,7 +1255,7 @@ void Launcher::RenderIcon(nux::GraphicsEngine& GfxContext, TextureCoord0Location = _shader_program_uv_persp_correction->GetAttributeLocation("iTexCoord0"); VertexColorLocation = _shader_program_uv_persp_correction->GetAttributeLocation("iColor"); FragmentColor = _shader_program_uv_persp_correction->GetUniformLocationARB ("color"); - + nux::GetGraphicsEngine ().SetTexture(GL_TEXTURE0, icon); if(TextureObjectLocation != -1) @@ -1252,9 +1293,9 @@ void Launcher::RenderIcon(nux::GraphicsEngine& GfxContext, CHECKGL( glEnableVertexAttribArrayARB(VertexColorLocation) ); CHECKGL( glVertexAttribPointerARB((GLuint)VertexColorLocation, 4, GL_FLOAT, GL_FALSE, 48, VtxBuffer + 8) ); } - + bkg_color.SetAlpha (bkg_color.A () * alpha); - + if(!USE_ARB_SHADERS) { CHECKGL ( glUniform4fARB (FragmentColor, bkg_color.R(), bkg_color.G(), bkg_color.B(), bkg_color.A() ) ); @@ -1267,7 +1308,7 @@ void Launcher::RenderIcon(nux::GraphicsEngine& GfxContext, nux::GetGraphicsEngine ().SetTexture(GL_TEXTURE0, icon); CHECKGL( glDrawArrays(GL_QUADS, 0, 4) ); } - + if(VertexLocation != -1) CHECKGL( glDisableVertexAttribArrayARB(VertexLocation) ); if(TextureCoord0Location != -1) @@ -1294,139 +1335,142 @@ void Launcher::DrawRenderArg (nux::GraphicsEngine& GfxContext, RenderArg const & GL_ONE); GfxContext.GetRenderStates ().SetColorMask (true, true, true, true); - + if (arg.backlight_intensity < 1.0f) { - RenderIcon(GfxContext, - arg, - _icon_outline_texture, - nux::Color(0xAAFFFFFF), - 1.0f - arg.backlight_intensity, - arg.icon->_xform_coords["Tile"], + RenderIcon(GfxContext, + arg, + _icon_outline_texture, + nux::Color(0xAAFFFFFF), + 1.0f - arg.backlight_intensity, + arg.icon->_xform_coords["Tile"], geo); } - + if (arg.backlight_intensity > 0.0f) { - RenderIcon(GfxContext, - arg, - _icon_bkg_texture, - arg.icon->BackgroundColor (), - arg.backlight_intensity, - arg.icon->_xform_coords["Tile"], + RenderIcon(GfxContext, + arg, + _icon_bkg_texture, + arg.icon->BackgroundColor (), + arg.backlight_intensity, + arg.icon->_xform_coords["Tile"], geo); } - + GfxContext.GetRenderStates ().SetSeparateBlend (true, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE); GfxContext.GetRenderStates ().SetColorMask (true, true, true, true); - - RenderIcon (GfxContext, - arg, - arg.icon->TextureForSize (_icon_image_size), + + RenderIcon (GfxContext, + arg, + arg.icon->TextureForSize (_icon_image_size), nux::Color::White, arg.alpha, arg.icon->_xform_coords["Image"], geo); - + if (arg.backlight_intensity > 0.0f) { - RenderIcon(GfxContext, - arg, - _icon_shine_texture, - nux::Color::White, - arg.backlight_intensity, - arg.icon->_xform_coords["Tile"], + RenderIcon(GfxContext, + arg, + _icon_shine_texture, + nux::Color::White, + arg.backlight_intensity, + arg.icon->_xform_coords["Tile"], geo); } - + if (false) { switch (arg.window_indicators) { case 2: - RenderIcon(GfxContext, - arg, - _icon_2indicator, - nux::Color::White, - 1.0f, - arg.icon->_xform_coords["Tile"], + RenderIcon(GfxContext, + arg, + _icon_2indicator, + nux::Color::White, + 1.0f, + arg.icon->_xform_coords["Tile"], geo); break; case 3: - RenderIcon(GfxContext, - arg, - _icon_3indicator, - nux::Color::White, - 1.0f, - arg.icon->_xform_coords["Tile"], + RenderIcon(GfxContext, + arg, + _icon_3indicator, + nux::Color::White, + 1.0f, + arg.icon->_xform_coords["Tile"], geo); break; case 4: - RenderIcon(GfxContext, - arg, - _icon_4indicator, - nux::Color::White, - 1.0f, - arg.icon->_xform_coords["Tile"], + RenderIcon(GfxContext, + arg, + _icon_4indicator, + nux::Color::White, + 1.0f, + arg.icon->_xform_coords["Tile"], geo); break; } } - + if (arg.glow_intensity > 0.0f) { - RenderIcon(GfxContext, - arg, + RenderIcon(GfxContext, + arg, _icon_glow_texture, - arg.icon->GlowColor (), - arg.glow_intensity, - arg.icon->_xform_coords["Glow"], + arg.icon->GlowColor (), + arg.glow_intensity, + arg.icon->_xform_coords["Glow"], geo); } - + if (arg.shimmer_progress > 0.0f && arg.shimmer_progress < 1.0f) { nux::Geometry base = GetGeometry (); int x1 = base.x + base.width; int x2 = base.x + base.width; float shimmer_constant = 1.9f; - + x1 -= geo.width * arg.shimmer_progress * shimmer_constant; GfxContext.PushClippingRectangle(nux::Geometry (x1, geo.y, x2 - x1, geo.height)); - + float fade_out = 1.0f - CLAMP (((x2 - x1) - geo.width) / (geo.width * (shimmer_constant - 1.0f)), 0.0f, 1.0f); - - RenderIcon(GfxContext, - arg, + + RenderIcon(GfxContext, + arg, _icon_glow_texture, - arg.icon->GlowColor (), - fade_out, - arg.icon->_xform_coords["Glow"], + arg.icon->GlowColor (), + fade_out, + arg.icon->_xform_coords["Glow"], geo); - + GfxContext.PopClippingRectangle(); } - + RenderIndicators (GfxContext, - arg, - arg.running_arrow ? arg.window_indicators : 0, - arg.active_arrow ? 1 : 0, + arg, + arg.running_arrow ? arg.window_indicators : 0, + arg.active_arrow ? 1 : 0, geo); } void Launcher::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) { nux::Geometry base = GetGeometry(); - GfxContext.PushClippingRectangle(base); nux::Geometry bkg_box; std::list<Launcher::RenderArg> args; std::list<Launcher::RenderArg>::reverse_iterator rev_it; std::list<Launcher::RenderArg>::iterator it; - + + // rely on the compiz event loop to come back to us in a nice throttling + if (AnimationInProgress ()) + g_timeout_add (0, &Launcher::AnimationTimeout, this); + nux::ROPConfig ROP; ROP.Blend = false; ROP.SrcBlend = GL_SRC_ALPHA; @@ -1434,9 +1478,41 @@ void Launcher::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) RenderArgs (args, bkg_box); - // clear region + if (_drag_icon && _render_drag_window) + { + RenderArg arg; + struct timespec current; + clock_gettime (CLOCK_MONOTONIC, ¤t); + + SetupRenderArg (_drag_icon, current, arg); + arg.render_center = nux::Point3 (_icon_size / 2.0f, _icon_size / 2.0f, 0.0f); + arg.logical_center = arg.render_center; + arg.x_rotation = 0.0f; + arg.running_arrow = false; + arg.active_arrow = false; + arg.skip = false; + arg.window_indicators = 0; + arg.alpha = 1.0f; + + std::list<Launcher::RenderArg> drag_args; + drag_args.push_front (arg); + UpdateIconXForm (drag_args); + + SetOffscreenRenderTarget (); + DrawRenderArg (nux::GetGraphicsEngine (), arg, nux::Geometry (0, 0, _icon_size, _icon_size)); + RestoreSystemRenderTarget (); + + _drag_window->ShowWindow (true); + nux::GetWindowCompositor ().SetAlwaysOnFrontWindow (_drag_window); + + _render_drag_window = false; + } + + + // clear region + GfxContext.PushClippingRectangle(base); gPainter.PushDrawColorLayer(GfxContext, base, nux::Color(0x00000000), true, ROP); - + // clip vertically but not horizontally GfxContext.PushClippingRectangle(nux::Geometry (base.x, bkg_box.y, base.width, bkg_box.height)); GfxContext.GetRenderStates ().SetSeparateBlend (true, @@ -1444,30 +1520,30 @@ void Launcher::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) GL_ONE_MINUS_SRC_ALPHA, GL_ONE_MINUS_DST_ALPHA, GL_ONE); - + gPainter.Paint2DQuadColor (GfxContext, bkg_box, nux::Color(0xAA000000)); - + UpdateIconXForm (args); EventLogic (); /* draw launcher */ for (rev_it = args.rbegin (); rev_it != args.rend (); rev_it++) { - if ((*rev_it).folding_rads >= 0.0f || (*rev_it).skip) + if ((*rev_it).x_rotation >= 0.0f || (*rev_it).skip) continue; - + DrawRenderArg (GfxContext, *rev_it, bkg_box); } for (it = args.begin(); it != args.end(); it++) { - if ((*it).folding_rads < 0.0f || (*it).skip) + if ((*it).x_rotation < 0.0f || (*it).skip) continue; - + DrawRenderArg (GfxContext, *it, bkg_box); } - - + + gPainter.Paint2DQuadColor (GfxContext, nux::Geometry (bkg_box.x + bkg_box.width - 1, bkg_box.y, 1, bkg_box.height), nux::Color(0x60FFFFFF)); GfxContext.GetRenderStates().SetColorMask (true, true, true, true); @@ -1500,7 +1576,7 @@ long Launcher::PostLayoutManagement(long LayoutResult) View::PostLayoutManagement(LayoutResult); _mouse_position = nux::Point2 (0, 0); - + return nux::eCompliantHeight | nux::eCompliantWidth; } @@ -1526,10 +1602,59 @@ void Launcher::NotifyMenuTermination(LauncherIcon* Icon) { } +void Launcher::StartIconDrag (LauncherIcon *icon) +{ + if (!icon) + return; + + _drag_icon = icon; + + if (_drag_window) + { + _drag_window->ShowWindow (false); + _drag_window->UnReference (); + _drag_window = NULL; + } + + _offscreen_rt_texture = nux::GetThreadGLDeviceFactory()->CreateSystemCapableDeviceTexture (_icon_size, _icon_size, 1, nux::BITFMT_R8G8B8A8); + _drag_window = new LauncherDragWindow (_offscreen_rt_texture); + _drag_window->SinkReference (); + + _render_drag_window = true; +} + +void Launcher::EndIconDrag () +{ + if (_drag_window) + { + _drag_window->ShowWindow (false); + _drag_window->UnReference (); + _drag_window = NULL; + } + + _drag_icon_under_mouse = NULL; + _drag_icon = NULL; + _render_drag_window = false; +} + +void Launcher::UpdateDragWindowPosition (int x, int y) +{ + if (_drag_window) + { + nux::Geometry geo = _drag_window->GetGeometry (); + _drag_window->SetBaseXY (x - geo.width / 2 + _parent->GetGeometry ().x, y - geo.height / 2 + _parent->GetGeometry ().y); + + LauncherIcon *hovered_icon = MouseIconIntersection ((int) (GetGeometry ().x / 2.0f), y); + + if (_drag_icon && hovered_icon && _drag_icon != hovered_icon) + request_reorder.emit (_drag_icon, hovered_icon); + } +} + void Launcher::RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags) { _mouse_position = nux::Point2 (x, y); - + MouseDownLogic (x, y, button_flags, key_flags); EnsureAnimation (); } @@ -1539,34 +1664,73 @@ void Launcher::RecvMouseUp(int x, int y, unsigned long button_flags, unsigned lo _mouse_position = nux::Point2 (x, y); nux::Geometry geo = GetGeometry (); - if (_launcher_action_state == ACTION_DRAG_LAUNCHER && !geo.IsInside(nux::Point(x, y))) + if (_launcher_action_state != ACTION_NONE && !geo.IsInside(nux::Point(x, y))) { // we are no longer hovered - UnsetHover (); + EnsureHoverState (); } - + MouseUpLogic (x, y, button_flags, key_flags); + + if (_launcher_action_state == ACTION_DRAG_ICON) + EndIconDrag (); + _launcher_action_state = ACTION_NONE; + _dnd_delta_x = 0; + _dnd_delta_y = 0; EnsureAnimation (); } void Launcher::RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags) { _mouse_position = nux::Point2 (x, y); - - _dnd_delta += dy; - if (nux::Abs (_dnd_delta) < 15 && _launcher_action_state != ACTION_DRAG_LAUNCHER) - return; + _dnd_delta_y += dy; + _dnd_delta_x += dx; + if (nux::Abs (_dnd_delta_y) < 15 && + nux::Abs (_dnd_delta_x) < 15 && + _launcher_action_state == ACTION_NONE) + return; + if (_icon_under_mouse) { _icon_under_mouse->MouseLeave.emit (); _icon_under_mouse->_mouse_inside = false; _icon_under_mouse = 0; } + + if (_launcher_action_state == ACTION_NONE) + { + SetTimeStruct (&_drag_start_time); + + if (nux::Abs (_dnd_delta_y) >= nux::Abs (_dnd_delta_x)) + { + _launcher_drag_delta += _dnd_delta_y; + _launcher_action_state = ACTION_DRAG_LAUNCHER; + } + else + { + LauncherIcon *drag_icon = MouseIconIntersection ((int) (GetGeometry ().x / 2.0f), y); + + if (drag_icon) + { + StartIconDrag (drag_icon); + _launcher_action_state = ACTION_DRAG_ICON; + UpdateDragWindowPosition (x, y); + } + + } + } + else if (_launcher_action_state == ACTION_DRAG_LAUNCHER) + { + _launcher_drag_delta += dy; + } + else if (_launcher_action_state == ACTION_DRAG_ICON) + { + UpdateDragWindowPosition (x, y); + } - _launcher_action_state = ACTION_DRAG_LAUNCHER; EnsureAnimation (); } @@ -1574,8 +1738,8 @@ void Launcher::RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned { _mouse_position = nux::Point2 (x, y); _mouse_inside_launcher = true; - - SetHover (); + + EnsureHoverState (); EventLogic (); EnsureAnimation (); @@ -1585,10 +1749,10 @@ void Launcher::RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned { _mouse_position = nux::Point2 (x, y); _mouse_inside_launcher = false; - - if (_launcher_action_state != ACTION_DRAG_LAUNCHER) - UnsetHover (); - + + if (_launcher_action_state == ACTION_NONE) + EnsureHoverState (); + EventLogic (); EnsureAnimation (); } @@ -1603,15 +1767,46 @@ void Launcher::RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_ void Launcher::RecvMouseWheel(int x, int y, int wheel_delta, unsigned long button_flags, unsigned long key_flags) { + if (!_hovered) + return; + + if (wheel_delta < 0) + { + // scroll up + _launcher_drag_delta += 10; + } + else + { + // scroll down + _launcher_drag_delta -= 10; + } + + EnsureAnimation (); +} + +void Launcher::RecvQuicklistOpened (QuicklistView *quicklist) +{ + EventLogic (); + EnsureHoverState (); + EnsureAnimation (); +} + +void Launcher::RecvQuicklistClosed (QuicklistView *quicklist) +{ + SetupAutohideTimer (); + + EventLogic (); + EnsureHoverState (); + EnsureAnimation (); } void Launcher::EventLogic () -{ - if (_launcher_action_state == ACTION_DRAG_LAUNCHER) +{ + if (_launcher_action_state != ACTION_NONE) return; - + LauncherIcon* launcher_icon = 0; - + if (_mouse_inside_launcher) launcher_icon = MouseIconIntersection (_mouse_position.x, _mouse_position.y); @@ -1650,8 +1845,8 @@ void Launcher::MouseUpLogic (int x, int y, unsigned long button_flags, unsigned if (_icon_mouse_down && (_icon_mouse_down == launcher_icon)) { _icon_mouse_down->MouseUp.emit (nux::GetEventButton (button_flags)); - - if (_launcher_action_state != ACTION_DRAG_LAUNCHER) + + if (_launcher_action_state == ACTION_NONE) _icon_mouse_down->MouseClick.emit (nux::GetEventButton (button_flags)); } @@ -1659,12 +1854,12 @@ void Launcher::MouseUpLogic (int x, int y, unsigned long button_flags, unsigned { launcher_icon->MouseUp.emit (nux::GetEventButton (button_flags)); } - + if (_launcher_action_state == ACTION_DRAG_LAUNCHER) { SetTimeStruct (&_drag_end_time); } - + _icon_mouse_down = 0; } @@ -1712,14 +1907,14 @@ LauncherIcon* Launcher::MouseIconIntersection (int x, int y) return 0; } -void Launcher::SetIconXForm (LauncherIcon *icon, nux::Matrix4 ViewProjectionMatrix, nux::Geometry geo, +void Launcher::SetIconXForm (LauncherIcon *icon, nux::Matrix4 ViewProjectionMatrix, nux::Geometry geo, float x, float y, float w, float h, float z, std::string name) { nux::Vector4 v0 = nux::Vector4(x, y, z, 1.0f); nux::Vector4 v1 = nux::Vector4(x, y+h, z, 1.0f); nux::Vector4 v2 = nux::Vector4(x+w, y+h, z, 1.0f); nux::Vector4 v3 = nux::Vector4(x+w, y, z, 1.0f); - + v0 = ViewProjectionMatrix * v0; v1 = ViewProjectionMatrix * v1; v2 = ViewProjectionMatrix * v2; @@ -1742,7 +1937,7 @@ void Launcher::SetIconXForm (LauncherIcon *icon, nux::Matrix4 ViewProjectionMatr nux::Vector4* vectors = icon->_xform_coords[name]; - + vectors[0].x = v0.x; vectors[0].y = v0.y; vectors[0].z = v0.z; @@ -1775,50 +1970,58 @@ void Launcher::UpdateIconXForm (std::list<Launcher::RenderArg> &args) std::list<Launcher::RenderArg>::iterator it; for(it = args.begin(); it != args.end(); it++) { - if ((*it).skip) - continue; - + LauncherIcon* launcher_icon = (*it).icon; - + // We to store the icon angle in the icons itself. Makes one thing easier afterward. - launcher_icon->_folding_angle = (*it).folding_rads; - + launcher_icon->_folding_angle = (*it).x_rotation; + float w = _icon_size; float h = _icon_size; - float x = (*it).center.x - w/2.0f; // x: top left corner - float y = (*it).center.y - h/2.0f; // y: top left corner - float z = (*it).center.z; + float x = (*it).render_center.x - w/2.0f; // x: top left corner + float y = (*it).render_center.y - h/2.0f; // y: top left corner + float z = (*it).render_center.z; + if ((*it).skip) + { + w = 1; + h = 1; + x = -100; + y = -100; + } + ObjectMatrix = nux::Matrix4::TRANSLATE(geo.width/2.0f, geo.height/2.0f, z) * // Translate the icon to the center of the viewport - nux::Matrix4::ROTATEX((*it).folding_rads) * // rotate the icon + nux::Matrix4::ROTATEX((*it).x_rotation) * // rotate the icon + nux::Matrix4::ROTATEY((*it).y_rotation) * + nux::Matrix4::ROTATEZ((*it).z_rotation) * nux::Matrix4::TRANSLATE(-x - w/2.0f, -y - h/2.0f, -z); // Put the center the icon to (0, 0) ViewProjectionMatrix = ProjectionMatrix*ViewMatrix*ObjectMatrix; SetIconXForm (launcher_icon, ViewProjectionMatrix, geo, x, y, w, h, z, "Tile"); - + w = _icon_image_size; h = _icon_image_size; - x = (*it).center.x - _icon_size/2.0f + _icon_image_size_delta/2.0f; - y = (*it).center.y - _icon_size/2.0f + _icon_image_size_delta/2.0f; - z = (*it).center.z; - + x = (*it).render_center.x - _icon_size/2.0f + _icon_image_size_delta/2.0f; + y = (*it).render_center.y - _icon_size/2.0f + _icon_image_size_delta/2.0f; + z = (*it).render_center.z; + SetIconXForm (launcher_icon, ViewProjectionMatrix, geo, x, y, w, h, z, "Image"); - + w = _icon_glow_size; h = _icon_glow_size; - x = (*it).center.x - _icon_glow_size/2.0f; - y = (*it).center.y - _icon_glow_size/2.0f; - z = (*it).center.z; - + x = (*it).render_center.x - _icon_glow_size/2.0f; + y = (*it).render_center.y - _icon_glow_size/2.0f; + z = (*it).render_center.z; + SetIconXForm (launcher_icon, ViewProjectionMatrix, geo, x, y, w, h, z, "Glow"); - + w = geo.width + 2; h = _icon_size + _space_between_icons; - x = (*it).center.x - w/2.0f; - y = (*it).center.y - h/2.0f; - z = (*it).center.z; - + x = (*it).logical_center.x - w/2.0f; + y = (*it).logical_center.y - h/2.0f; + z = (*it).logical_center.z; + SetIconXForm (launcher_icon, ViewProjectionMatrix, geo, x, y, w, h, z, "HitArea"); } } @@ -1843,7 +2046,7 @@ void GetInverseScreenPerspectiveMatrix(nux::Matrix4& ViewMatrix, nux::Matrix4& P x_cs = AspectRatio*y_cs y_cs/z_cs = tanf(Fovy/2) ==> z_cs = y_cs*1/tanf(Fovy/2) (this is the absolute value the quad depth value will be -z_cs since we are using OpenGL right hand coord system). - The quad (in camera space) facing the camera and centered around the camera view axis is defined by the points (-x_cs, y_cs) (top-left) + The quad (in camera space) facing the camera and centered around the camera view axis is defined by the points (-x_cs, y_cs) (top-left) and the point (x_cs, -y_cs) (bottom-right). If we move that quad along the camera view axis and place it at a distance z_cs of the camera, then its 4 corners are each on the 4 lines of the view frustum. @@ -1860,7 +2063,7 @@ void GetInverseScreenPerspectiveMatrix(nux::Matrix4& ViewMatrix, nux::Matrix4& P (x_cs, -y_cs) The full-screen quad (in screen space) is defined by the point (0, 0) (top-left) and (WindowWidth, WindowHeight) (bottom-right). - We can choose and arbitrary value y_cs and compute the z_cs position in camera space that will produce a quad in camera space that projects into + We can choose and arbitrary value y_cs and compute the z_cs position in camera space that will produce a quad in camera space that projects into the full-screen space. (0, 0) Screen Space @@ -1880,7 +2083,7 @@ void GetInverseScreenPerspectiveMatrix(nux::Matrix4& ViewMatrix, nux::Matrix4& P Screen Space Camera Space x ----> x_ = x*2*x_cs/WindowWidth - x_cs y ----> y_ = -y*2*y_cs/WindowHeight + y_cs - z ----> z_ = A*z -y_cs*1/tanf(Fovy/2) + z ----> z_ = A*z -y_cs*1/tanf(Fovy/2) where A is a coefficient that can attenuate the rate of change in depth when the quad moves along the camera axis If the following is the projection matrix: @@ -1903,7 +2106,7 @@ void GetInverseScreenPerspectiveMatrix(nux::Matrix4& ViewMatrix, nux::Matrix4& P float x_cs = y_cs*AspectRatio; //float CameraToScreenDistance = -y_cs*1.0f/(tanf(0.5f*Fovy/* *3.1415926/180.0f*/)); - ViewMatrix = nux::Matrix4::TRANSLATE(-x_cs, y_cs, CameraToScreenDistance) * + ViewMatrix = nux::Matrix4::TRANSLATE(-x_cs, y_cs, CameraToScreenDistance) * nux::Matrix4::SCALE(2.0f*x_cs/ViewportWidth, -2.0f*y_cs/ViewportHeight, -2.0f * 3 * y_cs/ViewportHeight /* or -2.0f * x_cs/ViewportWidth*/ ); PerspectiveMatrix.Perspective(Fovy, AspectRatio, NearClipPlane, FarClipPlane); @@ -1915,7 +2118,7 @@ void GetInverseScreenPerspectiveMatrix(nux::Matrix4& ViewMatrix, nux::Matrix4& P // float X = (ViewportWidth - W)/2.0; // float Y = (ViewportHeight - H)/2.0; // float Z = 0.0f; -// +// // { // glPushMatrix(); // // Local Transformation of the object @@ -1924,40 +2127,42 @@ void GetInverseScreenPerspectiveMatrix(nux::Matrix4& ViewMatrix, nux::Matrix4& P // glRotatef(cameraAngleY, 1, 0, 0); // glRotatef(cameraAngleX, 0, 1, 0); // glTranslatef(-X - W/2.0f, -Y - H/2.0f, 0.0f); -// +// // glBegin(GL_QUADS); // { // glNormal3f(0.0f, 0.0f, 1.0f); -// +// // glColor4f(1.0f, 0.0f, 0.0f, 1.0f); // glVertex4f(X, Y, Z, 1.0f); -// +// // glColor4f(0.0f, 1.0f, 0.0f, 1.0f); // glVertex4f(X, Y+H, Z, 1.0f); -// +// // glColor4f(0.0f, 0.0f, 1.0f, 1.0f); // glVertex4f(X+W, Y+H, Z, 1.0f); -// +// // glColor4f(0.0f, 1.0f, 1.0f, 1.0f); // glVertex4f(X+W, Y, Z, 1.0f); // } // glEnd(); } -void Launcher::SetActiveQuicklist (QuicklistView *quicklist) +void Launcher::SetOffscreenRenderTarget () { - // Assert: _active_quicklist should be 0 - _active_quicklist = quicklist; -} + int width = _offscreen_rt_texture->GetWidth (); + int height = _offscreen_rt_texture->GetHeight (); + + nux::GetThreadGLDeviceFactory ()->FormatFrameBufferObject (width, height, nux::BITFMT_R8G8B8A8); + nux::GetThreadGLDeviceFactory ()->SetColorRenderTargetSurface (0, _offscreen_rt_texture->GetSurfaceLevel (0)); + nux::GetThreadGLDeviceFactory ()->ActivateFrameBuffer (); -QuicklistView *Launcher::GetActiveQuicklist () -{ - return _active_quicklist; + nux::GetThreadGraphicsContext ()->SetContext (0, 0, width, height); + nux::GetThreadGraphicsContext ()->SetViewport (0, 0, width, height); + nux::GetThreadGraphicsContext ()->Push2DWindow (width, height); + nux::GetThreadGraphicsContext ()->EmptyClippingRegion(); } -void Launcher::CancelActiveQuicklist (QuicklistView *quicklist) +void Launcher::RestoreSystemRenderTarget () { - if (_active_quicklist == quicklist) - _active_quicklist = 0; + nux::GetWindowCompositor ().RestoreRenderingSurface (); } - diff --git a/src/Launcher.h b/src/Launcher.h index 6c601cb0f..9c53e0b76 100644 --- a/src/Launcher.h +++ b/src/Launcher.h @@ -27,6 +27,7 @@ #include <Nux/BaseWindow.h> #include "Introspectable.h" #include "LauncherIcon.h" +#include "LauncherDragWindow.h" #include "NuxGraphics/IOpenGLAsmShader.h" #include "Nux/TimerProc.h" @@ -46,23 +47,27 @@ public: LauncherIcon* GetActiveTooltipIcon() {return m_ActiveTooltipIcon;} LauncherIcon* GetActiveMenuIcon() {return m_ActiveMenuIcon;} - + bool TooltipNotify(LauncherIcon* Icon); bool MenuNotify(LauncherIcon* Icon); - + void SetIconSize(int tile_size, int icon_size); void NotifyMenuTermination(LauncherIcon* Icon); - + void SetModel (LauncherModel *model); - + void SetFloating (bool floating); - + void SetAutohide (bool autohide, nux::View *show_trigger); bool AutohideEnabled (); + nux::BaseWindow* GetParent () { return _parent; }; + void OnWindowMoved (CompWindow *window); void OnWindowResized (CompWindow *window); - + void OnWindowAppear (CompWindow *window); + void OnWindowDisappear (CompWindow *window); + virtual void RecvMouseUp(int x, int y, unsigned long button_flags, unsigned long key_flags); virtual void RecvMouseDown(int x, int y, unsigned long button_flags, unsigned long key_flags); virtual void RecvMouseDrag(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); @@ -71,17 +76,14 @@ public: virtual void RecvMouseMove(int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags); virtual void RecvMouseWheel(int x, int y, int wheel_delta, unsigned long button_flags, unsigned long key_flags); - //! Called by LauncherIcon to signal that a Quicklist is becoming active. - void SetActiveQuicklist (QuicklistView *quicklist); - //! Get the active qicklist - QuicklistView *GetActiveQuicklist (); - //! Called by LauncherIcon to signal that a Quicklist is becoming unactive. - void CancelActiveQuicklist (QuicklistView *quicklist); + virtual void RecvQuicklistOpened (QuicklistView *quicklist); + virtual void RecvQuicklistClosed (QuicklistView *quicklist); -protected: - // Introspectable methods - const gchar* GetName (); - void AddProperties (GVariantBuilder *builder); + sigc::signal<void, LauncherIcon *, LauncherIcon *> request_reorder; +protected: + // Introspectable methods + const gchar* GetName (); + void AddProperties (GVariantBuilder *builder); private: typedef enum @@ -96,12 +98,15 @@ private: ACTION_DRAG_LAUNCHER, ACTION_DRAG_ICON, } LauncherActionState; - + typedef struct { LauncherIcon *icon; - nux::Point3 center; - float folding_rads; + nux::Point3 render_center; + nux::Point3 logical_center; + float x_rotation; + float y_rotation; + float z_rotation; float alpha; float backlight_intensity; float glow_intensity; @@ -113,80 +118,100 @@ private: bool skip; int window_indicators; } RenderArg; - + static gboolean AnimationTimeout (gpointer data); static gboolean OnAutohideTimeout (gpointer data); static gboolean StrutHack (gpointer data); - + void OnTriggerMouseEnter (int x, int y, unsigned long button_flags, unsigned long key_flags); void OnTriggerMouseLeave (int x, int y, unsigned long button_flags, unsigned long key_flags); - + bool IconNeedsAnimation (LauncherIcon *icon, struct timespec const ¤t); bool AnimationInProgress (); void SetTimeStruct (struct timespec *timer, struct timespec *sister = 0, int sister_relation = 0); - + + void EnsureHoverState (); void EnsureHiddenState (); void EnsureAnimation (); void SetupAutohideTimer (); - + void CheckWindowOverLauncher (); - - float DnDExitProgress (struct timespec const ¤t); - float GetHoverProgress (struct timespec const ¤t); - float AutohideProgress (struct timespec const ¤t); + + float DnDStartProgress (struct timespec const ¤t); + float DnDExitProgress (struct timespec const ¤t); + float GetHoverProgress (struct timespec const ¤t); + float AutohideProgress (struct timespec const ¤t); float IconPresentProgress (LauncherIcon *icon, struct timespec const ¤t); float IconUrgentProgress (LauncherIcon *icon, struct timespec const ¤t); float IconShimmerProgress (LauncherIcon *icon, struct timespec const ¤t); float IconUrgentPulseValue (LauncherIcon *icon, struct timespec const ¤t); float IconStartingPulseValue (LauncherIcon *icon, struct timespec const ¤t); float IconBackgroundIntensity (LauncherIcon *icon, struct timespec const ¤t); + float IconCenterTransitionProgress (LauncherIcon *icon, struct timespec const ¤t); void SetHover (); void UnsetHover (); void SetHidden (bool hidden); - + void SetDndDelta (float x, float y, nux::Geometry geo, struct timespec const ¤t); float DragLimiter (float x); - + void SetupRenderArg (LauncherIcon *icon, struct timespec const ¤t, RenderArg &arg); - void RenderArgs (std::list<Launcher::RenderArg> &launcher_args, + void FillRenderArg (LauncherIcon *icon, + RenderArg &arg, + nux::Point3 ¢er, + float folding_threshold, + float folded_size, + float folded_spacing, + float autohide_offset, + float folded_z_distance, + float animation_neg_rads, + struct timespec const ¤t); + + void RenderArgs (std::list<Launcher::RenderArg> &launcher_args, nux::Geometry &box_geo); void DrawRenderArg (nux::GraphicsEngine& GfxContext, RenderArg const &arg, nux::Geometry geo); - void OnIconAdded (void *icon_pointer); - void OnIconRemoved (void *icon_pointer); + void OnIconAdded (LauncherIcon *icon); + void OnIconRemoved (LauncherIcon *icon); void OnOrderChanged (); - void OnIconNeedsRedraw (void *icon); + void OnIconNeedsRedraw (LauncherIcon *icon); void RenderIndicators (nux::GraphicsEngine& GfxContext, - RenderArg const &arg, - int running, - int active, + RenderArg const &arg, + int running, + int active, nux::Geometry geo); - - void RenderIcon (nux::GraphicsEngine& GfxContext, - RenderArg const &arg, - nux::BaseTexture *icon, - nux::Color bkg_color, - float alpha, - nux::Vector4 xform_coords[], + + void RenderIcon (nux::GraphicsEngine& GfxContext, + RenderArg const &arg, + nux::BaseTexture *icon, + nux::Color bkg_color, + float alpha, + nux::Vector4 xform_coords[], nux::Geometry geo); - - void SetIconXForm (LauncherIcon *icon, nux::Matrix4 ViewProjectionMatrix, nux::Geometry geo, - float x, float y, float w, float h, float z, std::string name); + + void SetIconXForm (LauncherIcon *icon, nux::Matrix4 ViewProjectionMatrix, nux::Geometry geo, + float x, float y, float w, float h, float z, std::string name); void UpdateIconXForm (std::list<Launcher::RenderArg> &args); - + LauncherIcon* MouseIconIntersection (int x, int y); void EventLogic (); void MouseDownLogic (int x, int y, unsigned long button_flags, unsigned long key_flags); void MouseUpLogic (int x, int y, unsigned long button_flags, unsigned long key_flags); + + void StartIconDrag (LauncherIcon *icon); + void EndIconDrag (); + void UpdateDragWindowPosition (int x, int y); virtual void PreLayoutManagement(); virtual long PostLayoutManagement(long LayoutResult); virtual void PositionChildLayout(float offsetX, float offsetY); - + + void SetOffscreenRenderTarget (); + void RestoreSystemRenderTarget (); nux::HLayout* m_Layout; int m_ContentOffsetY; @@ -194,9 +219,9 @@ private: LauncherIcon* m_ActiveTooltipIcon; LauncherIcon* m_ActiveMenuIcon; - + QuicklistView* _active_quicklist; - + bool _hovered; bool _floating; bool _autohide; @@ -204,6 +229,7 @@ private: bool _mouse_inside_launcher; bool _mouse_inside_trigger; bool _window_over_launcher; + bool _render_drag_window; float _folded_angle; float _neg_folded_angle; @@ -213,15 +239,21 @@ private: LauncherState _launcher_state; LauncherActionState _launcher_action_state; + LauncherIcon* _icon_under_mouse; LauncherIcon* _icon_mouse_down; + + LauncherIcon* _drag_icon; + LauncherIcon* _drag_icon_under_mouse; int _space_between_icons; int _icon_size; int _icon_image_size; int _icon_image_size_delta; int _icon_glow_size; - int _dnd_delta; + int _dnd_delta_y; + int _dnd_delta_x; + int _launcher_drag_delta; int _dnd_security; int _enter_y; @@ -232,6 +264,8 @@ private: nux::BaseTexture* _icon_2indicator; nux::BaseTexture* _icon_3indicator; nux::BaseTexture* _icon_4indicator; + + nux::IntrusiveSP<nux::IOpenGLBaseTexture> _offscreen_rt_texture; guint _anim_handle; guint _autohide_handle; @@ -247,13 +281,15 @@ private: nux::BaseWindow* _parent; nux::View* _autohide_trigger; LauncherModel* _model; - + LauncherDragWindow* _drag_window; + CompScreen* _screen; - + /* event times */ struct timespec _enter_time; struct timespec _exit_time; struct timespec _drag_end_time; + struct timespec _drag_start_time; struct timespec _autohide_time; }; diff --git a/src/LauncherController.cpp b/src/LauncherController.cpp index 9f69a8f60..242c5d184 100644 --- a/src/LauncherController.cpp +++ b/src/LauncherController.cpp @@ -41,6 +41,8 @@ LauncherController::LauncherController(Launcher* launcher, CompScreen *screen, n g_timeout_add (5000, (GSourceFunc) &LauncherController::BamfTimerCallback, this); InsertExpoAction (); InsertTrash (); + + _launcher->request_reorder.connect (sigc::mem_fun (this, &LauncherController::OnLauncherRequestReorder)); } LauncherController::~LauncherController() @@ -48,22 +50,85 @@ LauncherController::~LauncherController() _favorite_store->UnReference (); } -void -LauncherController::PresentIconOwningWindow (Window window) +void +LauncherController::OnLauncherRequestReorder (LauncherIcon *icon, LauncherIcon *other) { + if (icon == other) + return; + LauncherModel::iterator it; - LauncherIcon *owner = 0; + int i = 0; + int j = 0; + bool skipped = false; for (it = _model->begin (); it != _model->end (); it++) { - if ((*it)->IconOwnsWindow (window)) + if ((*it) == icon) { - owner = *it; - break; + skipped = true; + j++; + continue; + } + + if ((*it) == other) + { + if (!skipped) + { + icon->SetSortPriority (i); + if (i != j) (*it)->SaveCenter (); + i++; + } + + (*it)->SetSortPriority (i); + if (i != j) (*it)->SaveCenter (); + i++; + + if (skipped) + { + icon->SetSortPriority (i); + if (i != j) (*it)->SaveCenter (); + i++; + } + } + else + { + (*it)->SetSortPriority (i); + if (i != j) (*it)->SaveCenter (); + i++; } + j++; + } + + _model->Sort (&LauncherController::CompareIcons); + + std::list<const char*> desktop_paths; + for (it = _model->begin (); it != _model->end (); it++) + { + BamfLauncherIcon *icon; + icon = dynamic_cast<BamfLauncherIcon*> (*it); + + if (!icon) + continue; + + if (!icon->IsSticky ()) + continue; + + const char* desktop_file = icon->DesktopFile (); + + if (desktop_file && strlen (desktop_file) > 0) + desktop_paths.push_back (desktop_file); } - for (it = _model->shelf_begin (); !owner && it != _model->shelf_end (); it++) + _favorite_store->SetFavorites (desktop_paths); +} + +void +LauncherController::PresentIconOwningWindow (Window window) +{ + LauncherModel::iterator it; + LauncherIcon *owner = 0; + + for (it = _model->begin (); it != _model->end (); it++) { if ((*it)->IconOwnsWindow (window)) { @@ -74,7 +139,7 @@ LauncherController::PresentIconOwningWindow (Window window) if (owner) { - owner->Present (2, 600); + owner->Present (0.5f, 600); owner->UpdateQuirkTimeDelayed (300, LAUNCHER_ICON_QUIRK_SHIMMER); } } @@ -82,7 +147,8 @@ LauncherController::PresentIconOwningWindow (Window window) void LauncherController::OnExpoClicked (int button) { - PluginAdapter::Default ()->InitiateExpo (); + if (button == 1) + PluginAdapter::Default ()->InitiateExpo (); } void @@ -135,12 +201,6 @@ LauncherController::RegisterIcon (LauncherIcon *icon) (*it)->SetSortPriority (i); i++; } - - for (it = _model->shelf_begin (); it != _model->shelf_end (); it++) - { - (*it)->SetSortPriority (i); - i++; - } } /* static private */ @@ -193,7 +253,8 @@ LauncherController::CreateFavorite (const char *file_path) bamf_view_set_sticky (BAMF_VIEW (app), true); icon = new BamfLauncherIcon (_launcher, app, _screen); - icon->SetIconType (LAUNCHER_ICON_TYPE_FAVORITE); + icon->SetIconType (LAUNCHER_ICON_TYPE_APPLICATION); + icon->SetSortPriority (_sort_priority++); return icon; } diff --git a/src/LauncherController.h b/src/LauncherController.h index 8fffa56e1..98278866b 100644 --- a/src/LauncherController.h +++ b/src/LauncherController.h @@ -55,6 +55,8 @@ private: FavoriteStore* _favorite_store; int _sort_priority; + void OnLauncherRequestReorder (LauncherIcon *icon, LauncherIcon *other); + void InsertExpoAction (); void InsertTrash (); diff --git a/src/LauncherDragWindow.cpp b/src/LauncherDragWindow.cpp new file mode 100644 index 000000000..75935575c --- /dev/null +++ b/src/LauncherDragWindow.cpp @@ -0,0 +1,63 @@ +/* +* Copyright (C) 2010 Canonical Ltd +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License version 3 as +* published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* Authored by: Jason Smith <jason.smith@canonical.com> +*/ + +#include "Nux/Nux.h" +#include "Nux/BaseWindow.h" +#include "NuxGraphics/GraphicsEngine.h" +#include "Nux/TextureArea.h" + +#include "LauncherDragWindow.h" + +NUX_IMPLEMENT_OBJECT_TYPE (LauncherDragWindow); + +LauncherDragWindow::LauncherDragWindow (nux::IntrusiveSP<nux::IOpenGLBaseTexture> icon) +: nux::BaseWindow ("") +{ + _icon = icon; + SetBaseSize (_icon->GetWidth(), _icon->GetHeight()); +} + +LauncherDragWindow::~LauncherDragWindow () +{ +} + +void LauncherDragWindow::Draw (nux::GraphicsEngine& GfxContext, bool forceDraw) +{ +} + +void LauncherDragWindow::DrawContent (nux::GraphicsEngine& GfxContext, bool force_draw) +{ + nux::Geometry geo = GetGeometry (); + geo.SetX (0); + geo.SetY (0); + + GfxContext.PushClippingRectangle (geo); + + nux::TexCoordXForm texxform; + texxform.FlipVCoord (true); + + GfxContext.QRP_GLSL_1Tex (0, + 0, + _icon->GetWidth(), + _icon->GetHeight(), + _icon, + texxform, + nux::Color::White); + + GfxContext.PopClippingRectangle (); +} diff --git a/src/LauncherDragWindow.h b/src/LauncherDragWindow.h new file mode 100644 index 000000000..e502f0a29 --- /dev/null +++ b/src/LauncherDragWindow.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2010 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Jason Smith <jason.smith@canonical.com> + */ + +#ifndef LAUNCHERDRAGWINDOW_H +#define LAUNCHERDRAGWINDOW_H + +#include "Nux/Nux.h" +#include "Nux/BaseWindow.h" +#include "NuxGraphics/GraphicsEngine.h" + +#include "LauncherIcon.h" + +class LauncherDragWindow : public nux::BaseWindow +{ + NUX_DECLARE_OBJECT_TYPE (LauncherDragWindow, nux::BaseWindow); +public: + LauncherDragWindow (nux::IntrusiveSP<nux::IOpenGLBaseTexture> icon); + + ~LauncherDragWindow (); + + void Draw (nux::GraphicsEngine& gfxContext, + bool forceDraw); + + void DrawContent (nux::GraphicsEngine& gfxContext, + bool forceDraw); + +private: + + nux::IntrusiveSP<nux::IOpenGLBaseTexture> _icon; + + +}; + +#endif // LAUNCHERDRAGWINDOW_H + diff --git a/src/LauncherIcon.cpp b/src/LauncherIcon.cpp index b0fad1cdf..fb0e55fc9 100644 --- a/src/LauncherIcon.cpp +++ b/src/LauncherIcon.cpp @@ -31,6 +31,7 @@ #include "LauncherIcon.h" #include "Launcher.h" +#include "QuicklistManager.h" #include "QuicklistMenuItem.h" #include "QuicklistMenuItemLabel.h" #include "QuicklistMenuItemSeparator.h" @@ -66,9 +67,9 @@ LauncherIcon::LauncherIcon(Launcher* launcher) _sort_priority = 0; _quicklist = new QuicklistView (); - _quicklist->sigVisible.connect (sigc::mem_fun (this, &LauncherIcon::RecvShowQuicklist)); - _quicklist->sigHidden.connect (sigc::mem_fun (this, &LauncherIcon::RecvHideQuicklist)); _quicklist_is_initialized = false; + + QuicklistManager::Default ()->RegisterQuicklist (_quicklist); // Add to introspection AddChild (_quicklist); @@ -99,14 +100,18 @@ LauncherIcon::~LauncherIcon() const gchar * LauncherIcon::GetName () { - return m_TooltipText.GetTCharPtr (); + return "LauncherIcon"; } void LauncherIcon::AddProperties (GVariantBuilder *builder) { + g_variant_builder_add (builder, "{sv}", "x", _center.x); + g_variant_builder_add (builder, "{sv}", "y", _center.y); + g_variant_builder_add (builder, "{sv}", "z", _center.z); g_variant_builder_add (builder, "{sv}", "related-windows", g_variant_new_int32 (_related_windows)); g_variant_builder_add (builder, "{sv}", "icon-type", g_variant_new_int32 (_icon_type)); + g_variant_builder_add (builder, "{sv}", "tooltip-text", g_variant_new_string (m_TooltipText.GetTCharPtr ())); g_variant_builder_add (builder, "{sv}", "sort-priority", g_variant_new_int32 (_sort_priority)); g_variant_builder_add (builder, "{sv}", "quirk-active", g_variant_new_boolean (GetQuirk (LAUNCHER_ICON_QUIRK_ACTIVE))); @@ -288,14 +293,14 @@ nux::NString LauncherIcon::GetTooltipText() void LauncherIcon::RecvMouseEnter () { - if (_launcher->GetActiveQuicklist ()) + if (QuicklistManager::Default ()->Current ()) { // A quicklist is active return; } int tip_x = _launcher->GetBaseWidth () + 1; //icon_x + icon_w; - int tip_y = _center.y; + int tip_y = _center.y + _launcher->GetParent ()->GetGeometry ().y; _tooltip->ShowTooltipWithTipAt (tip_x, tip_y); @@ -314,26 +319,6 @@ void LauncherIcon::RecvMouseDown (int button) { if (button == 3) { - if (_launcher->GetActiveQuicklist () == _quicklist) - { - // this quicklist is already active - return; - } - - if (_launcher->GetActiveQuicklist ()) - { - // Hide the active quicklist. This will prevent it from Ungrabing the pointer in - // QuicklistView::RecvMouseDownOutsideOfQuicklist or void QuicklistView::RecvMouseClick. - // So the new quicklist that is about to be set as active will keep the grab of the pointer. - // Also disable theinput window. - _launcher->GetActiveQuicklist ()->EnableInputWindow (false); - _launcher->GetActiveQuicklist ()->CaptureMouseDownAnyWhereElse (false); - // This call must be last, because after, _launcher->GetActiveQuicklist () will return Null. - // the launcher listen to the sigHidden signal emitted by the BaseWindow when it becomes invisible - // and it set the active window to Null. - _launcher->GetActiveQuicklist ()->ShowWindow (false); - } - _tooltip->ShowWindow (false); _quicklist->RemoveAllMenuItem (); @@ -373,15 +358,9 @@ void LauncherIcon::RecvMouseDown (int button) } int tip_x = _launcher->GetBaseWidth () + 1; //icon_x + icon_w; - int tip_y = _center.y; - _quicklist->ShowQuicklistWithTipAt (tip_x, tip_y); - - _quicklist->EnableInputWindow (true, 1); - _quicklist->GrabPointer (); - + int tip_y = _center.y + _launcher->GetParent ()->GetGeometry ().y; + QuicklistManager::Default ()->ShowQuicklist (_quicklist, tip_x, tip_y); nux::GetWindowCompositor ().SetAlwaysOnFrontWindow (_quicklist); - - _quicklist->NeedRedraw (); } } @@ -394,16 +373,6 @@ void LauncherIcon::RecvMouseUp (int button) } } -void LauncherIcon::RecvShowQuicklist (nux::BaseWindow *quicklist) -{ - _launcher->SetActiveQuicklist (_quicklist); -} - -void LauncherIcon::RecvHideQuicklist (nux::BaseWindow *quicklist) -{ - _launcher->CancelActiveQuicklist (_quicklist); -} - void LauncherIcon::HideTooltip () { _tooltip->ShowWindow (false); @@ -430,10 +399,10 @@ LauncherIcon::SetCenter (nux::Point3 center) _center = center; int tip_x = _launcher->GetBaseWidth () + 1; //icon_x + icon_w; - int tip_y = _center.y; + int tip_y = _center.y + _launcher->GetParent ()->GetGeometry ().y; if (_quicklist->IsVisible ()) - _quicklist->ShowQuicklistWithTipAt (tip_x, tip_y); + QuicklistManager::Default ()->ShowQuicklist (_quicklist, tip_x, tip_y); else if (_tooltip->IsVisible ()) _tooltip->ShowTooltipWithTipAt (tip_x, tip_y); @@ -449,6 +418,13 @@ LauncherIcon::GetCenter () return _center; } +void +LauncherIcon::SaveCenter () +{ + _saved_center = _center; + UpdateQuirkTime (LAUNCHER_ICON_QUIRK_CENTER_SAVED); +} + gboolean LauncherIcon::OnPresentTimeout (gpointer data) { @@ -462,13 +438,13 @@ LauncherIcon::OnPresentTimeout (gpointer data) return false; } -int LauncherIcon::PresentUrgency () +float LauncherIcon::PresentUrgency () { return _present_urgency; } void -LauncherIcon::Present (int present_urgency, int length) +LauncherIcon::Present (float present_urgency, int length) { if (GetQuirk (LAUNCHER_ICON_QUIRK_PRESENTED)) return; @@ -476,7 +452,7 @@ LauncherIcon::Present (int present_urgency, int length) if (length >= 0) _present_time_handle = g_timeout_add (length, &LauncherIcon::OnPresentTimeout, this); - _present_urgency = present_urgency; + _present_urgency = CLAMP (present_urgency, 0.0f, 1.0f); SetQuirk (LAUNCHER_ICON_QUIRK_PRESENTED, true); } @@ -551,9 +527,9 @@ LauncherIcon::SetQuirk (LauncherIconQuirk quirk, bool value) // Present on urgent as a general policy if (quirk == LAUNCHER_ICON_QUIRK_VISIBLE && value) - Present (0, 1500); + Present (0.5f, 1500); if (quirk == LAUNCHER_ICON_QUIRK_URGENT && value) - Present (1, 1500); + Present (0.5f, 1500); } gboolean diff --git a/src/LauncherIcon.h b/src/LauncherIcon.h index 86e615557..43f172235 100644 --- a/src/LauncherIcon.h +++ b/src/LauncherIcon.h @@ -61,6 +61,7 @@ typedef enum LAUNCHER_ICON_QUIRK_PRESENTED, LAUNCHER_ICON_QUIRK_STARTING, LAUNCHER_ICON_QUIRK_SHIMMER, + LAUNCHER_ICON_QUIRK_CENTER_SAVED, LAUNCHER_ICON_QUIRK_LAST, } LauncherIconQuirk; @@ -69,7 +70,7 @@ class LauncherIcon : public Introspectable, public nux::InitiallyUnownedObject, { public: LauncherIcon(Launcher* launcher); - ~LauncherIcon(); + virtual ~LauncherIcon(); void SetTooltipText (const TCHAR* text); @@ -80,18 +81,17 @@ public: void RecvMouseDown (int button); void RecvMouseUp (int button); - void RecvShowQuicklist (nux::BaseWindow *quicklist); - void RecvHideQuicklist (nux::BaseWindow *quicklist); - void HideTooltip (); void SetCenter (nux::Point3 center); nux::Point3 GetCenter (); + void SaveCenter (); + int SortPriority (); int RelatedWindows (); - int PresentUrgency (); + float PresentUrgency (); bool GetQuirk (LauncherIconQuirk quirk); struct timespec GetQuirkTime (LauncherIconQuirk quirk); @@ -105,17 +105,16 @@ public: std::list<DbusmenuMenuitem *> Menus (); - sigc::signal<void, int> MouseDown; sigc::signal<void, int> MouseUp; sigc::signal<void> MouseEnter; sigc::signal<void> MouseLeave; sigc::signal<void, int> MouseClick; - sigc::signal<void, void *> show; - sigc::signal<void, void *> hide; - sigc::signal<void, void *> remove; - sigc::signal<void, void *> needs_redraw; + sigc::signal<void, LauncherIcon *> show; + sigc::signal<void, LauncherIcon *> hide; + sigc::signal<void, LauncherIcon *> remove; + sigc::signal<void, LauncherIcon *> needs_redraw; protected: const gchar * GetName (); void AddProperties (GVariantBuilder *builder); @@ -130,7 +129,7 @@ protected: void Remove (); - void Present (int urgency, int length); + void Present (float urgency, int length); void Unpresent (); void SetIconType (LauncherIconType type); @@ -183,13 +182,14 @@ private: nux::Color _glow_color; int _sort_priority; int _related_windows; - int _present_urgency; + float _present_urgency; guint _present_time_handle; guint _center_stabilize_handle; bool _quicklist_is_initialized; nux::Point3 _center; nux::Point3 _last_stable; + nux::Point3 _saved_center; LauncherIconType _icon_type; bool _quirks[LAUNCHER_ICON_QUIRK_LAST]; diff --git a/src/LauncherModel.cpp b/src/LauncherModel.cpp index c109bd519..2ed6c3a7b 100644 --- a/src/LauncherModel.cpp +++ b/src/LauncherModel.cpp @@ -81,9 +81,10 @@ LauncherModel::RemoveIcon (LauncherIcon *icon) _inner.remove (icon); if (size != _inner.size ()) + { icon_removed.emit (icon); - - icon->UnReference (); + icon->UnReference (); + } } gboolean @@ -98,10 +99,10 @@ LauncherModel::RemoveCallback (gpointer data) } void -LauncherModel::OnIconRemove (void *icon_pointer) +LauncherModel::OnIconRemove (LauncherIcon *icon) { RemoveArg *arg = (RemoveArg*) g_malloc0 (sizeof (RemoveArg)); - arg->icon = (LauncherIcon*) icon_pointer; + arg->icon = icon; arg->self = this; g_timeout_add (1000, &LauncherModel::RemoveCallback, arg); @@ -114,6 +115,7 @@ LauncherModel::Sort (SortFunc func) _inner_main.sort (func); Populate (); + order_changed.emit (); } int diff --git a/src/LauncherModel.h b/src/LauncherModel.h index 6da1b3fda..2c5da9e2c 100644 --- a/src/LauncherModel.h +++ b/src/LauncherModel.h @@ -40,7 +40,7 @@ public: void Sort (SortFunc func); int Size (); - void OnIconRemove (void *icon); + void OnIconRemove (LauncherIcon *icon); iterator begin (); iterator end (); @@ -57,8 +57,8 @@ public: reverse_iterator shelf_rbegin (); reverse_iterator shelf_rend (); - sigc::signal<void, void *> icon_added; - sigc::signal<void, void *> icon_removed; + sigc::signal<void, LauncherIcon *> icon_added; + sigc::signal<void, LauncherIcon *> icon_removed; sigc::signal<void> order_changed; private: diff --git a/src/PluginAdapter.cpp b/src/PluginAdapter.cpp index 535793724..8ccbc4c2d 100644 --- a/src/PluginAdapter.cpp +++ b/src/PluginAdapter.cpp @@ -50,6 +50,49 @@ PluginAdapter::~PluginAdapter() } void +PluginAdapter::NotifyStateChange (CompWindow *window, unsigned int state, unsigned int last_state) +{ + if (!(last_state & MAXIMIZE_STATE) && (state & MAXIMIZE_STATE)) + window_maximized.emit (window); + else if ((last_state & MAXIMIZE_STATE) && !(state & MAXIMIZE_STATE)) + window_restored.emit (window); +} + +void +PluginAdapter::Notify (CompWindow *window, CompWindowNotify notify) +{ + switch (notify) + { + case CompWindowNotifyMinimize: + window_minimized.emit (window); + break; + case CompWindowNotifyUnminimize: + window_unminimized.emit (window); + break; + case CompWindowNotifyShade: + window_shaded.emit (window); + break; + case CompWindowNotifyUnshade: + window_unshaded.emit (window); + break; + case CompWindowNotifyHide: + window_hidden.emit (window); + break; + case CompWindowNotifyShow: + window_shown.emit (window); + break; + case CompWindowNotifyMap: + window_mapped.emit (window); + break; + case CompWindowNotifyUnmap: + window_unmapped.emit (window); + break; + default: + break; + } +} + +void PluginAdapter::SetExpoAction (CompAction *expo) { m_ExpoAction = expo; diff --git a/src/PluginAdapter.h b/src/PluginAdapter.h index e268c3848..6f9d3c287 100644 --- a/src/PluginAdapter.h +++ b/src/PluginAdapter.h @@ -43,6 +43,21 @@ public: void InitiateExpo (); + void NotifyStateChange (CompWindow *window, unsigned int state, unsigned int last_state); + + void Notify (CompWindow *window, CompWindowNotify notify); + + sigc::signal<void, CompWindow *> window_maximized; + sigc::signal<void, CompWindow *> window_restored; + sigc::signal<void, CompWindow *> window_minimized; + sigc::signal<void, CompWindow *> window_unminimized; + sigc::signal<void, CompWindow *> window_shaded; + sigc::signal<void, CompWindow *> window_unshaded; + sigc::signal<void, CompWindow *> window_mapped; + sigc::signal<void, CompWindow *> window_unmapped; + sigc::signal<void, CompWindow *> window_shown; + sigc::signal<void, CompWindow *> window_hidden; + protected: PluginAdapter(CompScreen *screen); diff --git a/src/QuicklistManager.cpp b/src/QuicklistManager.cpp new file mode 100644 index 000000000..940378953 --- /dev/null +++ b/src/QuicklistManager.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2010 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Jamal Fanaian <j@jamalfanaian.com> + */ + +#include "Nux/Nux.h" +#include "Nux/BaseWindow.h" +#include "Nux/VLayout.h" +#include "Nux/WindowCompositor.h" +#include "QuicklistView.h" +#include "QuicklistManager.h" + +QuicklistManager * QuicklistManager::_default = 0; + +/* static */ +QuicklistManager *QuicklistManager::Default () +{ + if (!_default) + _default = new QuicklistManager (); + return _default; +} + +QuicklistManager::QuicklistManager () +{ + _current_quicklist = 0; +} + +QuicklistManager::~QuicklistManager () +{ +} + +QuicklistView *QuicklistManager::Current () +{ + return _current_quicklist; +} + +void QuicklistManager::RegisterQuicklist (QuicklistView *quicklist) +{ + std::list<QuicklistView*>::iterator it; + + if (std::find (_quicklist_list.begin(), _quicklist_list.end(), quicklist) != _quicklist_list.end()) { + // quicklist has already been registered + g_warning ("Attempted to register a quicklist that was previously registered"); + return; + } + + _quicklist_list.push_back (quicklist); + + quicklist->sigVisible.connect (sigc::mem_fun (this, &QuicklistManager::RecvShowQuicklist)); + quicklist->sigHidden.connect (sigc::mem_fun (this, &QuicklistManager::RecvHideQuicklist)); +} + +void QuicklistManager::ShowQuicklist (QuicklistView *quicklist, int tip_x, + int tip_y, bool hide_existing_if_open) +{ + if (_current_quicklist == quicklist) + { + // this quicklist is already active + // do we want to still redraw in case the position has changed? + return; + } + + if (hide_existing_if_open && _current_quicklist) + { + HideQuicklist (_current_quicklist); + } + + quicklist->ShowQuicklistWithTipAt (tip_x, tip_y); +} + +void QuicklistManager::HideQuicklist (QuicklistView *quicklist) +{ + quicklist->Hide(); +} + +void QuicklistManager::RecvShowQuicklist (nux::BaseWindow *window) +{ + QuicklistView *quicklist = (QuicklistView*) window; + + _current_quicklist = quicklist; + + quicklist_opened.emit (quicklist); +} + +void QuicklistManager::RecvHideQuicklist (nux::BaseWindow *window) +{ + QuicklistView *quicklist = (QuicklistView*) window; + + if (_current_quicklist == quicklist) + { + _current_quicklist = 0; + } + + quicklist_closed.emit (quicklist); +} + diff --git a/src/QuicklistManager.h b/src/QuicklistManager.h new file mode 100644 index 000000000..63a271212 --- /dev/null +++ b/src/QuicklistManager.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2010 Canonical Ltd + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Authored by: Jamal Fanaian <j@jamalfanaian.com> + */ + +#ifndef QUICKLISTMANAGER_H +#define QUICKLISTMANAGER_H + +class QuicklistManager : public sigc::trackable +{ +public: + static QuicklistManager *Default (); + + QuicklistManager (); + + ~QuicklistManager (); + + QuicklistView *Current (); + + void RegisterQuicklist (QuicklistView *quicklist); + void ShowQuicklist (QuicklistView *quicklist, int tip_x, int tip_y, bool hide_existing_if_open = true); + void HideQuicklist (QuicklistView *quicklist); + + void RecvShowQuicklist (nux::BaseWindow *window); + void RecvHideQuicklist (nux::BaseWindow *window); + + sigc::signal<void, QuicklistView*> quicklist_opened; + sigc::signal<void, QuicklistView*> quicklist_closed; + +private: + static QuicklistManager *_default; + + std::list<QuicklistView*> _quicklist_list; + QuicklistView *_current_quicklist; + +}; + +#endif + diff --git a/src/QuicklistMenuItemRadio.cpp b/src/QuicklistMenuItemRadio.cpp index 222d774fa..29b2cef25 100644 --- a/src/QuicklistMenuItemRadio.cpp +++ b/src/QuicklistMenuItemRadio.cpp @@ -59,14 +59,9 @@ QuicklistMenuItemRadio::Initialize (DbusmenuMenuitem* item) _item_type = MENUITEM_TYPE_LABEL; if (item) - _text = dbusmenu_menuitem_property_get (item, DBUSMENU_MENUITEM_PROP_LABEL); + _text = g_strdup (dbusmenu_menuitem_property_get (item, DBUSMENU_MENUITEM_PROP_LABEL)); else - _text = "QuicklistItem"; - - _normalTexture[0] = NULL; - _normalTexture[1] = NULL; - _prelightTexture[0] = NULL; - _prelightTexture[1] = NULL; + _text = g_strdup ("Radio Button"); int textWidth = 1; int textHeight = 1; @@ -94,6 +89,15 @@ QuicklistMenuItemRadio::~QuicklistMenuItemRadio () void QuicklistMenuItemRadio::PreLayoutManagement () { + _pre_layout_width = GetBaseWidth (); + _pre_layout_height = GetBaseHeight (); + + if (_normalTexture[0] == 0) + { + UpdateTexture (); + } + + QuicklistMenuItem::PreLayoutManagement (); } long @@ -137,7 +141,7 @@ QuicklistMenuItemRadio::Draw (nux::GraphicsEngine& gfxContext, bool forceDraw) { // Check if the texture have been computed. If they haven't, exit the function. - if (_normalTexture[0] == NULL) + if (!_normalTexture[0]) return; nux::IntrusiveSP<nux::IOpenGLBaseTexture> texture; @@ -154,16 +158,41 @@ QuicklistMenuItemRadio::Draw (nux::GraphicsEngine& gfxContext, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - if (GetActive ()) - if (GetEnabled ()) - texture = _prelightTexture[1]->GetDeviceTexture (); - else + if (GetEnabled ()) + { + if (GetActive () && _prelight) + { texture = _prelightTexture[0]->GetDeviceTexture (); - else - if (GetEnabled ()) + } + else if (GetActive ()) + { + texture = _normalTexture[0]->GetDeviceTexture (); + } + + if ((!GetActive ()) && _prelight) + { + texture = _prelightTexture[1]->GetDeviceTexture (); + } + else if (!GetActive ()) + { texture = _normalTexture[1]->GetDeviceTexture (); + } + + _color = nux::Color::White; + } + else + { + if (GetActive ()) + { + texture = _prelightTexture[0]->GetDeviceTexture (); + } else + { texture = _normalTexture[0]->GetDeviceTexture (); + } + + _color = nux::Color::DarkGray; + } gfxContext.QRP_GLSL_1Tex (base.x, base.y, @@ -193,8 +222,9 @@ QuicklistMenuItemRadio::PostDraw (nux::GraphicsEngine& gfxContext, void QuicklistMenuItemRadio::UpdateTexture () { - int width = GetBaseWidth (); - int height = GetBaseHeight (); + nux::Color transparent = nux::Color (0.0f, 0.0f, 0.0f, 0.0f); + int width = GetBaseWidth (); + int height = GetBaseHeight (); _cairoGraphics = new nux::CairoGraphics (CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = _cairoGraphics->GetContext (); @@ -208,7 +238,7 @@ QuicklistMenuItemRadio::UpdateTexture () cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f); cairo_set_line_width (cr, 1.0f); - DrawText (cr, width, height, _textColor); + DrawText (cr, width, height, nux::Color::White); nux::NBitmapData* bitmap = _cairoGraphics->GetBitmap (); @@ -236,7 +266,7 @@ QuicklistMenuItemRadio::UpdateTexture () cairo_fill (cr); cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f); - DrawText (cr, width, height, _textColor); + DrawText (cr, width, height, nux::Color::White); bitmap = _cairoGraphics->GetBitmap (); @@ -266,7 +296,7 @@ QuicklistMenuItemRadio::UpdateTexture () cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.0f); - DrawText (cr, width, height, _textColor); + DrawText (cr, width, height, transparent); bitmap = _cairoGraphics->GetBitmap (); @@ -299,7 +329,7 @@ QuicklistMenuItemRadio::UpdateTexture () cairo_arc (cr, x, y, radius, 0.0f * (G_PI / 180.0f), 360.0f * (G_PI / 180.0f)); cairo_fill (cr); - DrawText (cr, width, height, _textColor); + DrawText (cr, width, height, transparent); bitmap = _cairoGraphics->GetBitmap (); diff --git a/src/QuicklistMenuItemRadio.h b/src/QuicklistMenuItemRadio.h index 1b0de505c..1961fdaf8 100644 --- a/src/QuicklistMenuItemRadio.h +++ b/src/QuicklistMenuItemRadio.h @@ -39,6 +39,7 @@ class QuicklistMenuItemRadio : public QuicklistMenuItem ~QuicklistMenuItemRadio (); + protected: void PreLayoutManagement (); long PostLayoutManagement (long layoutResult); @@ -56,19 +57,9 @@ class QuicklistMenuItemRadio : public QuicklistMenuItem void PostDraw (nux::GraphicsEngine& gfxContext, bool forceDraw); - private: - nux::NString _text; - nux::Color _textColor; - int _pre_layout_width; - int _pre_layout_height; - nux::CairoGraphics* _cairoGraphics; - - nux::BaseTexture* _normalTexture[2]; - nux::BaseTexture* _prelightTexture[2]; - void Initialize (DbusmenuMenuitem* item); - void UpdateTexture (); + virtual void UpdateTexture (); virtual int CairoSurfaceWidth (); }; diff --git a/src/QuicklistView.cpp b/src/QuicklistView.cpp index c79cc5865..f389ab15d 100644 --- a/src/QuicklistView.cpp +++ b/src/QuicklistView.cpp @@ -92,6 +92,7 @@ QuicklistView::QuicklistView () OnMouseDrag.connect (sigc::mem_fun (this, &QuicklistView::RecvMouseDrag)); _mouse_down = false; + _enable_quicklist_for_testing = false; } QuicklistView::~QuicklistView () @@ -127,6 +128,12 @@ QuicklistView::~QuicklistView () _item_list.clear (); } +void +QuicklistView::EnableQuicklistForTesting (bool enable_testing) +{ + _enable_quicklist_for_testing = enable_testing; +} + void QuicklistView::ShowQuicklistWithTipAt (int anchor_tip_x, int anchor_tip_y) { int window_width; @@ -144,7 +151,7 @@ void QuicklistView::ShowQuicklistWithTipAt (int anchor_tip_x, int anchor_tip_y) SetBaseX (x); SetBaseY (y); - ShowWindow (true); + Show (); } void QuicklistView::ShowWindow (bool b, bool start_modal) @@ -152,6 +159,31 @@ void QuicklistView::ShowWindow (bool b, bool start_modal) BaseWindow::ShowWindow (b, start_modal); } +void QuicklistView::Show () +{ + if (!IsVisible()) + { + // FIXME: ShowWindow shouldn't need to be called first + ShowWindow (true); + EnableInputWindow (true, 1); + GrabPointer (); + NeedRedraw (); + } +} + +void QuicklistView::Hide () +{ + if (IsVisible() && !_enable_quicklist_for_testing) + { + CancelItemsPrelightStatus (); + CaptureMouseDownAnyWhereElse (false); + ForceStopFocus (1, 1); + UnGrabPointer (); + EnableInputWindow (false); + ShowWindow (false); + } +} + long QuicklistView::ProcessEvent (nux::IEvent& ievent, long TraverseInfo, long ProcessEventInfo) { long ret = TraverseInfo; @@ -191,34 +223,17 @@ long QuicklistView::ProcessEvent (nux::IEvent& ievent, long TraverseInfo, long P else { _mouse_down = false; - if (IsVisible ()) - { - CancelItemsPrelightStatus (); - CaptureMouseDownAnyWhereElse (false); - ForceStopFocus (1, 1); - UnGrabPointer (); - EnableInputWindow (false); - ShowWindow (false); - } + Hide (); return nux::eMouseEventSolved; } } else if ((ievent.e_event == nux::NUX_MOUSE_RELEASED) && _mouse_down) { _mouse_down = false; - if (IsVisible ()) - { - CancelItemsPrelightStatus (); - CaptureMouseDownAnyWhereElse (false); - ForceStopFocus (1, 1); - UnGrabPointer (); - EnableInputWindow (false); - ShowWindow (false); - } + Hide (); return nux::eMouseEventSolved; } - - + return ret; } @@ -406,12 +421,7 @@ void QuicklistView::RecvItemMouseClick (QuicklistMenuItem* item, int x, int y) // Check if the mouse was released over an item and emit the signal CheckAndEmitItemSignal (x + item->GetBaseX (), y + item->GetBaseY ()); - CancelItemsPrelightStatus (); - CaptureMouseDownAnyWhereElse (false); - ForceStopFocus (1, 1); - UnGrabPointer (); - EnableInputWindow (false); - ShowWindow (false); + Hide (); } } @@ -460,12 +470,7 @@ void QuicklistView::RecvItemMouseRelease (QuicklistMenuItem* item, int x, int y) // Check if the mouse was released over an item and emit the signal CheckAndEmitItemSignal (x + item->GetBaseX (), y + item->GetBaseY ()); - CancelItemsPrelightStatus (); - CaptureMouseDownAnyWhereElse (false); - ForceStopFocus (1, 1); - UnGrabPointer (); - EnableInputWindow (false); - ShowWindow (false); + Hide (); } } @@ -552,12 +557,7 @@ void QuicklistView::RecvMouseClick (int x, int y, unsigned long button_flags, un { if (IsVisible ()) { - CancelItemsPrelightStatus (); - CaptureMouseDownAnyWhereElse (false); - ForceStopFocus (1, 1); - UnGrabPointer (); - EnableInputWindow (false); - ShowWindow (false); + Hide (); } } @@ -573,15 +573,7 @@ void QuicklistView::RecvMouseDrag (int x, int y, int dx, int dy, unsigned long b void QuicklistView::RecvMouseDownOutsideOfQuicklist (int x, int y, unsigned long button_flags, unsigned long key_flags) { - if (IsVisible ()) - { - CancelItemsPrelightStatus (); - CaptureMouseDownAnyWhereElse (false); - ForceStopFocus (1, 1); - UnGrabPointer (); - EnableInputWindow (false); - ShowWindow (false); - } + Hide (); } void QuicklistView::RemoveAllMenuItem () @@ -1279,26 +1271,29 @@ void QuicklistView::UpdateTexture () return; int size_above_anchor = -1; // equal to sise below - - if ((_item_list.size () != 0) || (_default_item_list.size () != 0)) - { - _top_size = 4; - size_above_anchor = _top_size; - int x = _anchorX - _padding; - int y = _anchorY - _anchor_height/2 - _top_size - _corner_radius - _padding; - SetBaseX (x); - SetBaseY (y); - } - else + if (!_enable_quicklist_for_testing) { - _top_size = 0; - size_above_anchor = -1; - int x = _anchorX - _padding; - int y = _anchorY - _anchor_height/2 - _top_size - _corner_radius - _padding; + if ((_item_list.size () != 0) || (_default_item_list.size () != 0)) + { + _top_size = 4; + size_above_anchor = _top_size; + int x = _anchorX - _padding; + int y = _anchorY - _anchor_height/2 - _top_size - _corner_radius - _padding; + + SetBaseX (x); + SetBaseY (y); + } + else + { + _top_size = 0; + size_above_anchor = -1; + int x = _anchorX - _padding; + int y = _anchorY - _anchor_height/2 - _top_size - _corner_radius - _padding; - SetBaseX (x); - SetBaseY (y); + SetBaseX (x); + SetBaseY (y); + } } float blur_coef = 6.0f; diff --git a/src/QuicklistView.h b/src/QuicklistView.h index 91ad42c00..26974e908 100644 --- a/src/QuicklistView.h +++ b/src/QuicklistView.h @@ -80,6 +80,9 @@ public: void ShowQuicklistWithTipAt (int anchor_tip_x, int anchor_tip_y); virtual void ShowWindow (bool b, bool StartModal = false); + + void Show (); + void Hide (); int GetNumItems (); QuicklistMenuItem* GetNthItems (int index); @@ -91,7 +94,9 @@ public: // Introspection const gchar* GetName (); void AddProperties (GVariantBuilder *builder); - + + void EnableQuicklistForTesting (bool enable_testing); + private: void RecvCairoTextChanged (QuicklistMenuItem* item); void RecvCairoTextColorChanged (QuicklistMenuItem* item); @@ -135,7 +140,11 @@ private: int _top_size; // size of the segment from point 13 to 14. See figure in ql_compute_full_mask_path. bool _mouse_down; - + + //iIf true, suppress the Quicklist behaviour that is expected in Unity. + // Keep the Quicklist on screen for testing and automation. + bool _enable_quicklist_for_testing; + cairo_font_options_t* _fontOpts; nux::BaseTexture* _texture_bg; diff --git a/src/SimpleLauncherIcon.h b/src/SimpleLauncherIcon.h index 7c3cdf7cb..b4359e26f 100644 --- a/src/SimpleLauncherIcon.h +++ b/src/SimpleLauncherIcon.h @@ -27,7 +27,7 @@ class SimpleLauncherIcon : public LauncherIcon { public: SimpleLauncherIcon(Launcher* IconManager); - ~SimpleLauncherIcon(); + virtual ~SimpleLauncherIcon(); /* override */ nux::BaseTexture * GetTextureForSize (int size); diff --git a/src/TrashLauncherIcon.cpp b/src/TrashLauncherIcon.cpp index 7f7caac71..24c24ba9b 100644 --- a/src/TrashLauncherIcon.cpp +++ b/src/TrashLauncherIcon.cpp @@ -18,6 +18,8 @@ #include "TrashLauncherIcon.h" +#include <gio/gio.h> + TrashLauncherIcon::TrashLauncherIcon (Launcher* IconManager) : SimpleLauncherIcon(IconManager) { @@ -26,10 +28,23 @@ TrashLauncherIcon::TrashLauncherIcon (Launcher* IconManager) SetQuirk (LAUNCHER_ICON_QUIRK_VISIBLE, true); SetQuirk (LAUNCHER_ICON_QUIRK_RUNNING, false); SetIconType (LAUNCHER_ICON_TYPE_TRASH); + + m_TrashMonitor = g_file_monitor_directory (g_file_new_for_uri("trash:///"), + G_FILE_MONITOR_NONE, + NULL, + NULL); + + g_signal_connect(m_TrashMonitor, + "changed", + G_CALLBACK (&TrashLauncherIcon::OnTrashChanged), + this); + + UpdateTrashIcon (); } TrashLauncherIcon::~TrashLauncherIcon() { + g_object_unref (m_TrashMonitor); } void @@ -38,10 +53,58 @@ TrashLauncherIcon::OnMouseClick (int button) if (button == 1) { GError *error = NULL; - + g_spawn_command_line_async ("xdg-open trash://", &error); - + if (error) g_error_free (error); } } + +void +TrashLauncherIcon::UpdateTrashIcon () +{ + GFile *location; + location = g_file_new_for_uri ("trash:///"); + + g_file_query_info_async (location, + G_FILE_ATTRIBUTE_STANDARD_ICON, + G_FILE_QUERY_INFO_NONE, + 0, + NULL, + &TrashLauncherIcon::UpdateTrashIconCb, + this); + + g_object_unref(location); +} + +void +TrashLauncherIcon::UpdateTrashIconCb (GObject *source, + GAsyncResult *res, + gpointer data) +{ + TrashLauncherIcon *self = (TrashLauncherIcon*) data; + GFileInfo *info; + GIcon *icon; + + info = g_file_query_info_finish (G_FILE (source), res, NULL); + + if (info != NULL) { + icon = g_file_info_get_icon (info); + self->SetIconName (g_icon_to_string (icon)); + + g_object_unref(info); + } +} + +void +TrashLauncherIcon::OnTrashChanged (GFileMonitor *monitor, + GFile *file, + GFile *other_file, + GFileMonitorEvent event_type, + gpointer data) +{ + TrashLauncherIcon *self = (TrashLauncherIcon*) data; + self->UpdateTrashIcon (); +} + diff --git a/src/TrashLauncherIcon.h b/src/TrashLauncherIcon.h index 1680c5502..c07e1a3fe 100644 --- a/src/TrashLauncherIcon.h +++ b/src/TrashLauncherIcon.h @@ -30,6 +30,13 @@ public: protected: void OnMouseClick (int button); + void UpdateTrashIcon (); + +private: + GFileMonitor *m_TrashMonitor; + static void UpdateTrashIconCb (GObject *source, GAsyncResult *res, gpointer data); + static void OnTrashChanged (GFileMonitor *monitor, GFile *file, GFile *other_file, + GFileMonitorEvent event_type, gpointer data); }; diff --git a/src/unity.cpp b/src/unity.cpp index 1c5cd9a6e..7e6e38064 100644 --- a/src/unity.cpp +++ b/src/unity.cpp @@ -39,6 +39,8 @@ #include <core/atoms.h> +#include "../libunity/perf-logger-utility.h" + /* Set up vtable symbols */ COMPIZ_PLUGIN_20090315 (unityshell, UnityPluginVTable); @@ -107,7 +109,7 @@ UnityScreen::glPaintOutput (const GLScreenPaintAttrib &attrib, doShellRepaint = true; allowWindowPaint = true; - + /* glPaintOutput is part of the opengl plugin, so we need the GLScreen base class. */ ret = gScreen->glPaintOutput (attrib, transform, region, output, mask); @@ -139,17 +141,17 @@ UnityScreen::damageNuxRegions () std::vector<nux::Geometry>::iterator it; std::vector<nux::Geometry> dirty = wt->GetDrawList (); nux::Geometry geo; - + for (it = dirty.begin (); it != dirty.end (); it++) { geo = *it; cScreen->damageRegion (CompRegion (geo.x, geo.y, geo.width, geo.height)); } - + geo = wt->GetWindowCompositor ().GetTooltipMainWindowGeometry(); cScreen->damageRegion (CompRegion (geo.x, geo.y, geo.width, geo.height)); cScreen->damageRegion (CompRegion (lastTooltipArea.x, lastTooltipArea.y, lastTooltipArea.width, lastTooltipArea.height)); - + lastTooltipArea = geo; wt->ClearDrawList (); @@ -165,7 +167,7 @@ UnityScreen::handleEvent (XEvent *event) { wt->ProcessForeignEvent (event, NULL); } -} +} gboolean @@ -258,7 +260,7 @@ UnityScreen::getWindowPaintList () * stacked on top of one of the nux input windows * and if so paint nux and stop us from painting * other windows or on top of the whole screen */ -bool +bool UnityWindow::glDraw (const GLMatrix &matrix, GLFragment::Attrib &attrib, const CompRegion ®ion, @@ -286,20 +288,57 @@ UnityWindow::glDraw (const GLMatrix &matrix, void UnityWindow::windowNotify (CompWindowNotify n) { - if (n == CompWindowNotifyMinimize) - uScreen->controller->PresentIconOwningWindow (window->id ()); + PluginAdapter::Default ()->Notify (window, n); + + switch (n) + { + case CompWindowNotifyMinimize: + uScreen->controller->PresentIconOwningWindow (window->id ()); + uScreen->launcher->OnWindowDisappear (window); + break; + case CompWindowNotifyUnminimize: + uScreen->launcher->OnWindowAppear (window); + break; + case CompWindowNotifyShade: + uScreen->launcher->OnWindowDisappear (window); + break; + case CompWindowNotifyUnshade: + uScreen->launcher->OnWindowAppear (window); + break; + case CompWindowNotifyHide: + uScreen->launcher->OnWindowDisappear (window); + break; + case CompWindowNotifyShow: + uScreen->launcher->OnWindowAppear (window); + break; + case CompWindowNotifyMap: + uScreen->launcher->OnWindowAppear (window); + break; + case CompWindowNotifyUnmap: + uScreen->launcher->OnWindowDisappear (window); + break; + default: + break; + } window->windowNotify (n); } void +UnityWindow::stateChangeNotify (unsigned int lastState) +{ + PluginAdapter::Default ()->NotifyStateChange (window, window->state (), lastState); + window->stateChangeNotify (lastState); +} + +void UnityWindow::moveNotify (int x, int y, bool immediate) { uScreen->launcher->OnWindowMoved (window); window->moveNotify (x, y, immediate); } -void +void UnityWindow::resizeNotify (int x, int y, int w, int h) { uScreen->launcher->OnWindowResized (window); @@ -307,7 +346,7 @@ UnityWindow::resizeNotify (int x, int y, int w, int h) } /* Configure callback for the launcher window */ -void +void UnityScreen::launcherWindowConfigureCallback(int WindowWidth, int WindowHeight, nux::Geometry& geo, void *user_data) { int OurWindowHeight = WindowHeight - 24; @@ -315,23 +354,25 @@ UnityScreen::launcherWindowConfigureCallback(int WindowWidth, int WindowHeight, } /* Configure callback for the panel window */ -void +void UnityScreen::panelWindowConfigureCallback(int WindowWidth, int WindowHeight, nux::Geometry& geo, void *user_data) { geo = nux::Geometry(0, 0, WindowWidth, 24); } /* Start up nux after OpenGL is initialized */ -void +void UnityScreen::initUnity(nux::NThread* thread, void* InitData) { + START_FUNCTION (); initLauncher(thread, InitData); - + nux::ColorLayer background(nux::Color(0x00000000)); static_cast<nux::WindowThread*>(thread)->SetWindowBackgroundPaintLayer(&background); + END_FUNCTION (); } -void +void UnityScreen::onRedrawRequested () { damageNuxRegions (); @@ -356,6 +397,13 @@ UnityScreen::optionChanged (CompOption *opt, } } +static gboolean +write_logger_data_to_disk (gpointer data) +{ + perf_timeline_logger_write_log (perf_timeline_logger_get_default (), "/tmp/unity-perf.log"); + return FALSE; +} + UnityScreen::UnityScreen (CompScreen *screen) : PluginClassHandler <UnityScreen, CompScreen> (screen), screen (screen), @@ -363,30 +411,31 @@ UnityScreen::UnityScreen (CompScreen *screen) : gScreen (GLScreen::get (screen)), doShellRepaint (false) { + START_FUNCTION (); int (*old_handler) (Display *, XErrorEvent *); old_handler = XSetErrorHandler (NULL); - + g_thread_init (NULL); dbus_g_thread_init (); gtk_init (NULL, NULL); - + XSetErrorHandler (old_handler); /* Wrap compiz interfaces */ ScreenInterface::setHandler (screen); CompositeScreenInterface::setHandler (cScreen); GLScreenInterface::setHandler (gScreen); - + StartupNotifyService::Default ()->SetSnDisplay (screen->snDisplay (), screen->screenNum ()); nux::NuxInitialize (0); - wt = nux::CreateFromForeignWindow (cScreen->output (), - glXGetCurrentContext (), + wt = nux::CreateFromForeignWindow (cScreen->output (), + glXGetCurrentContext (), &UnityScreen::initUnity, this); - + wt->RedrawRequested.connect (sigc::mem_fun (this, &UnityScreen::onRedrawRequested)); - + wt->Run (NULL); uScreen = this; @@ -398,6 +447,7 @@ UnityScreen::UnityScreen (CompScreen *screen) : optionSetLauncherFloatNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); g_timeout_add (0, &UnityScreen::initPluginActions, this); + END_FUNCTION (); } UnityScreen::~UnityScreen () @@ -407,25 +457,28 @@ UnityScreen::~UnityScreen () /* Can't create windows until after we have initialized everything */ gboolean UnityScreen::strutHackTimeout (gpointer data) { - UnityScreen *self = (UnityScreen*) data; - + UnityScreen *self = (UnityScreen*) data; + if (!self->launcher->AutohideEnabled ()) { self->launcherWindow->InputWindowEnableStruts(false); self->launcherWindow->InputWindowEnableStruts(true); } - + self->panelWindow->InputWindowEnableStruts(false); self->panelWindow->InputWindowEnableStruts(true); - + return FALSE; } /* Start up the launcher */ void UnityScreen::initLauncher (nux::NThread* thread, void* InitData) { + START_FUNCTION (); + UnityScreen *self = (UnityScreen*) InitData; - + + LOGGER_START_PROCESS ("initLauncher-Launcher"); self->launcherWindow = new nux::BaseWindow(TEXT("")); self->launcher = new Launcher(self->launcherWindow, self->screen); self->AddChild (self->launcher); @@ -448,8 +501,10 @@ void UnityScreen::initLauncher (nux::NThread* thread, void* InitData) self->launcherWindow->InputWindowEnableStruts(true); self->launcher->SetIconSize (54, 48); + LOGGER_END_PROCESS ("initLauncher-Launcher"); /* Setup panel */ + LOGGER_START_PROCESS ("initLauncher-Panel"); self->panelView = new PanelView (); self->AddChild (self->panelView); @@ -468,10 +523,12 @@ void UnityScreen::initLauncher (nux::NThread* thread, void* InitData) self->panelWindow->SetBackgroundColor(nux::Color(0x00000000)); self->panelWindow->SetBlurredBackground(false); self->panelWindow->ShowWindow(true); - self->panelWindow->EnableInputWindow(true); + self->panelWindow->EnableInputWindow(true); self->panelWindow->InputWindowEnableStruts(true); - + LOGGER_END_PROCESS ("initLauncher-Panel"); g_timeout_add (2000, &UnityScreen::strutHackTimeout, self); + + END_FUNCTION (); } /* Window init */ diff --git a/src/unity.h b/src/unity.h index cec421f57..fb594188f 100644 --- a/src/unity.h +++ b/src/unity.h @@ -174,6 +174,8 @@ class UnityWindow : void moveNotify (int x, int y, bool immediate); void resizeNotify (int x, int y, int w, int h); + + void stateChangeNotify (unsigned int lastState); }; #define EX_SCREEN (screen) \ |
