summaryrefslogtreecommitdiff
path: root/src
diff options
authorNeil Jagdish Patel <neil.patel@canonical.com>2010-12-15 17:49:31 +0000
committerNeil Jagdish Patel <neil.patel@canonical.com>2010-12-15 17:49:31 +0000
commitf7002672fe68fbc14f72dcd92f57082c8579ccb2 (patch)
treee130352a9d55d129f601dfc9bcbcef0f39a37ef4 /src
parent3c334f733bc2b6d0186f8e9587eee807357fc0bc (diff)
parentf7c5941bf0726cf999588dfc894708c450add15b (diff)
[merge] trunk
(bzr r669.3.9)
Diffstat (limited to 'src')
-rw-r--r--src/BamfLauncherIcon.cpp325
-rw-r--r--src/BamfLauncherIcon.h27
-rw-r--r--src/FavoriteStore.h1
-rw-r--r--src/FavoriteStoreGSettings.cpp30
-rw-r--r--src/FavoriteStoreGSettings.h1
-rw-r--r--src/Launcher.cpp1011
-rw-r--r--src/Launcher.h144
-rw-r--r--src/LauncherController.cpp93
-rw-r--r--src/LauncherController.h2
-rw-r--r--src/LauncherDragWindow.cpp63
-rw-r--r--src/LauncherDragWindow.h50
-rw-r--r--src/LauncherIcon.cpp76
-rw-r--r--src/LauncherIcon.h24
-rw-r--r--src/LauncherModel.cpp10
-rw-r--r--src/LauncherModel.h6
-rw-r--r--src/PluginAdapter.cpp43
-rw-r--r--src/PluginAdapter.h15
-rw-r--r--src/QuicklistManager.cpp109
-rw-r--r--src/QuicklistManager.h52
-rw-r--r--src/QuicklistMenuItemRadio.cpp70
-rw-r--r--src/QuicklistMenuItemRadio.h13
-rw-r--r--src/QuicklistView.cpp125
-rw-r--r--src/QuicklistView.h13
-rw-r--r--src/SimpleLauncherIcon.h2
-rw-r--r--src/TrashLauncherIcon.cpp67
-rw-r--r--src/TrashLauncherIcon.h7
-rw-r--r--src/unity.cpp113
-rw-r--r--src/unity.h2
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 &current)
return 1.0f - CLAMP ((float) (TimeDelta (&current, &_drag_end_time)) / (float) ANIM_DURATION_LONG, 0.0f, 1.0f);
}
+float Launcher::DnDStartProgress (struct timespec const &current)
+{
+ return CLAMP ((float) (TimeDelta (&current, &_drag_start_time)) / (float) ANIM_DURATION, 0.0f, 1.0f);
+}
+
float Launcher::AutohideProgress (struct timespec const &current)
{
if (!_autohide)
return 0.0f;
-
+
if (_hidden)
return CLAMP ((float) (TimeDelta (&current, &_autohide_time)) / (float) ANIM_DURATION_SHORT, 0.0f, 1.0f);
else
@@ -327,26 +346,13 @@ float Launcher::AutohideProgress (struct timespec const &current)
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 &current)
@@ -354,27 +360,32 @@ bool Launcher::IconNeedsAnimation (LauncherIcon *icon, struct timespec const &cu
struct timespec time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_VISIBLE);
if (TimeDelta (&current, &time) < ANIM_DURATION_SHORT)
return true;
-
+
time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_RUNNING);
if (TimeDelta (&current, &time) < ANIM_DURATION_SHORT)
return true;
-
+
time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_STARTING);
if (TimeDelta (&current, &time) < (ANIM_DURATION_LONG * MAX_STARTING_BLINKS * STARTING_BLINK_LAMBDA * 2))
return true;
-
+
time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_URGENT);
if (TimeDelta (&current, &time) < (ANIM_DURATION_LONG * URGENT_BLINKS * 2))
return true;
-
+
time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_PRESENTED);
if (TimeDelta (&current, &time) < ANIM_DURATION)
return true;
-
+
time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_SHIMMER);
if (TimeDelta (&current, &time) < ANIM_DURATION_LONG)
return true;
-
+
+ time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_CENTER_SAVED);
+ if (TimeDelta (&current, &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, &current);
-
+
// hover in animation
if (TimeDelta (&current, &_enter_time) < ANIM_DURATION)
return true;
-
+
// hover out animation
if (TimeDelta (&current, &_exit_time) < ANIM_DURATION)
return true;
+ // drag start animation
+ if (TimeDelta (&current, &_drag_start_time) < ANIM_DURATION)
+ return true;
+
// drag end animation
if (TimeDelta (&current, &_drag_end_time) < ANIM_DURATION_LONG)
return true;
-
+
if (TimeDelta (&current, &_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, &current);
-
+
if (sister)
{
int diff = TimeDelta (&current, 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 (&current, &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 (&current, &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 &current)
+{
+ struct timespec save_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_CENTER_SAVED);
+ int save_ms = TimeDelta (&current, &save_time);
+ return CLAMP ((float) save_ms / (float) ANIM_DURATION, 0.0f, 1.0f);
+}
+
float Launcher::IconUrgentPulseValue (LauncherIcon *icon, struct timespec const &current)
{
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 (&current, &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 &curren
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 &center,
+ float folding_threshold,
+ float folded_size,
+ float folded_spacing,
+ float autohide_offset,
+ float folded_z_distance,
+ float animation_neg_rads,
+ struct timespec const &current)
+{
+ 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, &current);
-
+
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, &current);
+
+ 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 &current);
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 &current);
- float GetHoverProgress (struct timespec const &current);
- float AutohideProgress (struct timespec const &current);
+
+ float DnDStartProgress (struct timespec const &current);
+ float DnDExitProgress (struct timespec const &current);
+ float GetHoverProgress (struct timespec const &current);
+ float AutohideProgress (struct timespec const &current);
float IconPresentProgress (LauncherIcon *icon, struct timespec const &current);
float IconUrgentProgress (LauncherIcon *icon, struct timespec const &current);
float IconShimmerProgress (LauncherIcon *icon, struct timespec const &current);
float IconUrgentPulseValue (LauncherIcon *icon, struct timespec const &current);
float IconStartingPulseValue (LauncherIcon *icon, struct timespec const &current);
float IconBackgroundIntensity (LauncherIcon *icon, struct timespec const &current);
+ float IconCenterTransitionProgress (LauncherIcon *icon, struct timespec const &current);
void SetHover ();
void UnsetHover ();
void SetHidden (bool hidden);
-
+
void SetDndDelta (float x, float y, nux::Geometry geo, struct timespec const &current);
float DragLimiter (float x);
-
+
void SetupRenderArg (LauncherIcon *icon, struct timespec const &current, RenderArg &arg);
- void RenderArgs (std::list<Launcher::RenderArg> &launcher_args,
+ void FillRenderArg (LauncherIcon *icon,
+ RenderArg &arg,
+ nux::Point3 &center,
+ float folding_threshold,
+ float folded_size,
+ float folded_spacing,
+ float autohide_offset,
+ float folded_z_distance,
+ float animation_neg_rads,
+ struct timespec const &current);
+
+ 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 &region,
@@ -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) \