summaryrefslogtreecommitdiff
diff options
authorDidier Roche <didier.roche@canonical.com>2010-11-30 17:02:47 +0100
committerDidier Roche <didier.roche@canonical.com>2010-11-30 17:02:47 +0100
commit431332d7c1baa3cfee23932a5697550625f81218 (patch)
treed152884cba50462a5e2448853bc85dc7b6d607b9
parent56b431154e74af003cedc17ae3669d636a926f20 (diff)
parentcf53d4b7b8a1939379fef00e1e1cb0d8b964f44c (diff)
Import upstream version 3.2.2upstream-3.2.2
(bzr r55.4.35)
-rw-r--r--CMakeLists.txt2
-rw-r--r--com.canonical.Unity.gschema.xml2
-rw-r--r--libunity/ubus-server.c194
-rw-r--r--libunity/ubus-server.h26
-rw-r--r--po/unity.pot2
-rw-r--r--services/CMakeLists.txt1
-rw-r--r--services/panel-service.c43
-rw-r--r--src/BamfLauncherIcon.cpp424
-rw-r--r--src/BamfLauncherIcon.h8
-rw-r--r--src/FavoriteStoreGSettings.cpp2
-rw-r--r--src/Launcher.cpp115
-rw-r--r--src/Launcher.h20
-rw-r--r--src/LauncherController.cpp29
-rwxr-xr-xsrc/LauncherIcon.cpp124
-rw-r--r--src/LauncherIcon.h14
-rw-r--r--src/PanelHomeButton.cpp37
-rw-r--r--src/PanelHomeButton.h2
-rw-r--r--src/PanelIndicatorObjectEntryView.cpp1
-rw-r--r--[-rwxr-xr-x]src/QuicklistMenuItem.cpp22
-rwxr-xr-xsrc/QuicklistMenuItem.h9
-rwxr-xr-xsrc/QuicklistMenuItemCheckmark.cpp18
-rwxr-xr-xsrc/QuicklistMenuItemLabel.cpp10
-rwxr-xr-xsrc/QuicklistMenuItemRadio.cpp17
-rwxr-xr-xsrc/QuicklistMenuItemSeparator.cpp40
-rwxr-xr-xsrc/QuicklistMenuItemSeparator.h2
-rw-r--r--[-rwxr-xr-x]src/QuicklistView.cpp227
-rwxr-xr-xsrc/QuicklistView.h14
-rw-r--r--src/unity.cpp16
-rw-r--r--src/unity.h4
-rw-r--r--tests/unit/TestUBus.cpp39
-rwxr-xr-xtools/migrate_favorites.py6
31 files changed, 954 insertions, 516 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3f2385254..48586e7ec 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,7 +9,7 @@ subdirs (libunity services tests tools)
set (PROJECT_NAME "unity")
set (UNITY_MAJOR 3)
set (UNITY_MINOR 2)
-set (UNITY_MICRO 0)
+set (UNITY_MICRO 2)
set (UNITY_VERSION "${UNITY_MAJOR}.${UNITY_MINOR}.${UNITY_MICRO}")
set (UNITY_API_VERSION "3.0")
diff --git a/com.canonical.Unity.gschema.xml b/com.canonical.Unity.gschema.xml
index 7172831f7..58b2ca719 100644
--- a/com.canonical.Unity.gschema.xml
+++ b/com.canonical.Unity.gschema.xml
@@ -1,7 +1,7 @@
<schemalist>
<schema path="/desktop/unity/launcher/" id="com.canonical.Unity.Launcher" gettext-domain="unity">
<key type="as" name="favorites">
- <default>[ 'ubiquity-gtkui.desktop', 'nautilus.desktop', 'firefox.desktop', 'empathy.desktop', 'ubuntuone-control-panel-gtk.desktop', 'tomboy.desktop' ]</default>
+ <default>[ 'ubiquity-gtkui.desktop', 'nautilus.desktop', 'firefox.desktop', 'ubuntuone-control-panel-gtk.desktop', 'tomboy.desktop' ]</default>
<summary>List of desktop file ids for favorites on the launcher.</summary>
<description>These applications are shown in the Launcher by default.</description>
</key>
diff --git a/libunity/ubus-server.c b/libunity/ubus-server.c
index 54df70948..48126d64e 100644
--- a/libunity/ubus-server.c
+++ b/libunity/ubus-server.c
@@ -30,13 +30,14 @@
struct _UBusServerPrivate
{
- GHashTable *message_interest_table;
- GHashTable *dispatch_table;
+ GHashTable *message_interest_table;
+ GHashTable *dispatch_table;
- GQueue *message_queue;
+ GQueue *message_queue;
+ GStringChunk *message_names;
- gulong id_sequencial_number;
- gboolean message_pump_queued;
+ guint id_sequencial_number;
+ gboolean message_pump_queued;
};
@@ -44,16 +45,18 @@ G_DEFINE_TYPE (UBusServer, ubus_server, G_TYPE_INITIALLY_UNOWNED);
struct _UBusDispatchInfo
{
- gulong id;
- UBusCallback callback;
- gchar *message;
- gpointer *user_data;
+ guint id;
+ UBusCallback callback;
+ gchar *message;
+ gpointer *user_data;
};
typedef struct _UBusDispatchInfo UBusDispatchInfo;
UBusDispatchInfo *
-ubus_dispatch_info_new (UBusServer* server, const gchar *message,
- UBusCallback callback, gpointer user_data)
+ubus_dispatch_info_new (UBusServer *server,
+ const gchar *message,
+ UBusCallback callback,
+ gpointer user_data)
{
g_return_val_if_fail (UBUS_IS_SERVER (server), NULL);
UBusServerPrivate *priv = server->priv;
@@ -64,10 +67,10 @@ ubus_dispatch_info_new (UBusServer* server, const gchar *message,
g_critical (G_STRLOC ": ID's are overflowing");
}
- info = g_new (UBusDispatchInfo, 1);
+ info = g_slice_new (UBusDispatchInfo);
info->id = priv->id_sequencial_number++;
info->callback = callback;
- info->message = g_strdup (message);
+ info->message = g_string_chunk_insert_const (priv->message_names, message);
info->user_data = user_data;
return info;
@@ -76,8 +79,7 @@ ubus_dispatch_info_new (UBusServer* server, const gchar *message,
void
ubus_dispatch_info_free (UBusDispatchInfo *info)
{
- g_free (info->message);
- g_free (info);
+ g_slice_free (UBusDispatchInfo, info);
}
struct _UBusMessageInfo
@@ -88,78 +90,90 @@ struct _UBusMessageInfo
typedef struct _UBusMessageInfo UBusMessageInfo;
-UBusMessageInfo *
-ubus_message_info_new (const gchar *message, GVariant *data)
+/*
+ * If @data is floating the constructed message info will
+ * assume ownership of the ref.
+ *
+ * The message member of the UBusMessageInfo struct is managed
+ * by the UBusServer owning the message. This is done to have
+ * "interned" strings representing the message names.
+ *
+ * Technically the interning is done with g_string_chunk_insert_const().
+ * This not only gives us imporved memory management, but also allows
+ * us to compare message names with direct pointer comparison.
+ */
+static UBusMessageInfo*
+ubus_message_info_new (GVariant *data)
{
- UBusMessageInfo *info = g_new (UBusMessageInfo, 1);
- info->message = g_strdup (message);
+ UBusMessageInfo *info;
+
+ info = g_slice_new (UBusMessageInfo);
info->data = data;
if (data != NULL)
- g_variant_ref (data);
+ g_variant_ref_sink (data);
+
return info;
}
-void
+static void
ubus_message_info_free (UBusMessageInfo *info)
{
- g_variant_unref (info->data);
- g_free (info->message);
- g_free (info);
-}
-
-gboolean
-ulong_equal (gconstpointer v1,
- gconstpointer v2)
-{
- return *((const gulong*) v1) == *((const gulong*) v2);
-}
-
-guint
-ulong_hash (gconstpointer v)
-{
- return (guint) *(const gulong*) v;
+ if (info->data != NULL)
+ g_variant_unref (info->data);
+
+ g_slice_free (UBusMessageInfo, info);
}
static void
ubus_server_init (UBusServer *server)
{
UBusServerPrivate *priv;
+
priv = server->priv = UBUS_SERVER_GET_PRIVATE (server);
- // message_interest_table holds the message/DispatchInfo relationship
- priv->message_interest_table = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free,
- (GDestroyNotify)g_sequence_free);
- // dispatch table holds the individial id/DispatchInfo pairs
- priv->dispatch_table = g_hash_table_new_full (ulong_hash, ulong_equal,
- g_free,
- (GDestroyNotify)ubus_dispatch_info_free);
+ /* message_interest_table holds the message/DispatchInfo relationship
+ * We can use g_direct_* hash functions because we are interning all
+ * message names in our GStringChunk
+ */
+ priv->message_interest_table = g_hash_table_new_full (g_direct_hash,
+ g_direct_equal,
+ NULL,
+ (GDestroyNotify) g_sequence_free);
+ // dispatch_table holds the individial id/DispatchInfo pairs
+ priv->dispatch_table = g_hash_table_new_full (g_direct_hash,
+ g_direct_equal,
+ NULL,
+ (GDestroyNotify) ubus_dispatch_info_free);
// for anyone thats wondering (hi kamstrup!), there are two hash tables so
// that lookups are fast when sending messages and removing handlers
priv->message_queue = g_queue_new ();
+ priv->message_names = g_string_chunk_new (512);
priv->id_sequencial_number = 1;
}
static void
ubus_server_finalize (GObject *object)
{
- UBusServer *server = UBUS_SERVER (object);
- UBusServerPrivate *priv = server->priv;
+ UBusServer *server;
+ UBusServerPrivate *priv;
+
+ server = UBUS_SERVER (object);
+ priv = server->priv;
+
g_hash_table_destroy (priv->message_interest_table);
g_hash_table_destroy (priv->dispatch_table);
UBusMessageInfo *info = g_queue_pop_tail (priv->message_queue);
for (; info != NULL; info = g_queue_pop_tail (priv->message_queue))
{
- if (info->data != NULL)
- g_variant_unref (info->data);
- g_free (info);
+ ubus_message_info_free (info);
}
g_queue_free (priv->message_queue);
+ g_string_chunk_free (priv->message_names);
G_OBJECT_CLASS (ubus_server_parent_class)->finalize (object);
}
@@ -175,10 +189,11 @@ ubus_server_class_init (UBusServerClass *klass)
UBusServer *
ubus_server_get_default ()
{
+ UBusServer *server;
static gsize singleton;
+
if (g_once_init_enter (&singleton))
- {
- UBusServer *server;
+ {
server = g_object_new (UBUS_TYPE_SERVER, NULL);
g_object_ref_sink (server);
g_once_init_leave (&singleton, (gsize) server);
@@ -190,31 +205,37 @@ ubus_server_get_default ()
return (UBusServer *)singleton;
}
-gulong
-ubus_server_register_interest (UBusServer* server, const gchar *message,
- UBusCallback callback, gpointer user_data)
+guint
+ubus_server_register_interest (UBusServer *server,
+ const gchar *message,
+ UBusCallback callback,
+ gpointer user_data)
{
+ UBusServerPrivate *priv;
+ GSequence *dispatch_list;
+ gchar *interned_message;
+ UBusDispatchInfo *info;
+
g_return_val_if_fail (UBUS_IS_SERVER (server), 0);
g_return_val_if_fail (message != NULL, 0);
- UBusServerPrivate *priv = server->priv;
- GSequence *dispatch_list = g_hash_table_lookup (priv->message_interest_table,
- message);
- UBusDispatchInfo *info;
+ priv = server->priv;
+ interned_message = g_string_chunk_insert_const (priv->message_names, message);
+ dispatch_list = g_hash_table_lookup (priv->message_interest_table,
+ interned_message);
if (dispatch_list == NULL)
{
// not had this message before so add a new entry to the message_interest table
- gchar *key = g_strdup (message);
dispatch_list = g_sequence_new (NULL); // we use a sequence because its a stable pointer
- g_hash_table_insert (priv->message_interest_table, key, dispatch_list);
+ g_hash_table_insert (priv->message_interest_table,
+ interned_message,
+ dispatch_list);
}
// add the callback to the dispatch table
info = ubus_dispatch_info_new (server, message, callback, user_data);
- gulong *id = g_malloc (sizeof (gulong));
- *id = info->id;
- g_hash_table_insert (priv->dispatch_table, id, info);
+ g_hash_table_insert (priv->dispatch_table, GUINT_TO_POINTER (info->id), info);
// add the dispatch info to the dispatch list in the message interest table
g_sequence_append (dispatch_list, info);
@@ -222,7 +243,7 @@ ubus_server_register_interest (UBusServer* server, const gchar *message,
return info->id;
}
-gboolean
+static gboolean
ubus_server_pump_message_queue (UBusServer *server)
{
g_return_val_if_fail (UBUS_IS_SERVER (server), FALSE);
@@ -261,20 +282,20 @@ ubus_server_pump_message_queue (UBusServer *server)
iter = next;
}
- if (info->data != NULL)
- g_variant_unref (info->data);
- g_free (info);
+ ubus_message_info_free (info);
}
return FALSE;
}
-void
+static void
ubus_server_queue_message_pump (UBusServer *server)
{
+ UBusServerPrivate *priv;
+
g_return_if_fail (UBUS_IS_SERVER (server));
- UBusServerPrivate *priv = server->priv;
+ priv = server->priv;
if (priv->message_pump_queued)
return;
@@ -283,34 +304,41 @@ ubus_server_queue_message_pump (UBusServer *server)
}
void
-ubus_server_send_message (UBusServer *server, const gchar *message,
- GVariant *data)
+ubus_server_send_message (UBusServer *server,
+ const gchar *message,
+ GVariant *data)
{
+ UBusServerPrivate *priv;
+ UBusMessageInfo *message_info;
+
g_return_if_fail (UBUS_IS_SERVER (server));
- g_return_if_fail (message != NULL);
- UBusServerPrivate *priv = server->priv;
+ g_return_if_fail (message != NULL);
- UBusMessageInfo *message_info = ubus_message_info_new (message, data);
- g_queue_push_head (priv->message_queue, message_info);
+ priv = server->priv;
+ message_info = ubus_message_info_new (data);
+ message_info->message = g_string_chunk_insert_const (priv->message_names,
+ message);
+ g_queue_push_head (priv->message_queue, message_info);
ubus_server_queue_message_pump (server);
}
void
-ubus_server_unregister_interest (UBusServer* server, gulong handle)
+ubus_server_unregister_interest (UBusServer* server, guint handle)
{
+ UBusServerPrivate *priv;
+ GSequence *dispatch_list;
+ UBusDispatchInfo *info;
+
g_return_if_fail (UBUS_IS_SERVER (server));
g_return_if_fail (handle > 0);
- UBusServerPrivate *priv = server->priv;
- UBusDispatchInfo *info;
- GSequence *dispatch_list;
- // get our info
- info = g_hash_table_lookup (priv->dispatch_table, &handle);
+ priv = server->priv;
+ info = g_hash_table_lookup (priv->dispatch_table, GUINT_TO_POINTER (handle));
if (info == NULL)
{
- g_warning (G_STRLOC ": Handle %lu does not exist", handle);
+ g_warning (G_STRLOC ": Handle %u does not exist", handle);
return;
}
diff --git a/libunity/ubus-server.h b/libunity/ubus-server.h
index 5aee95a92..b6d4bbef8 100644
--- a/libunity/ubus-server.h
+++ b/libunity/ubus-server.h
@@ -57,17 +57,23 @@ struct _UBusServer
UBusServerPrivate *priv;
};
-typedef void (*UBusCallback) (GVariant *data, gpointer *user_data);
+typedef void (*UBusCallback) (GVariant *data,
+ gpointer user_data);
-GType ubus_server_get_type (void) G_GNUC_CONST;
-UBusServer *ubus_server_get_default ();
-void ubus_server_prime_context (UBusServer* server, GMainContext *context);
-gulong ubus_server_register_interest (UBusServer* server, const gchar *message,
- UBusCallback callback, gpointer user_data);
-void ubus_server_send_message (UBusServer* server, const gchar *message,
- GVariant *data);
-void ubus_server_unregister_interest (UBusServer* server, gulong handle);
-void ubus_server_force_message_pump (UBusServer* server);
+GType ubus_server_get_type (void) G_GNUC_CONST;
+UBusServer* ubus_server_get_default ();
+void ubus_server_prime_context (UBusServer *server,
+ GMainContext *context);
+guint ubus_server_register_interest (UBusServer *server,
+ const gchar *message,
+ UBusCallback callback,
+ gpointer user_data);
+void ubus_server_send_message (UBusServer *server,
+ const gchar *message,
+ GVariant *data);
+void ubus_server_unregister_interest (UBusServer *server,
+ guint handle);
+void ubus_server_force_message_pump (UBusServer *server);
G_END_DECLS
diff --git a/po/unity.pot b/po/unity.pot
index 4181f41c8..1bf78a1c5 100644
--- a/po/unity.pot
+++ b/po/unity.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: ayatana-dev@lists.launchpad.net\n"
-"POT-Creation-Date: 2010-11-24 13:32-0500\n"
+"POT-Creation-Date: 2010-11-28 20:25-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
diff --git a/services/CMakeLists.txt b/services/CMakeLists.txt
index 66309cc4f..744a131d6 100644
--- a/services/CMakeLists.txt
+++ b/services/CMakeLists.txt
@@ -13,6 +13,7 @@ set(CFLAGS
"-DGETTEXT_PACKAGE=\"unity\""
"-DINDICATORDIR=\"${_indicatordir}\""
"-DINDICATORICONDIR=\"${_iconsdir}\""
+ "-Werror -Wall"
)
add_definitions(${CFLAGS})
diff --git a/services/panel-service.c b/services/panel-service.c
index bff42ecb1..060aaf06f 100644
--- a/services/panel-service.c
+++ b/services/panel-service.c
@@ -33,6 +33,9 @@ G_DEFINE_TYPE (PanelService, panel_service, G_TYPE_OBJECT);
(G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_SERVICE, PanelServicePrivate))
#define NOTIFY_TIMEOUT 80
+#define N_TIMEOUT_SLOTS 50
+
+static PanelService *static_service = NULL;
struct _PanelServicePrivate
{
@@ -40,7 +43,8 @@ struct _PanelServicePrivate
GHashTable *id2entry_hash;
GHashTable *entry2indicator_hash;
- gint32 timeouts[100];
+ guint initial_sync_id;
+ gint32 timeouts[N_TIMEOUT_SLOTS];
GtkMenu *last_menu;
guint32 last_menu_id;
@@ -98,16 +102,33 @@ static GdkFilterReturn event_filter (GdkXEvent *ev,
/*
* GObject stuff
*/
+
static void
panel_service_class_dispose (GObject *object)
{
PanelServicePrivate *priv = PANEL_SERVICE (object)->priv;
+ gint i;
g_hash_table_destroy (priv->id2entry_hash);
g_hash_table_destroy (priv->entry2indicator_hash);
gdk_window_remove_filter (NULL, (GdkFilterFunc)event_filter, object);
+ if (priv->initial_sync_id)
+ {
+ g_source_remove (priv->initial_sync_id);
+ priv->initial_sync_id = 0;
+ }
+
+ for (i = 0; i < N_TIMEOUT_SLOTS; i++)
+ {
+ if (priv->timeouts[i] > 0)
+ {
+ g_source_remove (priv->timeouts[i]);
+ priv->timeouts[i] = 0;
+ }
+ }
+
G_OBJECT_CLASS (panel_service_parent_class)->dispose (object);
}
@@ -246,9 +267,10 @@ static gboolean
initial_resync (PanelService *self)
{
if (PANEL_IS_SERVICE (self))
- g_signal_emit (self, _service_signals[RE_SYNC], 0, "");
-
-
+ {
+ g_signal_emit (self, _service_signals[RE_SYNC], 0, "");
+ self->priv->initial_sync_id = 0;
+ }
return FALSE;
}
@@ -269,18 +291,16 @@ panel_service_init (PanelService *self)
sort_indicators (self);
suppress_signals = FALSE;
- g_idle_add ((GSourceFunc)initial_resync, self);
+ priv->initial_sync_id = g_idle_add ((GSourceFunc)initial_resync, self);
}
PanelService *
panel_service_get_default ()
{
- static PanelService *service = NULL;
+ if (static_service == NULL || !PANEL_IS_SERVICE (static_service))
+ static_service = g_object_new (PANEL_TYPE_SERVICE, NULL);
- if (service == NULL || !PANEL_IS_SERVICE (service))
- service = g_object_new (PANEL_TYPE_SERVICE, NULL);
-
- return service;
+ return static_service;
}
PanelService *
@@ -316,6 +336,9 @@ actually_notify_object (IndicatorObject *object)
PanelServicePrivate *priv;
gint position;
+ if (!PANEL_IS_SERVICE (static_service))
+ return FALSE;
+
if (!INDICATOR_IS_OBJECT (object))
return FALSE;
diff --git a/src/BamfLauncherIcon.cpp b/src/BamfLauncherIcon.cpp
index 90d70256b..d64a8aac4 100644
--- a/src/BamfLauncherIcon.cpp
+++ b/src/BamfLauncherIcon.cpp
@@ -22,6 +22,7 @@
#include "BamfLauncherIcon.h"
#include "Launcher.h"
#include "PluginAdapter.h"
+#include "FavoriteStore.h"
#include <gio/gdesktopappinfo.h>
@@ -31,40 +32,49 @@
BamfLauncherIcon::BamfLauncherIcon (Launcher* IconManager, BamfApplication *app, CompScreen *screen)
: SimpleLauncherIcon(IconManager)
{
- m_App = app;
- m_Screen = screen;
- char *icon_name = bamf_view_get_icon (BAMF_VIEW (m_App));
+ m_App = app;
+ m_Screen = screen;
+ 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);
- g_signal_connect (app, "running-changed", (GCallback) &BamfLauncherIcon::OnRunningChanged, this);
- 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 ();
+ 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);
+ g_signal_connect (app, "running-changed", (GCallback) &BamfLauncherIcon::OnRunningChanged, this);
+ 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 ();
}
BamfLauncherIcon::~BamfLauncherIcon()
{
- g_object_unref (m_App);
+ g_signal_handlers_disconnect_by_func (m_App, (void *) &BamfLauncherIcon::OnChildRemoved, this);
+ g_signal_handlers_disconnect_by_func (m_App, (void *) &BamfLauncherIcon::OnChildAdded, this);
+ g_signal_handlers_disconnect_by_func (m_App, (void *) &BamfLauncherIcon::OnUrgentChanged, this);
+ g_signal_handlers_disconnect_by_func (m_App, (void *) &BamfLauncherIcon::OnRunningChanged, this);
+ g_signal_handlers_disconnect_by_func (m_App, (void *) &BamfLauncherIcon::OnActiveChanged, this);
+ g_signal_handlers_disconnect_by_func (m_App, (void *) &BamfLauncherIcon::OnUserVisibleChanged, this);
+ g_signal_handlers_disconnect_by_func (m_App, (void *) &BamfLauncherIcon::OnClosed, this);
+
+ g_object_unref (m_App);
}
bool
@@ -94,195 +104,309 @@ BamfLauncherIcon::IconOwnsWindow (Window w)
void
BamfLauncherIcon::OnMouseClick (int button)
{
- if (button != 1)
- return;
-
- BamfView *view;
- GList *children, *l;
- bool active, running;
- GDesktopAppInfo *appInfo;
+ if (button != 1)
+ return;
+
+ BamfView *view;
+ GList *children, *l;
+ bool active, running;
+ GDesktopAppInfo *appInfo;
+
+ children = bamf_view_get_children (BAMF_VIEW (m_App));
+ active = bamf_view_is_active (BAMF_VIEW (m_App));
+ running = bamf_view_is_running (BAMF_VIEW (m_App));
+
+ if (!running)
+ {
+ 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, NULL);
+ g_object_unref (appInfo);
- children = bamf_view_get_children (BAMF_VIEW (m_App));
- active = bamf_view_is_active (BAMF_VIEW (m_App));
- running = bamf_view_is_running (BAMF_VIEW (m_App));
+ UpdateQuirkTime (LAUNCHER_ICON_QUIRK_STARTING);
- if (!running)
+ return;
+ }
+
+ if (active)
+ {
+ std::list<Window> windowList;
+ for (l = children; l; l = l->next)
{
- 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, NULL);
- g_object_unref (appInfo);
-
- UpdateQuirkTime (LAUNCHER_ICON_QUIRK_STARTING);
-
- return;
+ view = (BamfView *) l->data;
+
+ if (BAMF_IS_WINDOW (view))
+ {
+ guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view));
+
+ windowList.push_back ((Window) xid);
+ }
}
- if (active)
+ if (windowList.size () > 1)
{
- std::list<Window> windowList;
- for (l = children; l; l = l->next)
- {
- view = (BamfView *) l->data;
-
- 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;
- }
+ std::string *match = PluginAdapter::Default ()->MatchStringForXids (&windowList);
+ PluginAdapter::Default ()->InitiateScale (match);
+ delete match;
}
- else
+ }
+ else
+ {
+ for (l = children; l; l = l->next)
{
- for (l = children; l; l = l->next)
- {
- view = (BamfView *) l->data;
-
- if (BAMF_IS_WINDOW (view))
- {
- guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view));
-
- CompWindow *window = m_Screen->findWindow ((Window) xid);
-
- if (window)
- window->activate ();
- }
- }
+ view = (BamfView *) l->data;
+
+ if (BAMF_IS_WINDOW (view))
+ {
+ guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view));
+
+ CompWindow *window = m_Screen->findWindow ((Window) xid);
+
+ if (window)
+ window->activate ();
+ }
}
+ }
}
void
BamfLauncherIcon::OnClosed (BamfView *view, gpointer data)
{
- BamfLauncherIcon *self = (BamfLauncherIcon *) data;
-
- if (!bamf_view_is_sticky (BAMF_VIEW (self->m_App)))
- self->Remove ();
+ BamfLauncherIcon *self = (BamfLauncherIcon *) data;
+
+ if (!bamf_view_is_sticky (BAMF_VIEW (self->m_App)))
+ self->Remove ();
}
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);
+ BamfLauncherIcon *self = (BamfLauncherIcon *) data;
+
+ if (!bamf_view_is_sticky (BAMF_VIEW (self->m_App)))
+ self->SetQuirk (LAUNCHER_ICON_QUIRK_VISIBLE, visible);
}
void
BamfLauncherIcon::OnRunningChanged (BamfView *view, gboolean running, gpointer data)
{
- BamfLauncherIcon *self = (BamfLauncherIcon *) data;
- self->SetQuirk (LAUNCHER_ICON_QUIRK_RUNNING, running);
-
- if (running)
- {
- self->EnsureWindowState ();
- self->UpdateIconGeometries (self->GetCenter ());
- }
+ BamfLauncherIcon *self = (BamfLauncherIcon *) data;
+ self->SetQuirk (LAUNCHER_ICON_QUIRK_RUNNING, running);
+
+ if (running)
+ {
+ self->EnsureWindowState ();
+ self->UpdateIconGeometries (self->GetCenter ());
+ }
}
void
BamfLauncherIcon::OnActiveChanged (BamfView *view, gboolean active, gpointer data)
{
- BamfLauncherIcon *self = (BamfLauncherIcon *) data;
- self->SetQuirk (LAUNCHER_ICON_QUIRK_ACTIVE, active);
+ BamfLauncherIcon *self = (BamfLauncherIcon *) data;
+ self->SetQuirk (LAUNCHER_ICON_QUIRK_ACTIVE, active);
}
void
BamfLauncherIcon::OnUrgentChanged (BamfView *view, gboolean urgent, gpointer data)
{
- BamfLauncherIcon *self = (BamfLauncherIcon *) data;
- self->SetQuirk (LAUNCHER_ICON_QUIRK_URGENT, urgent);
+ BamfLauncherIcon *self = (BamfLauncherIcon *) data;
+ self->SetQuirk (LAUNCHER_ICON_QUIRK_URGENT, urgent);
}
void
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);
+ 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);
}
void
BamfLauncherIcon::OnChildAdded (BamfView *view, BamfView *child, gpointer data)
{
- BamfLauncherIcon *self = (BamfLauncherIcon*) data;
- self->EnsureWindowState ();
- self->UpdateIconGeometries (self->GetCenter ());
+ BamfLauncherIcon *self = (BamfLauncherIcon*) data;
+ self->EnsureWindowState ();
+ self->UpdateMenus ();
+ self->UpdateIconGeometries (self->GetCenter ());
}
void
BamfLauncherIcon::OnChildRemoved (BamfView *view, BamfView *child, gpointer data)
{
- BamfLauncherIcon *self = (BamfLauncherIcon*) data;
- self->EnsureWindowState ();
+ BamfLauncherIcon *self = (BamfLauncherIcon*) data;
+ self->EnsureWindowState ();
}
-std::list<DbusmenuClient *>
+void
+BamfLauncherIcon::UpdateMenus ()
+{
+ GList *children, *l;
+
+ children = bamf_view_get_children (BAMF_VIEW (m_App));
+ for (l = children; l; l = l->next)
+ {
+ if (!BAMF_IS_INDICATOR (l->data))
+ continue;
+
+ 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;
+ }
+}
+
+void
+BamfLauncherIcon::OnQuit (DbusmenuMenuitem *item, int time, BamfLauncherIcon *self)
+{
+ GList *children, *l;
+ BamfView *view;
+
+ children = bamf_view_get_children (BAMF_VIEW (self->m_App));
+
+ for (l = children; l; l = l->next)
+ {
+ view = (BamfView *) l->data;
+
+ if (BAMF_IS_WINDOW (view))
+ {
+ guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view));
+ CompWindow *window = self->m_Screen->findWindow ((Window) xid);
+
+ window->close (self->m_Screen->getCurrentTime ());
+ }
+ }
+}
+
+void
+BamfLauncherIcon::OnTogglePin (DbusmenuMenuitem *item, int time, BamfLauncherIcon *self)
+{
+ 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 ());
+ }
+}
+
+std::list<DbusmenuMenuitem *>
BamfLauncherIcon::GetMenus ()
{
- GList *children, *l;
- std::list<DbusmenuClient *> result;
+ std::map<std::string, DbusmenuClient *>::iterator it;
+ std::list<DbusmenuMenuitem *> result;
+ DbusmenuMenuitem *menu_item;
+
+ for (it = _menu_clients.begin (); it != _menu_clients.end (); it++)
+ {
+ GList * child = NULL;
+ DbusmenuClient *client = (*it).second;
+ DbusmenuMenuitem *root = dbusmenu_client_get_root (client);
- children = bamf_view_get_children (BAMF_VIEW (m_App));
- for (l = children; l; l = l->next)
+ for (child = dbusmenu_menuitem_get_children(root); child != NULL; child = g_list_next(child))
{
- if (BAMF_IS_INDICATOR (l->data))
- {
- BamfIndicator *indicator = BAMF_INDICATOR (l->data);
- DbusmenuClient *client = dbusmenu_client_new (bamf_indicator_get_remote_address (indicator), bamf_indicator_get_dbus_menu_path (indicator));
-
- result.push_back (client);
- }
+ DbusmenuMenuitem *item = (DbusmenuMenuitem *) child->data;
+
+ if (!item)
+ continue;
+
+ result.push_back (item);
}
+ }
+
+ if (_menu_items.find ("Pin") == _menu_items.end ())
+ {
+ 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, "Pin To 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)) ?
+ DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED : DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED;
+
+ dbusmenu_menuitem_property_set_int (_menu_items["Pin"],
+ DBUSMENU_MENUITEM_PROP_TOGGLE_STATE,
+ checked);
+ result.push_back (_menu_items["Pin"]);
+
+ 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);
- return result;
+ g_signal_connect (menu_item, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, (GCallback) &BamfLauncherIcon::OnQuit, this);
+
+ _menu_items["Quit"] = menu_item;
+ }
+
+ result.push_back (_menu_items["Quit"]);
+
+ return result;
}
void
BamfLauncherIcon::UpdateIconGeometries (nux::Point3 center)
{
- GList *children, *l;
- BamfView *view;
- long data[4];
+ GList *children, *l;
+ BamfView *view;
+ long data[4];
- data[0] = center.x - 24;
- data[1] = center.y - 24;
- data[2] = 48;
- data[3] = 48;
+ data[0] = center.x - 24;
+ data[1] = center.y - 24;
+ data[2] = 48;
+ data[3] = 48;
- children = bamf_view_get_children (BAMF_VIEW (m_App));
+ children = bamf_view_get_children (BAMF_VIEW (m_App));
- for (l = children; l; l = l->next)
+ for (l = children; l; l = l->next)
+ {
+ view = (BamfView *) l->data;
+
+ if (BAMF_IS_WINDOW (view))
{
- view = (BamfView *) l->data;
-
- 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);
- }
+ guint32 xid = bamf_window_get_xid (BAMF_WINDOW (view));
+
+ XChangeProperty (m_Screen->dpy (), xid, Atoms::wmIconGeometry,
+ XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *) data, 4);
}
+ }
}
void
diff --git a/src/BamfLauncherIcon.h b/src/BamfLauncherIcon.h
index 8150cbfea..22ea7c656 100644
--- a/src/BamfLauncherIcon.h
+++ b/src/BamfLauncherIcon.h
@@ -41,7 +41,7 @@ public:
protected:
void OnMouseClick (int button);
- std::list<DbusmenuClient *> GetMenus ();
+ std::list<DbusmenuMenuitem *> GetMenus ();
void UpdateIconGeometries (nux::Point3 center);
void OnCenterStabilized (nux::Point3 center);
@@ -51,8 +51,11 @@ protected:
private:
BamfApplication *m_App;
CompScreen *m_Screen;
+ std::map<std::string, DbusmenuClient *> _menu_clients;
+ std::map<std::string, DbusmenuMenuitem *> _menu_items;
void EnsureWindowState ();
+ void UpdateMenus ();
static void OnClosed (BamfView *view, gpointer data);
static void OnUserVisibleChanged (BamfView *view, gboolean visible, gpointer data);
@@ -61,6 +64,9 @@ 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 OnQuit (DbusmenuMenuitem *item, int time, BamfLauncherIcon *self);
+ static void OnTogglePin (DbusmenuMenuitem *item, int time, BamfLauncherIcon *self);
};
#endif // BAMFLAUNCHERICON_H
diff --git a/src/FavoriteStoreGSettings.cpp b/src/FavoriteStoreGSettings.cpp
index 3519d7370..9c09cb3a8 100644
--- a/src/FavoriteStoreGSettings.cpp
+++ b/src/FavoriteStoreGSettings.cpp
@@ -173,7 +173,7 @@ FavoriteStoreGSettings::AddFavorite (const char *desktop_path,
int n_total_favs;
GSList *f;
gint i = 0;
-
+
g_return_if_fail (desktop_path);
g_return_if_fail (position < (gint)g_slist_length (m_favorites));
diff --git a/src/Launcher.cpp b/src/Launcher.cpp
index ca4f56f1a..9067b5fa6 100644
--- a/src/Launcher.cpp
+++ b/src/Launcher.cpp
@@ -331,24 +331,28 @@ void Launcher::EnsureAnimation ()
bool Launcher::IconNeedsAnimation (LauncherIcon *icon, struct timespec current)
{
- struct timespec visible_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_VISIBLE);
- if (TimeDelta (&current, &visible_time) < ANIM_DURATION_SHORT)
+ struct timespec time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_VISIBLE);
+ if (TimeDelta (&current, &time) < ANIM_DURATION_SHORT)
return true;
- struct timespec running_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_RUNNING);
- if (TimeDelta (&current, &running_time) < ANIM_DURATION_SHORT)
+ time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_RUNNING);
+ if (TimeDelta (&current, &time) < ANIM_DURATION_SHORT)
return true;
- struct timespec starting_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_STARTING);
- if (TimeDelta (&current, &starting_time) < (ANIM_DURATION_LONG * MAX_STARTING_BLINKS * STARTING_BLINK_LAMBDA * 2))
+ time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_STARTING);
+ if (TimeDelta (&current, &time) < (ANIM_DURATION_LONG * MAX_STARTING_BLINKS * STARTING_BLINK_LAMBDA * 2))
return true;
- struct timespec urgent_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_URGENT);
- if (TimeDelta (&current, &urgent_time) < (ANIM_DURATION_LONG * URGENT_BLINKS * 2))
+ 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;
- struct timespec present_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_PRESENTED);
- if (TimeDelta (&current, &present_time) < ANIM_DURATION)
+ time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_SHIMMER);
+ if (TimeDelta (&current, &time) < ANIM_DURATION_LONG)
return true;
return false;
@@ -481,6 +485,13 @@ float Launcher::IconUrgentProgress (LauncherIcon *icon, struct timespec current)
return 1.0f - result;
}
+float Launcher::IconShimmerProgress (LauncherIcon *icon, struct timespec current)
+{
+ struct timespec shimmer_time = icon->GetQuirkTime (LAUNCHER_ICON_QUIRK_SHIMMER);
+ int shimmer_ms = TimeDelta (&current, &shimmer_time);
+ return CLAMP ((float) shimmer_ms / (float) ANIM_DURATION_LONG, 0.0f, 1.0f);
+}
+
float Launcher::IconUrgentPulseValue (LauncherIcon *icon, struct timespec current)
{
if (!icon->GetQuirk (LAUNCHER_ICON_QUIRK_URGENT))
@@ -530,6 +541,29 @@ float Launcher::IconBackgroundIntensity (LauncherIcon *icon, struct timespec cur
return result;
}
+void Launcher::SetupRenderArg (LauncherIcon *icon, struct timespec current, RenderArg &arg)
+{
+ arg.icon = icon;
+ arg.alpha = 1.0f;
+ arg.running_arrow = false;
+ arg.active_arrow = icon->GetQuirk (LAUNCHER_ICON_QUIRK_ACTIVE);
+ arg.folding_rads = 0.0f;
+ arg.skip = false;
+
+ arg.window_indicators = MIN (4, icon->RelatedWindows ());
+
+ // we dont need to show strays
+ if (arg.window_indicators == 1 || !icon->GetQuirk (LAUNCHER_ICON_QUIRK_RUNNING))
+ arg.window_indicators = 0;
+
+ 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
+ arg.glow_intensity = urgent_progress;
+}
+
void Launcher::RenderArgs (std::list<Launcher::RenderArg> &launcher_args,
std::list<Launcher::RenderArg> &shelf_args,
nux::Geometry &box_geo, nux::Geometry &shelf_geo)
@@ -648,24 +682,7 @@ void Launcher::RenderArgs (std::list<Launcher::RenderArg> &launcher_args,
RenderArg arg;
LauncherIcon *icon = *it;
- arg.icon = icon;
- arg.alpha = 1.0f;
- arg.running_arrow = false;
- arg.active_arrow = icon->GetQuirk (LAUNCHER_ICON_QUIRK_ACTIVE);
- arg.folding_rads = 0.0f;
- arg.skip = false;
-
- arg.window_indicators = MIN (4, icon->RelatedWindows ());
-
- // we dont need to show strays
- if (arg.window_indicators == 1 || !icon->GetQuirk (LAUNCHER_ICON_QUIRK_RUNNING))
- arg.window_indicators = 0;
-
- arg.backlight_intensity = IconBackgroundIntensity (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
- arg.glow_intensity = urgent_progress;
+ SetupRenderArg (icon, current, arg);
// reset z
center.z = 0;
@@ -721,22 +738,8 @@ void Launcher::RenderArgs (std::list<Launcher::RenderArg> &launcher_args,
{
RenderArg arg;
LauncherIcon *icon = *it;
-
- arg.icon = icon;
- arg.alpha = 1.0f;
- arg.glow_intensity = 0.0f;
- arg.running_arrow = false;
- arg.active_arrow = icon->GetQuirk (LAUNCHER_ICON_QUIRK_ACTIVE);
- arg.folding_rads = 0.0f;
- arg.skip = false;
-
- arg.window_indicators = MIN (4, icon->RelatedWindows ());
-
- // we dont need to show strays
- if (arg.window_indicators == 1 || !icon->GetQuirk (LAUNCHER_ICON_QUIRK_RUNNING))
- arg.window_indicators = 0;
-
- arg.backlight_intensity = IconBackgroundIntensity (icon, current);
+
+ SetupRenderArg (icon, current, arg);
// reset z
center.z = 0;
@@ -1241,6 +1244,30 @@ void Launcher::DrawRenderArg (nux::GraphicsEngine& GfxContext, RenderArg arg, nu
geo,
false);
}
+
+ 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,
+ _icon_glow_texture,
+ arg.icon->GlowColor (),
+ fade_out,
+ arg.icon->_xform_coords["Glow"],
+ geo,
+ false);
+
+ GfxContext.PopClippingRectangle();
+ }
}
void Launcher::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw)
diff --git a/src/Launcher.h b/src/Launcher.h
index 2c701d35d..2fd3345ef 100644
--- a/src/Launcher.h
+++ b/src/Launcher.h
@@ -23,7 +23,7 @@
#include <sys/time.h>
#include <Nux/View.h>
-#include <Nux/BaseWindow.h>
+#include <Nux/BaseWindow.h>
#include "Introspectable.h"
#include "LauncherIcon.h"
#include "NuxGraphics/IOpenGLAsmShader.h"
@@ -65,20 +65,20 @@ public:
virtual void RecvMouseEnter(int x, int y, unsigned long button_flags, unsigned long key_flags);
virtual void RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned long key_flags);
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);
-
+ 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);
-
-protected:
- // Introspectable methods
- const gchar* GetName ();
+
+protected:
+ // Introspectable methods
+ const gchar* GetName ();
void AddProperties (GVariantBuilder *builder);
-
+
private:
typedef enum
{
@@ -101,6 +101,7 @@ private:
float alpha;
float backlight_intensity;
float glow_intensity;
+ float shimmer_progress;
bool running_arrow;
bool active_arrow;
bool skip;
@@ -126,6 +127,7 @@ private:
float AutohideProgress ();
float IconPresentProgress (LauncherIcon *icon, struct timespec current);
float IconUrgentProgress (LauncherIcon *icon, struct timespec current);
+ float IconShimmerProgress (LauncherIcon *icon, struct timespec current);
float IconUrgentPulseValue (LauncherIcon *icon, struct timespec current);
float IconStartingPulseValue (LauncherIcon *icon, struct timespec current);
float IconBackgroundIntensity (LauncherIcon *icon, struct timespec current);
@@ -135,6 +137,8 @@ private:
void SetHidden (bool hidden);
void SetDndDelta (float x, float y, nux::Geometry geo, struct timespec current);
+
+ void SetupRenderArg (LauncherIcon *icon, struct timespec current, RenderArg &arg);
void RenderArgs (std::list<Launcher::RenderArg> &launcher_args,
std::list<Launcher::RenderArg> &shelf_args,
nux::Geometry &box_geo, nux::Geometry &shelf_geo);
diff --git a/src/LauncherController.cpp b/src/LauncherController.cpp
index cd760536a..5d5996661 100644
--- a/src/LauncherController.cpp
+++ b/src/LauncherController.cpp
@@ -52,24 +52,28 @@ void
LauncherController::PresentIconOwningWindow (Window window)
{
LauncherModel::iterator it;
+ LauncherIcon *owner = 0;
for (it = _model->begin (); it != _model->end (); it++)
{
if ((*it)->IconOwnsWindow (window))
{
- (*it)->Present (2, 600);
- return;
+ owner = *it;
+ break;
}
}
- for (it = _model->shelf_begin (); it != _model->shelf_end (); it++)
+ for (it = _model->shelf_begin (); !owner && it != _model->shelf_end (); it++)
{
if ((*it)->IconOwnsWindow (window))
{
- (*it)->Present (2, 600);
- return;
+ owner = *it;
+ break;
}
}
+
+ owner->Present (2, 600);
+ owner->UpdateQuirkTimeDelayed (300, LAUNCHER_ICON_QUIRK_SHIMMER);
}
void
@@ -119,6 +123,21 @@ LauncherController::RegisterIcon (LauncherIcon *icon)
{
_model->AddIcon (icon);
_model->Sort (&LauncherController::CompareIcons);
+
+ LauncherModel::iterator it;
+
+ int i = 0;
+ for (it = _model->begin (); it != _model->end (); it++)
+ {
+ (*it)->SetSortPriority (i);
+ i++;
+ }
+
+ for (it = _model->shelf_begin (); it != _model->shelf_end (); it++)
+ {
+ (*it)->SetSortPriority (i);
+ i++;
+ }
}
/* static private */
diff --git a/src/LauncherIcon.cpp b/src/LauncherIcon.cpp
index 921d3408e..0cbe5f36a 100755
--- a/src/LauncherIcon.cpp
+++ b/src/LauncherIcon.cpp
@@ -227,18 +227,6 @@ nux::NString LauncherIcon::GetTooltipText()
void
LauncherIcon::RecvMouseEnter ()
{
- if (_quicklist_is_initialized == false)
- {
- std::list<DbusmenuClient *> menus_list = Menus ();
- std::list<DbusmenuClient *>::iterator it;
- for (it = menus_list.begin (); it != menus_list.end (); it++)
- {
- g_signal_connect(G_OBJECT(*it), DBUSMENU_CLIENT_SIGNAL_ROOT_CHANGED, G_CALLBACK(&LauncherIcon::RootChanged), _quicklist);
- }
-
- _quicklist_is_initialized = true;
- }
-
if (_launcher->GetActiveQuicklist ())
{
// A quicklist is active
@@ -261,48 +249,6 @@ void LauncherIcon::RecvMouseLeave ()
_tooltip->ShowWindow (false);
}
-void LauncherIcon::ChildRealized (DbusmenuMenuitem *newitem, QuicklistView *quicklist)
-{
- g_return_if_fail (newitem);
-
- const gchar* type = dbusmenu_menuitem_property_get (newitem, DBUSMENU_MENUITEM_PROP_TYPE);
- const gchar* toggle_type = dbusmenu_menuitem_property_get (newitem, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE);
-
- if (g_strcmp0 (type, DBUSMENU_CLIENT_TYPES_SEPARATOR) == 0)
- {
- QuicklistMenuItemSeparator* item = new QuicklistMenuItemSeparator (newitem, NUX_TRACKER_LOCATION);
- quicklist->AddMenuItem (item);
- }
- else if (g_strcmp0 (toggle_type, DBUSMENU_MENUITEM_TOGGLE_CHECK) == 0)
- {
- QuicklistMenuItemCheckmark* item = new QuicklistMenuItemCheckmark (newitem, NUX_TRACKER_LOCATION);
- quicklist->AddMenuItem (item);
- }
- else if (g_strcmp0 (toggle_type, DBUSMENU_MENUITEM_TOGGLE_RADIO) == 0)
- {
- QuicklistMenuItemRadio* item = new QuicklistMenuItemRadio (newitem, NUX_TRACKER_LOCATION);
- quicklist->AddMenuItem (item);
- }
- else //(g_strcmp0 (type, DBUSMENU_MENUITEM_PROP_LABEL) == 0)
- {
- QuicklistMenuItemLabel* item = new QuicklistMenuItemLabel (newitem, NUX_TRACKER_LOCATION);
- quicklist->AddMenuItem (item);
- }
-// else
-// {
-// g_warning ("Unknown menu item type in file %s at line %s", G_STRFUNC, G_STRLOC);
-// }
-}
-
-void LauncherIcon::RootChanged (DbusmenuClient * client, DbusmenuMenuitem * newroot, QuicklistView *quicklist)
-{
- GList * child = NULL;
- for (child = dbusmenu_menuitem_get_children(newroot); child != NULL; child = g_list_next(child))
- {
- g_signal_connect(G_OBJECT(child->data), DBUSMENU_MENUITEM_SIGNAL_REALIZED, G_CALLBACK(ChildRealized), quicklist);
- }
-}
-
void LauncherIcon::RecvMouseDown (int button)
{
if (button == 3)
@@ -329,14 +275,51 @@ void LauncherIcon::RecvMouseDown (int button)
_tooltip->ShowWindow (false);
+ _quicklist->RemoveAllMenuItem ();
+
+ std::list<DbusmenuMenuitem *> menus = Menus ();
+ if (menus.empty ())
+ return;
+
+ std::list<DbusmenuMenuitem *>::iterator it;
+ for (it = menus.begin (); it != menus.end (); it++)
+ {
+ DbusmenuMenuitem *menu_item = *it;
+
+ const gchar* type = dbusmenu_menuitem_property_get (menu_item, DBUSMENU_MENUITEM_PROP_TYPE);
+ const gchar* toggle_type = dbusmenu_menuitem_property_get (menu_item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE);
+
+ if (g_strcmp0 (type, DBUSMENU_CLIENT_TYPES_SEPARATOR) == 0)
+ {
+ QuicklistMenuItemSeparator* item = new QuicklistMenuItemSeparator (menu_item, NUX_TRACKER_LOCATION);
+ _quicklist->AddMenuItem (item);
+ }
+ else if (g_strcmp0 (toggle_type, DBUSMENU_MENUITEM_TOGGLE_CHECK) == 0)
+ {
+ QuicklistMenuItemCheckmark* item = new QuicklistMenuItemCheckmark (menu_item, NUX_TRACKER_LOCATION);
+ _quicklist->AddMenuItem (item);
+ }
+ else if (g_strcmp0 (toggle_type, DBUSMENU_MENUITEM_TOGGLE_RADIO) == 0)
+ {
+ QuicklistMenuItemRadio* item = new QuicklistMenuItemRadio (menu_item, NUX_TRACKER_LOCATION);
+ _quicklist->AddMenuItem (item);
+ }
+ else //(g_strcmp0 (type, DBUSMENU_MENUITEM_PROP_LABEL) == 0)
+ {
+ QuicklistMenuItemLabel* item = new QuicklistMenuItemLabel (menu_item, NUX_TRACKER_LOCATION);
+ _quicklist->AddMenuItem (item);
+ }
+ }
int tip_x = _launcher->GetBaseWidth () + 1; //icon_x + icon_w;
int tip_y = _center.y;
-
_quicklist->ShowQuicklistWithTipAt (tip_x, tip_y);
- _quicklist->EnableInputWindow (true);
+
+ _quicklist->EnableInputWindow (true, 1);
_quicklist->GrabPointer ();
+
nux::GetWindowCompositor ().SetAlwaysOnFrontWindow (_quicklist);
+
_quicklist->NeedRedraw ();
}
}
@@ -512,6 +495,28 @@ LauncherIcon::SetQuirk (LauncherIconQuirk quirk, bool value)
Present (1, 1500);
}
+gboolean
+LauncherIcon::OnDelayedUpdateTimeout (gpointer data)
+{
+ DelayedUpdateArg *arg = (DelayedUpdateArg *) data;
+ LauncherIcon *self = arg->self;
+
+ clock_gettime (CLOCK_MONOTONIC, &(self->_quirk_times[arg->quirk]));
+ self->needs_redraw.emit (self);
+
+ return false;
+}
+
+void
+LauncherIcon::UpdateQuirkTimeDelayed (guint ms, LauncherIconQuirk quirk)
+{
+ DelayedUpdateArg *arg = new DelayedUpdateArg ();
+ arg->self = this;
+ arg->quirk = quirk;
+
+ g_timeout_add (ms, &LauncherIcon::OnDelayedUpdateTimeout, arg);
+}
+
void
LauncherIcon::UpdateQuirkTime (LauncherIconQuirk quirk)
{
@@ -538,14 +543,13 @@ LauncherIcon::RelatedWindows ()
return _related_windows;
}
-std::list<DbusmenuClient *> LauncherIcon::Menus ()
+std::list<DbusmenuMenuitem *> LauncherIcon::Menus ()
{
return GetMenus ();
}
-std::list<DbusmenuClient *> LauncherIcon::GetMenus ()
+std::list<DbusmenuMenuitem *> LauncherIcon::GetMenus ()
{
- std::list<DbusmenuClient *> result;
-
+ std::list<DbusmenuMenuitem *> result;
return result;
}
diff --git a/src/LauncherIcon.h b/src/LauncherIcon.h
index e3d87df88..2163f53bc 100644
--- a/src/LauncherIcon.h
+++ b/src/LauncherIcon.h
@@ -31,6 +31,7 @@
#include <gtk/gtk.h>
#include <libdbusmenu-glib/client.h>
+#include <libdbusmenu-glib/menuitem.h>
#include "Tooltip.h"
#include "QuicklistView.h"
@@ -58,6 +59,7 @@ typedef enum
LAUNCHER_ICON_QUIRK_URGENT,
LAUNCHER_ICON_QUIRK_PRESENTED,
LAUNCHER_ICON_QUIRK_STARTING,
+ LAUNCHER_ICON_QUIRK_SHIMMER,
LAUNCHER_ICON_QUIRK_LAST,
} LauncherIconQuirk;
@@ -100,7 +102,7 @@ public:
nux::BaseTexture * TextureForSize (int size);
- std::list<DbusmenuClient *> Menus ();
+ std::list<DbusmenuMenuitem *> Menus ();
sigc::signal<void, int> MouseDown;
@@ -116,6 +118,7 @@ public:
protected:
void SetQuirk (LauncherIconQuirk quirk, bool value);
+ void UpdateQuirkTimeDelayed (guint ms, LauncherIconQuirk quirk);
void UpdateQuirkTime (LauncherIconQuirk quirk);
void ResetQuirkTime (LauncherIconQuirk quirk);
@@ -129,7 +132,7 @@ protected:
void SetIconType (LauncherIconType type);
void SetSortPriority (int priority);
- virtual std::list<DbusmenuClient *> GetMenus ();
+ virtual std::list<DbusmenuMenuitem *> GetMenus ();
virtual nux::BaseTexture * GetTextureForSize (int size) = 0;
virtual void OnCenterStabilized (nux::Point3 center) {};
@@ -157,10 +160,17 @@ protected:
friend class LauncherController;
private:
+ typedef struct
+ {
+ LauncherIcon *self;
+ LauncherIconQuirk quirk;
+ } DelayedUpdateArg;
+
static void ChildRealized (DbusmenuMenuitem *newitem, QuicklistView *quicklist);
static void RootChanged (DbusmenuClient * client, DbusmenuMenuitem *newroot, QuicklistView *quicklist);
static gboolean OnPresentTimeout (gpointer data);
static gboolean OnCenterTimeout (gpointer data);
+ static gboolean OnDelayedUpdateTimeout (gpointer data);
void ColorForIcon (GdkPixbuf *pixbuf, nux::Color &background, nux::Color &glow);
diff --git a/src/PanelHomeButton.cpp b/src/PanelHomeButton.cpp
index ef0d5180a..9fe30194f 100644
--- a/src/PanelHomeButton.cpp
+++ b/src/PanelHomeButton.cpp
@@ -37,6 +37,9 @@ PanelHomeButton::PanelHomeButton ()
{
_pixbuf = gdk_pixbuf_new_from_file (PKGDATADIR"/bfb.png", NULL);
SetMinMaxSize (BUTTON_WIDTH, PANEL_HEIGHT);
+
+ OnMouseClick.connect (sigc::mem_fun (this, &PanelHomeButton::RecvMouseClick));
+
Refresh ();
}
@@ -103,3 +106,37 @@ PanelHomeButton::Refresh ()
NeedRedraw ();
}
+
+void
+PanelHomeButton::RecvMouseClick (int x,
+ int y,
+ unsigned long button_flags,
+ unsigned long key_flags)
+{
+#define APPS_URI "file:///usr/share/applications"
+
+ /* FIXME: This is just for Alpha 1, so we have some feedback on clicking the
+ * PanelHomeButton, and especially because we don't have any other way of
+ * launching non-launcher apps right now
+ */
+ if (nux::GetEventButton (button_flags) == 1)
+ {
+ GdkAppLaunchContext *context;
+ GError *error = NULL;
+
+ context = gdk_app_launch_context_new ();
+ gdk_app_launch_context_set_screen (context, gdk_screen_get_default ());
+ gdk_app_launch_context_set_timestamp (context, GDK_CURRENT_TIME);
+
+ if (!g_app_info_launch_default_for_uri (APPS_URI,
+ (GAppLaunchContext *)context,
+ &error))
+ {
+ g_warning ("Unable to launcher applications folder: %s",
+ error->message);
+ g_error_free (error);
+ }
+
+ g_object_unref (context);
+ }
+}
diff --git a/src/PanelHomeButton.h b/src/PanelHomeButton.h
index d96fb34b7..61138de0c 100644
--- a/src/PanelHomeButton.h
+++ b/src/PanelHomeButton.h
@@ -30,6 +30,8 @@ public:
PanelHomeButton ();
~PanelHomeButton ();
+ void RecvMouseClick (int x, int y, unsigned long button_flags, unsigned long key_flags);
+
private:
void Refresh ();
diff --git a/src/PanelIndicatorObjectEntryView.cpp b/src/PanelIndicatorObjectEntryView.cpp
index 7744bfdec..302cbd5ec 100644
--- a/src/PanelIndicatorObjectEntryView.cpp
+++ b/src/PanelIndicatorObjectEntryView.cpp
@@ -44,6 +44,7 @@ PanelIndicatorObjectEntryView::PanelIndicatorObjectEntryView (IndicatorObjectEnt
_util_cg (CAIRO_FORMAT_ARGB32, 1, 1)
{
_proxy->Updated.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::Refresh));
+
InputArea::OnMouseDown.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::OnMouseDown));
Refresh ();
diff --git a/src/QuicklistMenuItem.cpp b/src/QuicklistMenuItem.cpp
index 389d28434..cd0963339 100755..100644
--- a/src/QuicklistMenuItem.cpp
+++ b/src/QuicklistMenuItem.cpp
@@ -25,9 +25,6 @@
#include <X11/Xlib.h>
-#define ITEM_INDENT_ABS 20
-#define ITEM_CORNER_RADIUS_ABS 4
-
static void
OnPropertyChanged (gchar* property,
GValue* value,
@@ -198,7 +195,7 @@ QuicklistMenuItem::GetActive ()
if (_menuItem == 0)
return false;
return dbusmenu_menuitem_property_get_bool (_menuItem,
- DBUSMENU_MENUITEM_PROP_TOGGLE_STATE);
+ DBUSMENU_MENUITEM_PROP_TOGGLE_STATE) == DBUSMENU_MENUITEM_TOGGLE_STATE_CHECKED;
}
void QuicklistMenuItem::ItemActivated ()
@@ -237,6 +234,9 @@ void QuicklistMenuItem::GetTextExtents (const gchar* font,
if (!font)
return;
+ if (_text == NULL)
+ return;
+
surface = cairo_image_surface_create (CAIRO_FORMAT_A1, 1, 1);
cr = cairo_create (surface);
cairo_set_font_options (cr, gdk_screen_get_font_options (screen));
@@ -298,17 +298,16 @@ void QuicklistMenuItem::RecvMouseDown (int x, int y, unsigned long button_flags,
void QuicklistMenuItem::RecvMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags)
{
- sigMouseReleased.emit (this);
+ sigMouseReleased.emit (this, x, y);
}
void QuicklistMenuItem::RecvMouseClick (int x, int y, unsigned long button_flags, unsigned long key_flags)
{
if (!GetEnabled ())
{
- sigMouseClick.emit (this);
return;
}
- sigMouseClick.emit (this);
+ sigMouseClick.emit (this, x, y);
}
void QuicklistMenuItem::RecvMouseMove (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
@@ -318,7 +317,7 @@ void QuicklistMenuItem::RecvMouseMove (int x, int y, int dx, int dy, unsigned lo
void QuicklistMenuItem::RecvMouseDrag (int x, int y, int dx, int dy, unsigned long button_flags, unsigned long key_flags)
{
-
+ sigMouseDrag.emit (this, x, y);
}
void QuicklistMenuItem::RecvMouseEnter (int x, int y, unsigned long button_flags, unsigned long key_flags)
@@ -395,6 +394,9 @@ QuicklistMenuItem::DrawText (cairo_t* cr,
int height,
nux::Color color)
{
+ if (_text == NULL)
+ return;
+
int textWidth = 0;
int textHeight = 0;
PangoLayout* layout = NULL;
@@ -432,7 +434,9 @@ QuicklistMenuItem::DrawText (cairo_t* cr,
pango_layout_context_changed (layout);
- cairo_move_to (cr, ITEM_INDENT_ABS, (float) (height - textHeight) / 2.0f);
+ cairo_move_to (cr,
+ 2 * ITEM_MARGIN + ITEM_INDENT_ABS,
+ (float) (height - textHeight) / 2.0f);
pango_cairo_show_layout (cr, layout);
// clean up
diff --git a/src/QuicklistMenuItem.h b/src/QuicklistMenuItem.h
index 71e43bb31..d07b3a61c 100755
--- a/src/QuicklistMenuItem.h
+++ b/src/QuicklistMenuItem.h
@@ -30,6 +30,10 @@
#include <pango/pango.h>
#include <pango/pangocairo.h>
+#define ITEM_INDENT_ABS 16
+#define ITEM_CORNER_RADIUS_ABS 3
+#define ITEM_MARGIN 4
+
typedef enum
{
MENUITEM_TYPE_UNKNOWN = 0,
@@ -109,8 +113,9 @@ class QuicklistMenuItem : public nux::View
sigc::signal<void, QuicklistMenuItem*> sigMouseEnter;
sigc::signal<void, QuicklistMenuItem*> sigMouseLeave;
- sigc::signal<void, QuicklistMenuItem*> sigMouseReleased;
- sigc::signal<void, QuicklistMenuItem*> sigMouseClick;
+ sigc::signal<void, QuicklistMenuItem*, int, int> sigMouseReleased;
+ sigc::signal<void, QuicklistMenuItem*, int, int> sigMouseClick;
+ sigc::signal<void, QuicklistMenuItem*, int, int> sigMouseDrag;
DbusmenuMenuitem* _menuItem;
QuicklistMenuItemType _item_type;
diff --git a/src/QuicklistMenuItemCheckmark.cpp b/src/QuicklistMenuItemCheckmark.cpp
index 166d13c0a..eaa645c58 100755
--- a/src/QuicklistMenuItemCheckmark.cpp
+++ b/src/QuicklistMenuItemCheckmark.cpp
@@ -23,9 +23,6 @@
#include "Nux/Nux.h"
#include "QuicklistMenuItemCheckmark.h"
-#define ITEM_INDENT_ABS 20
-#define ITEM_CORNER_RADIUS_ABS 4
-
static double
_align (double val)
{
@@ -68,7 +65,8 @@ QuicklistMenuItemCheckmark::Initialize (DbusmenuMenuitem* item)
int textWidth = 1;
int textHeight = 1;
GetTextExtents (textWidth, textHeight);
- SetMinimumSize (textWidth + ITEM_INDENT_ABS, textHeight);
+ SetMinimumSize (textWidth + ITEM_INDENT_ABS + 3 * ITEM_MARGIN,
+ textHeight + 2 * ITEM_MARGIN);
}
QuicklistMenuItemCheckmark::~QuicklistMenuItemCheckmark ()
@@ -142,6 +140,10 @@ QuicklistMenuItemCheckmark::Draw (nux::GraphicsEngine& gfxContext,
{
nux::IntrusiveSP<nux::IOpenGLBaseTexture> texture;
+ // Check if the texture have been computed. If they haven't, exit the function.
+ if (!_normalTexture[0])
+ return;
+
nux::Geometry base = GetGeometry ();
gfxContext.PushClippingRectangle (base);
@@ -253,8 +255,8 @@ QuicklistMenuItemCheckmark::UpdateTexture ()
cairo_save (cr);
cairo_translate (cr,
- _align ((ITEM_INDENT_ABS - 16.0f) / 2.0f),
- _align (((double) height - 16.0f)/ 2.0f));
+ _align ((ITEM_INDENT_ABS - 16.0f + ITEM_MARGIN) / 2.0f),
+ _align (((double) height - 16.0f) / 2.0f));
cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f);
@@ -313,7 +315,7 @@ QuicklistMenuItemCheckmark::UpdateTexture ()
_prelightTexture[0] = nux::GetThreadGLDeviceFactory()->CreateSystemCapableTexture ();
_prelightTexture[0]->Update (bitmap);
- // draw active/prelight, unchecked version
+ // draw active/prelight, checked version
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
cairo_paint (cr);
@@ -335,7 +337,7 @@ QuicklistMenuItemCheckmark::UpdateTexture ()
cairo_save (cr);
cairo_translate (cr,
- _align ((ITEM_INDENT_ABS - 16.0f) / 2.0f),
+ _align ((ITEM_INDENT_ABS - 16.0f + ITEM_MARGIN) / 2.0f),
_align (((double) height - 16.0f) / 2.0f));
cairo_translate (cr, 3.0f, 1.0f);
diff --git a/src/QuicklistMenuItemLabel.cpp b/src/QuicklistMenuItemLabel.cpp
index 768df4956..52edd0af6 100755
--- a/src/QuicklistMenuItemLabel.cpp
+++ b/src/QuicklistMenuItemLabel.cpp
@@ -23,9 +23,6 @@
#include "Nux/Nux.h"
#include "QuicklistMenuItemLabel.h"
-#define ITEM_INDENT_ABS 20
-#define ITEM_CORNER_RADIUS_ABS 4
-
QuicklistMenuItemLabel::QuicklistMenuItemLabel (DbusmenuMenuitem* item,
NUX_FILE_LINE_DECL) :
QuicklistMenuItem (item,
@@ -57,7 +54,8 @@ QuicklistMenuItemLabel::Initialize (DbusmenuMenuitem* item)
int textWidth = 1;
int textHeight = 1;
GetTextExtents (textWidth, textHeight);
- SetMinimumSize (textWidth + ITEM_INDENT_ABS, textHeight);
+ SetMinimumSize (textWidth + ITEM_INDENT_ABS + 3 * ITEM_MARGIN,
+ textHeight + 2 * ITEM_MARGIN);
}
QuicklistMenuItemLabel::~QuicklistMenuItemLabel ()
@@ -129,6 +127,10 @@ void
QuicklistMenuItemLabel::Draw (nux::GraphicsEngine& gfxContext,
bool forceDraw)
{
+ // Check if the texture have been computed. If they haven't, exit the function.
+ if (_normalTexture[0] == NULL)
+ return;
+
nux::IntrusiveSP<nux::IOpenGLBaseTexture> texture;
nux::Geometry base = GetGeometry ();
diff --git a/src/QuicklistMenuItemRadio.cpp b/src/QuicklistMenuItemRadio.cpp
index 73d5ffae0..3566ee07e 100755
--- a/src/QuicklistMenuItemRadio.cpp
+++ b/src/QuicklistMenuItemRadio.cpp
@@ -22,9 +22,6 @@
#include "Nux/Nux.h"
#include "QuicklistMenuItemRadio.h"
-#define ITEM_INDENT_ABS 20.0f
-#define ITEM_CORNER_RADIUS_ABS 4.0f
-
static double
_align (double val)
{
@@ -69,8 +66,12 @@ QuicklistMenuItemRadio::Initialize (DbusmenuMenuitem* item)
_prelightTexture[0] = NULL;
_prelightTexture[1] = NULL;
- SetMinimumSize (1, 1);
- // make sure _dpiX and _dpiY are initialized correctly
+ int textWidth = 1;
+ int textHeight = 1;
+ GetTextExtents (textWidth, textHeight);
+ SetMinimumSize (textWidth + ITEM_INDENT_ABS + 3 * ITEM_MARGIN,
+ textHeight + 2 * ITEM_MARGIN);
+
}
QuicklistMenuItemRadio::~QuicklistMenuItemRadio ()
@@ -133,6 +134,10 @@ void
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)
+ return;
+
nux::IntrusiveSP<nux::IOpenGLBaseTexture> texture;
nux::Geometry base = GetGeometry ();
@@ -220,7 +225,7 @@ QuicklistMenuItemRadio::UpdateTexture ()
cairo_set_source_rgba (cr, 1.0f, 1.0f, 1.0f, 1.0f);
cairo_set_line_width (cr, 1.0f);
- double x = _align (ITEM_INDENT_ABS / 2.0f);
+ double x = _align ((ITEM_INDENT_ABS + ITEM_MARGIN) / 2.0f);
double y = _align ((double) height / 2.0f);
double radius = 3.5f;
diff --git a/src/QuicklistMenuItemSeparator.cpp b/src/QuicklistMenuItemSeparator.cpp
index 58dcedd92..f519ac9e5 100755
--- a/src/QuicklistMenuItemSeparator.cpp
+++ b/src/QuicklistMenuItemSeparator.cpp
@@ -24,9 +24,10 @@ QuicklistMenuItemSeparator::QuicklistMenuItemSeparator (DbusmenuMenuitem* item,
QuicklistMenuItem (item,
NUX_FILE_LINE_PARAM)
{
- SetMinimumHeight (3);
- SetBaseSize (64, 3);
- _normalTexture = NULL;
+ SetMinimumHeight (5);
+ SetBaseSize (64, 5);
+ //_normalTexture = NULL;
+ _color = nux::Color (1.0f, 1.0f, 1.0f, 0.5f);
_item_type = MENUITEM_TYPE_SEPARATOR;
}
@@ -37,9 +38,10 @@ QuicklistMenuItem (item,
debug,
NUX_FILE_LINE_PARAM)
{
- SetMinimumHeight (3);
- SetBaseSize (64, 3);
- _normalTexture = NULL;
+ SetMinimumHeight (5);
+ SetBaseSize (64, 5);
+ //_normalTexture = NULL;
+ _color = nux::Color (1.0f, 1.0f, 1.0f, 0.5f);
_item_type = MENUITEM_TYPE_SEPARATOR;
}
@@ -53,7 +55,7 @@ QuicklistMenuItemSeparator::PreLayoutManagement ()
_pre_layout_width = GetBaseWidth ();
_pre_layout_height = GetBaseHeight ();
- if((_normalTexture == 0) )
+ if((_normalTexture[0] == 0) )
{
UpdateTexture ();
}
@@ -102,6 +104,10 @@ void
QuicklistMenuItemSeparator::Draw (nux::GraphicsEngine& gfxContext,
bool forceDraw)
{
+ // Check if the texture have been computed. If they haven't, exit the function.
+ if (_normalTexture[0] == 0)
+ return;
+
nux::Geometry base = GetGeometry ();
gfxContext.PushClippingRectangle (base);
@@ -118,7 +124,7 @@ QuicklistMenuItemSeparator::Draw (nux::GraphicsEngine& gfxContext,
base.y,
base.width,
base.height,
- _normalTexture->GetDeviceTexture(),
+ _normalTexture[0]->GetDeviceTexture(),
texxform,
_color);
@@ -154,25 +160,25 @@ QuicklistMenuItemSeparator::UpdateTexture ()
cairo_paint (cr);
cairo_set_source_rgba (cr, _color.R (), _color.G (), _color.B (), _color.A ());
cairo_set_line_width (cr, 1.0f);
- cairo_move_to (cr, 0.5f, 1.5f);
- cairo_line_to (cr, width - 0.5f, 1.5f);
+ cairo_move_to (cr, 0.5f, 2.5f);
+ cairo_line_to (cr, width - 0.5f, 2.5f);
cairo_stroke (cr);
nux::NBitmapData* bitmap = _cairoGraphics->GetBitmap ();
- if (_normalTexture)
- _normalTexture->UnReference ();
+ if (_normalTexture[0])
+ _normalTexture[0]->UnReference ();
- _normalTexture = nux::GetThreadGLDeviceFactory()->CreateSystemCapableTexture ();
- _normalTexture->Update (bitmap);
+ _normalTexture[0] = nux::GetThreadGLDeviceFactory()->CreateSystemCapableTexture ();
+ _normalTexture[0]->Update (bitmap);
delete _cairoGraphics;
}
int QuicklistMenuItemSeparator::CairoSurfaceWidth ()
{
- if (_normalTexture)
- return _normalTexture->GetWidth ();
+ if (_normalTexture[0])
+ return _normalTexture[0]->GetWidth ();
return 0;
-} \ No newline at end of file
+}
diff --git a/src/QuicklistMenuItemSeparator.h b/src/QuicklistMenuItemSeparator.h
index 63865d559..31e18d73e 100755
--- a/src/QuicklistMenuItemSeparator.h
+++ b/src/QuicklistMenuItemSeparator.h
@@ -51,8 +51,6 @@ class QuicklistMenuItemSeparator : public QuicklistMenuItem
void DrawContent (nux::GraphicsEngine& gfxContext, bool forceDraw);
void PostDraw (nux::GraphicsEngine& gfxContext, bool forceDraw);
-
- nux::BaseTexture* _normalTexture;
virtual void UpdateTexture ();
diff --git a/src/QuicklistView.cpp b/src/QuicklistView.cpp
index 9ddc950cf..b344faabe 100755..100644
--- a/src/QuicklistView.cpp
+++ b/src/QuicklistView.cpp
@@ -71,8 +71,6 @@ QuicklistView::QuicklistView ()
_vlayout->AddLayout (_item_layout, 0);
_vlayout->AddLayout (_default_item_layout, 0);
-
- FillInDefaultItems ();
_vlayout->AddLayout (_bottom_space, 0);
@@ -119,52 +117,6 @@ QuicklistView::~QuicklistView ()
_item_list.clear ();
}
-// This function is for testing. It will go eventually
-void QuicklistView::FillInDefaultItems ()
-{
- QuicklistMenuItemCheckmark* item = 0;
- DbusmenuMenuitem* dbus_item = 0;
- // Enabled and Active Checkmark
- dbus_item = dbusmenu_menuitem_new ();
- dbusmenu_menuitem_property_set (dbus_item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, DBUSMENU_MENUITEM_TOGGLE_CHECK);
- dbusmenu_menuitem_property_set (dbus_item, DBUSMENU_MENUITEM_PROP_LABEL, "check mark 0");
- dbusmenu_menuitem_property_set_bool (dbus_item, DBUSMENU_MENUITEM_PROP_ENABLED, true);
- dbusmenu_menuitem_property_set_int (dbus_item, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED);
-
- item = new QuicklistMenuItemCheckmark (dbus_item, NUX_TRACKER_LOCATION);
-
- item->sigTextChanged.connect (sigc::mem_fun (this, &QuicklistView::RecvCairoTextChanged));
- item->sigColorChanged.connect (sigc::mem_fun (this, &QuicklistView::RecvCairoTextColorChanged));
- item->sigMouseClick.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseClick));
- item->sigMouseReleased.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseRelease));
- item->sigMouseEnter.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseEnter));
- item->sigMouseLeave.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseLeave));
-
- _default_item_layout->AddView(item, 1, nux::eCenter, nux::eFull);
- _default_item_list.push_back (item);
- item->Reference();
-
- // Disabled and Active Checkmark
- dbus_item = dbusmenu_menuitem_new ();
- dbusmenu_menuitem_property_set (dbus_item, DBUSMENU_MENUITEM_PROP_TOGGLE_TYPE, DBUSMENU_MENUITEM_TOGGLE_CHECK);
- dbusmenu_menuitem_property_set (dbus_item, DBUSMENU_MENUITEM_PROP_LABEL, "check mark disabled");
- dbusmenu_menuitem_property_set_bool (dbus_item, DBUSMENU_MENUITEM_PROP_ENABLED, false);
- dbusmenu_menuitem_property_set_int (dbus_item, DBUSMENU_MENUITEM_PROP_TOGGLE_STATE, DBUSMENU_MENUITEM_TOGGLE_STATE_UNCHECKED);
-
- item = new QuicklistMenuItemCheckmark (dbus_item, NUX_TRACKER_LOCATION);
-
- item->sigTextChanged.connect (sigc::mem_fun (this, &QuicklistView::RecvCairoTextChanged));
- item->sigColorChanged.connect (sigc::mem_fun (this, &QuicklistView::RecvCairoTextColorChanged));
- item->sigMouseClick.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseClick));
- item->sigMouseReleased.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseRelease));
- item->sigMouseEnter.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseEnter));
- item->sigMouseLeave.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseLeave));
-
- _default_item_layout->AddView(item, 1, nux::eCenter, nux::eFull);
- _default_item_list.push_back (item);
- item->Reference();
-}
-
void QuicklistView::ShowQuicklistWithTipAt (int anchor_tip_x, int anchor_tip_y)
{
int window_width;
@@ -214,8 +166,12 @@ long QuicklistView::ProcessEvent (nux::IEvent& ievent, long TraverseInfo, long P
// We choose to test the quicklist items ourselves instead of processing them as it is usual in nux.
// This is meant to be easier since the quicklist has a atypical way of working.
if (m_layout)
+ {
ret = m_layout->ProcessEvent (window_event, ret, ProcEvInfo);
-
+ }
+
+ // The quicklist itself does not process the evvent. Instead we do some analysis of the event
+ // to detect the user action and perform the correct operation.
if (ievent.e_event == nux::NUX_MOUSE_PRESSED)
{
if (GetGeometry ().IsPointInside (ievent.e_x, ievent.e_y))
@@ -227,6 +183,7 @@ long QuicklistView::ProcessEvent (nux::IEvent& ievent, long TraverseInfo, long P
_mouse_down = false;
if (IsVisible ())
{
+ CancelItemsPrelightStatus ();
CaptureMouseDownAnyWhereElse (false);
ForceStopFocus (1, 1);
UnGrabPointer ();
@@ -238,10 +195,10 @@ long QuicklistView::ProcessEvent (nux::IEvent& ievent, long TraverseInfo, long P
}
else if ((ievent.e_event == nux::NUX_MOUSE_RELEASED) && _mouse_down)
{
-
_mouse_down = false;
if (IsVisible ())
{
+ CancelItemsPrelightStatus ();
CaptureMouseDownAnyWhereElse (false);
ForceStopFocus (1, 1);
UnGrabPointer ();
@@ -251,11 +208,7 @@ long QuicklistView::ProcessEvent (nux::IEvent& ievent, long TraverseInfo, long P
return nux::eMouseEventSolved;
}
- // PostProcessEvent2 must always have its last parameter set to 0
- // because the m_BackgroundArea is the real physical limit of the window.
- // So the previous test about IsPointInside do not prevail over m_BackgroundArea
- // testing the event by itself.
- //ret = PostProcessEvent2 (ievent, ret, 0);
+
return ret;
}
@@ -435,11 +388,15 @@ void QuicklistView::RecvCairoTextColorChanged (QuicklistMenuItem* cairo_text)
NeedRedraw ();
}
-void QuicklistView::RecvItemMouseClick (QuicklistMenuItem* item)
+void QuicklistView::RecvItemMouseClick (QuicklistMenuItem* item, int x, int y)
{
_mouse_down = false;
if (IsVisible ())
{
+ // 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 ();
@@ -448,11 +405,52 @@ void QuicklistView::RecvItemMouseClick (QuicklistMenuItem* item)
}
}
-void QuicklistView::RecvItemMouseRelease (QuicklistMenuItem* item)
+void QuicklistView::CheckAndEmitItemSignal (int x, int y)
+{
+ nux::Geometry geo;
+ std::list<QuicklistMenuItem*>::iterator it;
+ for (it = _item_list.begin(); it != _item_list.end(); it++)
+ {
+ geo = (*it)->GetGeometry ();
+ geo.width = _item_layout->GetBaseWidth ();
+
+ if (geo.IsPointInside (x, y))
+ {
+ // An action is performed: send the signal back to the application
+ if ((*it)->_menuItem)
+ {
+ dbusmenu_menuitem_handle_event ((*it)->_menuItem, "clicked", NULL, 0);
+ }
+ }
+ }
+
+ for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
+ {
+ geo = (*it)->GetGeometry ();
+ geo.width = _default_item_layout->GetBaseWidth ();
+
+ if (geo.IsPointInside (x, y))
+ {
+ // An action is performed: send the signal back to the application
+ if ((*it)->_menuItem)
+ {
+ dbusmenu_menuitem_handle_event ((*it)->_menuItem, "clicked", NULL, 0);
+ }
+ }
+ }
+}
+
+void QuicklistView::RecvItemMouseRelease (QuicklistMenuItem* item, int x, int y)
{
_mouse_down = false;
+
+
if (IsVisible ())
{
+ // 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 ();
@@ -461,6 +459,57 @@ void QuicklistView::RecvItemMouseRelease (QuicklistMenuItem* item)
}
}
+void QuicklistView::CancelItemsPrelightStatus ()
+{
+ std::list<QuicklistMenuItem*>::iterator it;
+ for (it = _item_list.begin(); it != _item_list.end(); it++)
+ {
+ (*it)->_prelight = false;
+ }
+
+ for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
+ {
+ (*it)->_prelight = false;
+ }
+}
+
+void QuicklistView::RecvItemMouseDrag (QuicklistMenuItem* item, int x, int y)
+{
+ nux::Geometry geo;
+ std::list<QuicklistMenuItem*>::iterator it;
+ for (it = _item_list.begin(); it != _item_list.end(); it++)
+ {
+ geo = (*it)->GetGeometry ();
+ geo.width = _item_layout->GetBaseWidth ();
+
+ if (geo.IsPointInside (x + item->GetBaseX (), y + item->GetBaseY ()))
+ {
+ (*it)->_prelight = true;
+ }
+ else
+ {
+ (*it)->_prelight = false;
+ }
+ }
+
+ for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
+ {
+ geo = (*it)->GetGeometry ();
+ geo.width = _default_item_layout->GetBaseWidth ();
+
+ if (geo.IsPointInside (x + item->GetBaseX (), y + item->GetBaseY ()))
+ {
+ (*it)->_prelight = true;
+ }
+ else
+ {
+ (*it)->_prelight = false;
+ }
+ }
+
+ NeedRedraw ();
+}
+
void QuicklistView::RecvItemMouseEnter (QuicklistMenuItem* item)
{
NeedRedraw ();
@@ -485,13 +534,15 @@ void QuicklistView::RecvMouseDown (int x, int y, unsigned long button_flags, uns
void QuicklistView::RecvMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags)
{
-
+ // Check if the mouse was released over an item and emit the signal
+ CheckAndEmitItemSignal (x, y);
}
void QuicklistView::RecvMouseClick (int x, int y, unsigned long button_flags, unsigned long key_flags)
{
if (IsVisible ())
{
+ CancelItemsPrelightStatus ();
CaptureMouseDownAnyWhereElse (false);
ForceStopFocus (1, 1);
UnGrabPointer ();
@@ -514,6 +565,7 @@ void QuicklistView::RecvMouseDownOutsideOfQuicklist (int x, int y, unsigned long
{
if (IsVisible ())
{
+ CancelItemsPrelightStatus ();
CaptureMouseDownAnyWhereElse (false);
ForceStopFocus (1, 1);
UnGrabPointer ();
@@ -524,6 +576,17 @@ void QuicklistView::RecvMouseDownOutsideOfQuicklist (int x, int y, unsigned long
void QuicklistView::RemoveAllMenuItem ()
{
+ std::list<QuicklistMenuItem*>::iterator it;
+ for (it = _item_list.begin(); it != _item_list.end(); it++)
+ {
+ (*it)->UnReference();
+ }
+
+ for (it = _default_item_list.begin(); it != _default_item_list.end(); it++)
+ {
+ (*it)->UnReference();
+ }
+
_item_list.clear ();
_default_item_list.clear ();
@@ -544,6 +607,7 @@ void QuicklistView::AddMenuItem (QuicklistMenuItem* item)
item->sigMouseReleased.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseRelease));
item->sigMouseEnter.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseEnter));
item->sigMouseLeave.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseLeave));
+ item->sigMouseDrag.connect (sigc::mem_fun (this, &QuicklistView::RecvItemMouseDrag));
_item_layout->AddView(item, 1, nux::eCenter, nux::eFull);
_item_list.push_back (item);
@@ -868,10 +932,10 @@ void ql_tint_dot_hl (cairo_t* cr,
hl_size);
cairo_pattern_add_color_stop_rgba (hl_pattern,
0.0f,
- 1.0f,
- 1.0f,
- 1.0f,
- 0.65f);
+ rgba_hl[0],
+ rgba_hl[1],
+ rgba_hl[2],
+ rgba_hl[3]);
cairo_pattern_add_color_stop_rgba (hl_pattern, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f);
cairo_set_source (cr, hl_pattern);
cairo_fill (cr);
@@ -1033,17 +1097,42 @@ void ql_compute_mask (cairo_t* cr)
}
void ql_compute_outline (cairo_t* cr,
- gfloat line_width,
- gfloat* rgba_line)
+ gfloat line_width,
+ gfloat* rgba_line,
+ gfloat size)
{
+ cairo_pattern_t* pattern = NULL;
+ float x = 0.0f;
+ float y = 0.0f;
+ float offset = 2.5f * ANCHOR_WIDTH / size;
+
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
- cairo_set_source_rgba (cr,
+
+ pattern = cairo_pattern_create_linear (x, y, size, y);
+ cairo_pattern_add_color_stop_rgba (pattern, 0.0f,
rgba_line[0],
rgba_line[1],
rgba_line[2],
rgba_line[3]);
+ cairo_pattern_add_color_stop_rgba (pattern, offset,
+ rgba_line[0],
+ rgba_line[1],
+ rgba_line[2],
+ rgba_line[3]);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.1f * offset,
+ rgba_line[0] * 0.65f,
+ rgba_line[1] * 0.65f,
+ rgba_line[2] * 0.65f,
+ rgba_line[3]);
+ cairo_pattern_add_color_stop_rgba (pattern, 1.0f,
+ rgba_line[0] * 0.65f,
+ rgba_line[1] * 0.65f,
+ rgba_line[2] * 0.65f,
+ rgba_line[3]);
+ cairo_set_source (cr, pattern);
cairo_set_line_width (cr, line_width);
cairo_stroke (cr);
+ cairo_pattern_destroy (pattern);
}
void ql_draw (cairo_t* cr,
@@ -1137,7 +1226,7 @@ void
ql_draw (cr, TRUE, line_width, rgba_shadow, FALSE, FALSE);
ql_surface_blur (surf, blur_coeff);
ql_compute_mask (cr);
- ql_compute_outline (cr, line_width, rgba_line);
+ ql_compute_outline (cr, line_width, rgba_line, width);
}
void ql_compute_full_mask (
@@ -1207,10 +1296,10 @@ void QuicklistView::UpdateTexture ()
cairo_t *cr_outline = cairo_outline->GetContext ();
float tint_color[4] = {0.0f, 0.0f, 0.0f, 0.80f};
- float hl_color[4] = {1.0f, 1.0f, 1.0f, 0.15f};
- float dot_color[4] = {1.0f, 1.0f, 1.0f, 0.20f};
+ float hl_color[4] = {1.0f, 1.0f, 1.0f, 0.65f};
+ float dot_color[4] = {1.0f, 1.0f, 1.0f, 0.10f};
float shadow_color[4] = {0.0f, 0.0f, 0.0f, 1.00f};
- float outline_color[4] = {1.0f, 1.0f, 1.0f, 0.75f};
+ float outline_color[4] = {1.0f, 1.0f, 1.0f, 0.65f};
float mask_color[4] = {1.0f, 1.0f, 1.0f, 1.00f};
// float anchor_width = 10;
// float anchor_height = 18;
diff --git a/src/QuicklistView.h b/src/QuicklistView.h
index 8f84fba14..08e76d77a 100755
--- a/src/QuicklistView.h
+++ b/src/QuicklistView.h
@@ -81,7 +81,7 @@ public:
int GetNumItems ();
QuicklistMenuItem* GetNthItems (int index);
- QuicklistMenuItemType GetNthType (int index);
+ QuicklistMenuItemType GetNthType (int index);
std::list<QuicklistMenuItem*> GetChildren ();
void TestMenuItems (DbusmenuMenuitem* root);
@@ -89,11 +89,12 @@ public:
private:
void RecvCairoTextChanged (QuicklistMenuItem* item);
void RecvCairoTextColorChanged (QuicklistMenuItem* item);
- void RecvItemMouseClick (QuicklistMenuItem* item);
- void RecvItemMouseRelease (QuicklistMenuItem* item);
+ void RecvItemMouseClick (QuicklistMenuItem* item, int x, int y);
+ void RecvItemMouseRelease (QuicklistMenuItem* item, int x, int y);
void RecvItemMouseEnter (QuicklistMenuItem* item);
void RecvItemMouseLeave (QuicklistMenuItem* item);
-
+ void RecvItemMouseDrag (QuicklistMenuItem* item, int x, int y);
+
void RecvMouseDown (int x, int y, unsigned long button_flags, unsigned long key_flags);
void RecvMouseUp (int x, int y, unsigned long button_flags, unsigned long key_flags);
void RecvMouseClick (int x, int y, unsigned long button_flags, unsigned long key_flags);
@@ -114,6 +115,11 @@ private:
//! A convenience function to fill in the default quicklist with some random items.
void FillInDefaultItems ();
+ void CancelItemsPrelightStatus ();
+
+ //! Check the mouse up event sent by an item. Detect the item where the mous is and emit the appropriate signal.
+ void CheckAndEmitItemSignal (int x, int y);
+
//nux::CairoGraphics* _cairo_graphics;
int _anchorX;
int _anchorY;
diff --git a/src/unity.cpp b/src/unity.cpp
index 9a4ff64e6..1260ea090 100644
--- a/src/unity.cpp
+++ b/src/unity.cpp
@@ -230,6 +230,22 @@ UnityScreen::GetName ()
return "Unity";
}
+bool
+UnityWindow::glPaint (const GLWindowPaintAttrib &attrib, const GLMatrix &matrix,
+ const CompRegion &region, unsigned int mask)
+{
+ const std::list <Window> &xwns = nux::XInputWindow::NativeHandleList ();
+ GLWindowPaintAttrib new_tribs (attrib);
+
+ if (std::find (xwns.begin (), xwns.end (), window->id ()) != xwns.end ())
+ {
+ new_tribs.opacity = 0;
+ }
+
+
+ return gWindow->glPaint (new_tribs, matrix, region, mask);
+}
+
/* handle window painting in an opengl context
*
* we want to paint underneath other windows here,
diff --git a/src/unity.h b/src/unity.h
index be22b0077..25bf84e87 100644
--- a/src/unity.h
+++ b/src/unity.h
@@ -157,6 +157,10 @@ class UnityWindow :
CompWindow *window;
GLWindow *gWindow;
+ bool
+ glPaint (const GLWindowPaintAttrib &, const GLMatrix &,
+ const CompRegion &, unsigned int);
+
/* basic window draw function */
bool
glDraw (const GLMatrix &matrix,
diff --git a/tests/unit/TestUBus.cpp b/tests/unit/TestUBus.cpp
index d5dab471a..c68d63e2e 100644
--- a/tests/unit/TestUBus.cpp
+++ b/tests/unit/TestUBus.cpp
@@ -53,7 +53,7 @@ TestAllocation ()
}
void
-test_handler_inc_counter (GVariant *data, gpointer *val)
+test_handler_inc_counter (GVariant *data, gpointer val)
{
// inc a counter when we get called
gint *counter = (gint*)val;
@@ -61,7 +61,7 @@ test_handler_inc_counter (GVariant *data, gpointer *val)
}
void
-test_handler_inc_counter_2 (GVariant *data, gpointer *val)
+test_handler_inc_counter_2 (GVariant *data, gpointer val)
{
// inc a counter by two when called
gint *counter = (gint*)val;
@@ -71,17 +71,20 @@ test_handler_inc_counter_2 (GVariant *data, gpointer *val)
static void
TestPropagation ()
{
- UBusServer *ubus = ubus_server_get_default ();
- gint counter = 0;
- gulong handler1 = ubus_server_register_interest (ubus, MESSAGE1,
- test_handler_inc_counter,
- &counter);
+ UBusServer *ubus;
+ gint counter, i;
+ guint handler1, handler2;
+
+ ubus = ubus_server_get_default ();
+ handler1 = ubus_server_register_interest (ubus, MESSAGE1,
+ test_handler_inc_counter,
+ &counter);
+
+ handler2 = ubus_server_register_interest (ubus, MESSAGE2, // tests UNICODE
+ test_handler_inc_counter_2,
+ &counter);
- gulong handler2 = ubus_server_register_interest (ubus, MESSAGE2, // tests UNICODE
- test_handler_inc_counter_2,
- &counter);
-
- gint i;
+ counter = 0;
for (i=0; i<1000; i++)
{
ubus_server_send_message (ubus, MESSAGE1, NULL);
@@ -120,7 +123,7 @@ main_loop_bailout (gpointer data)
}
void
-test_handler_mainloop (GVariant *data, gpointer *val)
+test_handler_mainloop (GVariant *data, gpointer val)
{
// inc a counter when we get called
gint *counter = (gint*)val;
@@ -131,11 +134,13 @@ test_handler_mainloop (GVariant *data, gpointer *val)
static void
TestMainLoop ()
{
- GMainLoop *mainloop;
- UBusServer *ubus = ubus_server_get_default ();
- gint counter = 0;
-
+ GMainLoop *mainloop;
+ UBusServer *ubus;
+ gint counter = 0;
+
+ ubus = ubus_server_get_default ();
mainloop = g_main_loop_new (NULL, TRUE);
+
g_timeout_add_seconds (1, main_loop_bailout, mainloop);
ubus_server_register_interest (ubus, MESSAGE1,
diff --git a/tools/migrate_favorites.py b/tools/migrate_favorites.py
index 53387bf45..f29689fb2 100755
--- a/tools/migrate_favorites.py
+++ b/tools/migrate_favorites.py
@@ -60,8 +60,12 @@ def register_new_app(launcher_location, apps_list):
return apps_list
+try:
+ migration_level = subprocess.Popen(["gsettings", "get", "com.canonical.Unity.Launcher", "favorite-migration"], stdout=subprocess.PIPE).communicate()[0].strip()[1:-1]
+except OSError, e:
+ print "Gsettings not executable or not installed, postponing migration. The error was: %s" % e
+ sys.exit(1)
-migration_level = subprocess.Popen(["gsettings", "get", "com.canonical.Unity.Launcher", "favorite-migration"], stdout=subprocess.PIPE).communicate()[0].strip()[1:-1]
if migration_level >= LAST_MIGRATION:
print "Migration already done"
sys.exit(0)