diff options
| author | Didier Roche <didier.roche@canonical.com> | 2011-02-17 19:15:27 +0100 |
|---|---|---|
| committer | Didier Roche <didier.roche@canonical.com> | 2011-02-17 19:15:27 +0100 |
| commit | 1c93238eadf8e691598255c11beebe391a6eb4f7 (patch) | |
| tree | 18d319c96970b62ffa1e8fb8d53e759cfe09cf11 | |
| parent | 76475e02021228c31ca77047941ef4b3b5a3fb75 (diff) | |
| parent | 5cd66dcf75eec0bcec5f3b6bdede8c3c54953885 (diff) | |
Import upstream version 3.4.4upstream-3.4.4
(bzr r55.4.43)
82 files changed, 2876 insertions, 793 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ba79be9d..7e4fedb93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ subdirs (services tests tools doc) set (PROJECT_NAME "unity") set (UNITY_MAJOR 3) set (UNITY_MINOR 4) -set (UNITY_MICRO 2) +set (UNITY_MICRO 4) set (UNITY_VERSION "${UNITY_MAJOR}.${UNITY_MINOR}.${UNITY_MICRO}") set (UNITY_API_VERSION "3.0") @@ -85,17 +85,23 @@ if (BOOT_LOGGER) SET (BOOT_LOGGER_FLAG "-DENABLE_LOGGER") endif (BOOT_LOGGER) +SET (MAINTAINER_CFLAGS "-Werror -Wall -Wcast-align -Wno-uninitialized -Wempty-body -Wformat-security -Winit-self") +option (DISABLE_MAINTAINER_CFLAGS "Disable maintainer CFlags" OFF) +if (DISABLE_MAINTAINER_CFLAGS) + SET (MAINTAINER_CFLAGS "") +endif (DISABLE_MAINTAINER_CFLAGS) + # # src (Compiz Plugin) # -set (UNITY_PLUGIN_DEPS "nux-0.9;libbamf;dee-1.0;gio-2.0;gio-unix-2.0;dbusmenu-glib-0.4;x11;libstartup-notification-1.0;gthread-2.0;indicator;atk") +set (UNITY_PLUGIN_DEPS "nux-0.9;libbamf;dee-1.0;gio-2.0;gio-unix-2.0;dbusmenu-glib-0.4;x11;libstartup-notification-1.0;gthread-2.0;indicator;atk;unity-misc") find_package (Compiz REQUIRED) include (CompizPlugin) compiz_plugin (unityshell PKGDEPS ${UNITY_PLUGIN_DEPS} PLUGINDEPS composite opengl - CFLAGSADD "-DINSTALLPREFIX='\"${CMAKE_INSTALL_PREFIX}\"' -DPKGDATADIR='\"${CMAKE_INSTALL_PREFIX}/share/unity/3\"' -I${CMAKE_BINARY_DIR} ${BOOT_LOGGER_FLAG} -DGETTEXT_PACKAGE='\"unity\"'" + CFLAGSADD "-DINSTALLPREFIX='\"${CMAKE_INSTALL_PREFIX}\"' -DPKGDATADIR='\"${CMAKE_INSTALL_PREFIX}/share/unity/3\"' -I${CMAKE_BINARY_DIR} ${BOOT_LOGGER_FLAG} -DGETTEXT_PACKAGE='\"unity\"' ${MAINTAINER_CFLAGS}" ) # diff --git a/com.canonical.Unity.gschema.xml b/com.canonical.Unity.gschema.xml index 58b2ca719..66f291e12 100644 --- a/com.canonical.Unity.gschema.xml +++ b/com.canonical.Unity.gschema.xml @@ -11,4 +11,11 @@ <description>This is a detection key for the favorite migration script to know whether the needed migration is done or not.</description> </key> </schema> + <schema path="/desktop/unity/panel/" id="com.canonical.Unity.Panel" gettext-domain="unity"> + <key type="as" name="systray-whitelist"> + <default>[ 'JavaEmbeddedFrame', 'Wine', 'Skype' ]</default> + <summary>List of client names, resource classes or wm classes to allow in the Panel's systray implementation.</summary> + <description>"" (empty) will not allow any tray icons, "all" will allow all tray icons, otherwise there will be an attempt to match each icon to a value here.</description> + </key> + </schema> </schemalist> diff --git a/resources/places-tile-bg-tilable.png b/resources/places-tile-bg-tilable.png Binary files differnew file mode 100644 index 000000000..c0fde8dce --- /dev/null +++ b/resources/places-tile-bg-tilable.png diff --git a/services/CMakeLists.txt b/services/CMakeLists.txt index e7e177f57..913ca1c35 100644 --- a/services/CMakeLists.txt +++ b/services/CMakeLists.txt @@ -10,6 +10,7 @@ execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} indicator --variable iconsdir set(CFLAGS ${SERVICE_DEPS_CFLAGS} ${SERVICE_DEPS_CFLAGS_OTHER} + ${MAINTAINER_CFLAGS} "-DGETTEXT_PACKAGE=\"unity\"" "-DINDICATORDIR=\"${_indicatordir}\"" "-DINDICATORICONDIR=\"${_iconsdir}\"" @@ -28,6 +29,8 @@ add_executable(unity-panel-service panel-a11y.h panel-indicator-accessible.c panel-indicator-accessible.h + panel-indicator-entry-accessible.c + panel-indicator-entry-accessible.h panel-main.c panel-root-accessible.c panel-root-accessible.h diff --git a/services/panel-indicator-accessible.c b/services/panel-indicator-accessible.c index 8e660b248..39f71f865 100644 --- a/services/panel-indicator-accessible.c +++ b/services/panel-indicator-accessible.c @@ -18,6 +18,7 @@ #include <glib/gi18n.h> #include "panel-indicator-accessible.h" +#include "panel-indicator-entry-accessible.h" G_DEFINE_TYPE(PanelIndicatorAccessible, panel_indicator_accessible, ATK_TYPE_OBJECT) @@ -30,9 +31,33 @@ static AtkObject *panel_indicator_accessible_ref_child (AtkObject *accessib struct _PanelIndicatorAccessiblePrivate { + IndicatorObject *indicator; + GSList *a11y_children; }; static void +panel_indicator_accessible_finalize (GObject *object) +{ + PanelIndicatorAccessible *pia = PANEL_INDICATOR_ACCESSIBLE (object); + + if (pia->priv != NULL) + { + if (pia->priv->indicator != NULL) + g_object_unref (G_OBJECT (pia->priv->indicator)); + + while (pia->priv->a11y_children != NULL) + { + AtkObject *accessible = ATK_OBJECT (pia->priv->a11y_children->data); + + pia->priv->a11y_children = g_slist_remove (pia->priv->a11y_children, accessible); + g_object_unref (accessible); + } + } + + G_OBJECT_CLASS (panel_indicator_accessible_parent_class)->finalize (object); +} + +static void panel_indicator_accessible_class_init (PanelIndicatorAccessibleClass *klass) { GObjectClass *object_class; @@ -40,6 +65,7 @@ panel_indicator_accessible_class_init (PanelIndicatorAccessibleClass *klass) /* GObject */ object_class = G_OBJECT_CLASS (klass); + object_class->finalize = panel_indicator_accessible_finalize; /* AtkObject */ atk_class = ATK_OBJECT_CLASS (klass); @@ -54,18 +80,58 @@ static void panel_indicator_accessible_init (PanelIndicatorAccessible *pia) { pia->priv = GET_PRIVATE (pia); + pia->priv->a11y_children = NULL; } AtkObject * -panel_indicator_accessible_new (void) +panel_indicator_accessible_new (IndicatorObject *indicator) { - AtkObject *accessible; + PanelIndicatorAccessible *pia; - accessible = ATK_OBJECT (g_object_new (PANEL_TYPE_INDICATOR_ACCESSIBLE, NULL)); + pia = g_object_new (PANEL_TYPE_INDICATOR_ACCESSIBLE, NULL); + atk_object_initialize (ATK_OBJECT (pia), indicator); + + return ATK_OBJECT (pia); +} - atk_object_initialize (accessible, NULL); +/* Indicator callbacks */ - return accessible; +static void +on_indicator_entry_added (IndicatorObject *io, IndicatorObjectEntry *entry, gpointer user_data) +{ + AtkObject *accessible; + PanelIndicatorAccessible *pia = PANEL_INDICATOR_ACCESSIBLE (user_data); + + accessible = panel_indicator_entry_accessible_new (entry); + if (accessible != NULL) + { + pia->priv->a11y_children = g_slist_append (pia->priv->a11y_children, accessible); + g_signal_emit_by_name (ATK_OBJECT (pia), "children-changed", + g_slist_length (pia->priv->a11y_children) - 1, + accessible); + } +} + +static void +on_indicator_entry_removed (IndicatorObject *io, IndicatorObjectEntry *entry, gpointer user_data) +{ + GSList *l; + guint count = 0; + PanelIndicatorAccessible *pia = PANEL_INDICATOR_ACCESSIBLE (user_data); + + for (l = pia->priv->a11y_children; l != NULL; l = l->next, count++) + { + AtkObject *accessible = ATK_OBJECT (l->data); + + if (entry == panel_indicator_entry_accessible_get_entry (PANEL_INDICATOR_ENTRY_ACCESSIBLE (accessible))) + { + pia->priv->a11y_children = g_slist_remove (pia->priv->a11y_children, accessible); + g_signal_emit_by_name (ATK_OBJECT (pia), "children-changed", + count, accessible); + + g_object_unref (accessible); + } + } } /* Implementation of AtkObject methods */ @@ -73,26 +139,53 @@ panel_indicator_accessible_new (void) static void panel_indicator_accessible_initialize (AtkObject *accessible, gpointer data) { + PanelIndicatorAccessible *pia; + GList *entries, *l; + g_return_if_fail (PANEL_IS_INDICATOR_ACCESSIBLE (accessible)); ATK_OBJECT_CLASS (panel_indicator_accessible_parent_class)->initialize (accessible, data); + pia = PANEL_INDICATOR_ACCESSIBLE (accessible); atk_object_set_name (accessible, _("An indicator")); /* FIXME */ - atk_object_set_role (accessible, ATK_ROLE_LABEL); + atk_object_set_role (accessible, ATK_ROLE_PANEL); + + /* Setup the indicator object */ + pia->priv->indicator = g_object_ref (data); + g_signal_connect (G_OBJECT (pia->priv->indicator), "entry-added", + G_CALLBACK (on_indicator_entry_added), pia); + g_signal_connect (G_OBJECT (pia->priv->indicator), "entry-removed", + G_CALLBACK (on_indicator_entry_removed), pia); + + /* Retrieve all entries and create their accessible objects */ + entries = indicator_object_get_entries (pia->priv->indicator); + for (l = entries; l != NULL; l = l->next) + { + AtkObject *accessible; + + accessible = panel_indicator_entry_accessible_new ((IndicatorObjectEntry *) l->data); + pia->priv->a11y_children = g_slist_append (pia->priv->a11y_children, accessible); + } + + g_list_free (entries); } static gint panel_indicator_accessible_get_n_children (AtkObject *accessible) { - g_return_val_if_fail (PANEL_IS_INDICATOR_ACCESSIBLE (accessible), 0); + PanelIndicatorAccessible *pia = PANEL_INDICATOR_ACCESSIBLE (accessible); - return 0; + g_return_val_if_fail (PANEL_IS_INDICATOR_ACCESSIBLE (pia), 0); + + return g_slist_length (pia->priv->a11y_children); } static AtkObject * panel_indicator_accessible_ref_child (AtkObject *accessible, gint i) { - g_return_val_if_fail (PANEL_IS_INDICATOR_ACCESSIBLE (accessible), NULL); + PanelIndicatorAccessible *pia = PANEL_INDICATOR_ACCESSIBLE (accessible); + + g_return_val_if_fail (PANEL_IS_INDICATOR_ACCESSIBLE (pia), NULL); - return NULL; + return g_object_ref (g_slist_nth_data (pia->priv->a11y_children, i)); } diff --git a/services/panel-indicator-accessible.h b/services/panel-indicator-accessible.h index 0bad990b3..685387d49 100644 --- a/services/panel-indicator-accessible.h +++ b/services/panel-indicator-accessible.h @@ -20,6 +20,8 @@ #define _PANEL_INDICATOR_ACCESSIBLE_H_ #include <atk/atk.h> +#include <libindicator/indicator.h> +#include <libindicator/indicator-object.h> G_BEGIN_DECLS @@ -46,7 +48,7 @@ struct _PanelIndicatorAccessibleClass }; GType panel_indicator_accessible_get_type (void); -AtkObject *panel_indicator_accessible_new (void); +AtkObject *panel_indicator_accessible_new (IndicatorObject *indicator); G_END_DECLS diff --git a/services/panel-indicator-entry-accessible.c b/services/panel-indicator-entry-accessible.c new file mode 100644 index 000000000..e888bd9f8 --- /dev/null +++ b/services/panel-indicator-entry-accessible.c @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2011 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: Rodrigo Moya <rodrigo.moya@canonical.com> + */ + +#include "panel-indicator-entry-accessible.h" + +G_DEFINE_TYPE(PanelIndicatorEntryAccessible, panel_indicator_entry_accessible, ATK_TYPE_OBJECT) + +#define GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), PANEL_TYPE_INDICATOR_ENTRY_ACCESSIBLE, PanelIndicatorEntryAccessiblePrivate)) + +/* AtkObject methods */ +static void panel_indicator_entry_accessible_initialize (AtkObject *accessible, gpointer data); +static gint panel_indicator_entry_accessible_get_n_children (AtkObject *accessible); +static AtkObject *panel_indicator_entry_accessible_ref_child (AtkObject *accessible, gint i); + +struct _PanelIndicatorEntryAccessiblePrivate +{ + IndicatorObjectEntry *entry; +}; + +static void +panel_indicator_entry_accessible_class_init (PanelIndicatorEntryAccessibleClass *klass) +{ + GObjectClass *object_class; + AtkObjectClass *atk_class; + + /* GObject */ + object_class = G_OBJECT_CLASS (klass); + + /* AtkObject */ + atk_class = ATK_OBJECT_CLASS (klass); + atk_class->initialize = panel_indicator_entry_accessible_initialize; + atk_class->get_n_children = panel_indicator_entry_accessible_get_n_children; + atk_class->ref_child = panel_indicator_entry_accessible_ref_child; + + g_type_class_add_private (object_class, sizeof (PanelIndicatorEntryAccessiblePrivate)); +} + +static void +panel_indicator_entry_accessible_init (PanelIndicatorEntryAccessible *piea) +{ + piea->priv = GET_PRIVATE (piea); +} + +AtkObject * +panel_indicator_entry_accessible_new (IndicatorObjectEntry *entry) +{ + PanelIndicatorEntryAccessible *piea; + + piea = g_object_new (PANEL_TYPE_INDICATOR_ENTRY_ACCESSIBLE, NULL); + atk_object_initialize (ATK_OBJECT (piea), entry); + + return ATK_OBJECT (piea); +} + +IndicatorObjectEntry * +panel_indicator_entry_accessible_get_entry (PanelIndicatorEntryAccessible *piea) +{ + g_return_val_if_fail (PANEL_IS_INDICATOR_ENTRY_ACCESSIBLE (piea), NULL); + + return piea->priv->entry; +} + +/* Implementation of AtkObject methods */ + +static void +panel_indicator_entry_accessible_initialize (AtkObject *accessible, gpointer data) +{ + PanelIndicatorEntryAccessible *piea; + + g_return_if_fail (PANEL_IS_INDICATOR_ENTRY_ACCESSIBLE (accessible)); + + ATK_OBJECT_CLASS (panel_indicator_entry_accessible_parent_class)->initialize (accessible, data); + + piea = PANEL_INDICATOR_ENTRY_ACCESSIBLE (accessible); + piea->priv->entry = (IndicatorObjectEntry *) data; + + if (GTK_IS_LABEL (piea->priv->entry->label)) + { + atk_object_set_role (accessible, ATK_ROLE_LABEL); + atk_object_set_name (accessible, gtk_label_get_text (piea->priv->entry->label)); + } + if (GTK_IS_IMAGE (piea->priv->entry->image)) + { + atk_object_set_role (accessible, ATK_ROLE_IMAGE); + } +} + +static gint +panel_indicator_entry_accessible_get_n_children (AtkObject *accessible) +{ + PanelIndicatorEntryAccessible *piea; + gint n_children = 0; + + g_return_val_if_fail (PANEL_IS_INDICATOR_ENTRY_ACCESSIBLE (accessible), 0); + + piea = PANEL_INDICATOR_ENTRY_ACCESSIBLE (accessible); + if (GTK_IS_MENU (piea->priv->entry->menu)) + n_children = 1; + + return n_children; +} + +static AtkObject * +panel_indicator_entry_accessible_ref_child (AtkObject *accessible, gint i) +{ + PanelIndicatorEntryAccessible *piea; + AtkObject *child = NULL; + + g_return_val_if_fail (PANEL_IS_INDICATOR_ENTRY_ACCESSIBLE (accessible), NULL); + + piea = PANEL_INDICATOR_ENTRY_ACCESSIBLE (accessible); + if (GTK_IS_MENU (piea->priv->entry->menu)) + child = gtk_widget_get_accessible (GTK_WIDGET (piea->priv->entry->menu)); + + return child; +} diff --git a/services/panel-indicator-entry-accessible.h b/services/panel-indicator-entry-accessible.h new file mode 100644 index 000000000..a1eb2c86e --- /dev/null +++ b/services/panel-indicator-entry-accessible.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2011 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: Rodrigo Moya <rodrigo.moya@canonical.com> + */ + +#ifndef _PANEL_INDICATOR_ENTRY_ACCESSIBLE_H_ +#define _PANEL_INDICATOR_ENTRY_ACCESSIBLE_H_ + +#include <atk/atk.h> +#include <libindicator/indicator.h> +#include <libindicator/indicator-object.h> + +G_BEGIN_DECLS + +#define PANEL_TYPE_INDICATOR_ENTRY_ACCESSIBLE (panel_indicator_entry_accessible_get_type ()) +#define PANEL_INDICATOR_ENTRY_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PANEL_TYPE_INDICATOR_ENTRY_ACCESSIBLE, PanelIndicatorEntryAccessible)) +#define PANEL_INDICATOR_ENTRY_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANEL_TYPE_INDICATOR_ENTRY_ACCESSIBLE, PanelIndicatorEntryAccessibleClass)) +#define PANEL_IS_INDICATOR_ENTRY_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PANEL_TYPE_INDICATOR_ENTRY_ACCESSIBLE)) +#define PANEL_IS_INDICATOR_ENTRY_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANEL_TYPE_INDICATOR_ENTRY_ACCESSIBLE)) +#define PANEL_INDICATOR_ENTRY_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANEL_TYPE_INDICATOR_ENTRY_ACCESSIBLE, PanelIndicatorEntryAccessibleClass)) + +typedef struct _PanelIndicatorEntryAccessible PanelIndicatorEntryAccessible; +typedef struct _PanelIndicatorEntryAccessibleClass PanelIndicatorEntryAccessibleClass; +typedef struct _PanelIndicatorEntryAccessiblePrivate PanelIndicatorEntryAccessiblePrivate; + +struct _PanelIndicatorEntryAccessible +{ + AtkObject parent; + PanelIndicatorEntryAccessiblePrivate *priv; +}; + +struct _PanelIndicatorEntryAccessibleClass +{ + AtkObjectClass parent_class; +}; + +GType panel_indicator_entry_accessible_get_type (void); +AtkObject *panel_indicator_entry_accessible_new (IndicatorObjectEntry *entry); + +IndicatorObjectEntry *panel_indicator_entry_accessible_get_entry (PanelIndicatorEntryAccessible *piea); + +G_END_DECLS + +#endif diff --git a/services/panel-root-accessible.c b/services/panel-root-accessible.c index 966ba6596..1453b7e26 100644 --- a/services/panel-root-accessible.c +++ b/services/panel-root-accessible.c @@ -33,9 +33,28 @@ static AtkObject *panel_root_accessible_get_parent (AtkObject *accessible); struct _PanelRootAccessiblePrivate { + PanelService *service; + GSList *a11y_children; }; static void +panel_root_accessible_finalize (GObject *object) +{ + PanelRootAccessible *root = PANEL_ROOT_ACCESSIBLE (object); + + if (root->priv != NULL) + { + while (root->priv->a11y_children != NULL) + { + AtkObject *accessible = ATK_OBJECT (root->priv->a11y_children->data); + + root->priv->a11y_children = g_slist_remove (root->priv->a11y_children, accessible); + g_object_unref (accessible); + } + } +} + +static void panel_root_accessible_class_init (PanelRootAccessibleClass *klass) { GObjectClass *object_class; @@ -43,6 +62,7 @@ panel_root_accessible_class_init (PanelRootAccessibleClass *klass) /* GObject */ object_class = G_OBJECT_CLASS (klass); + object_class->finalize = panel_root_accessible_finalize; /* AtkObject */ atk_class = ATK_OBJECT_CLASS (klass); @@ -58,6 +78,8 @@ static void panel_root_accessible_init (PanelRootAccessible *root) { root->priv = GET_PRIVATE (root); + root->priv->a11y_children = NULL; + root->priv->service = panel_service_get_default (); } AtkObject * @@ -76,6 +98,9 @@ panel_root_accessible_new (void) static void panel_root_accessible_initialize (AtkObject *accessible, gpointer data) { + gint n_children, i; + PanelRootAccessible *root = PANEL_ROOT_ACCESSIBLE (accessible); + g_return_if_fail (PANEL_IS_ROOT_ACCESSIBLE (accessible)); ATK_OBJECT_CLASS (panel_root_accessible_parent_class)->initialize (accessible, data); @@ -83,41 +108,48 @@ panel_root_accessible_initialize (AtkObject *accessible, gpointer data) accessible->role = ATK_ROLE_APPLICATION; atk_object_set_name (accessible, g_get_prgname ()); atk_object_set_parent (accessible, NULL); + + /* Retrieve all indicators and create their accessible objects */ + n_children = panel_service_get_n_indicators (root->priv->service); + for (i = 0; i < n_children; i++) + { + IndicatorObject *indicator; + + indicator = panel_service_get_indicator (root->priv->service, i); + if (indicator != NULL) + { + AtkObject *accessible; + + accessible = panel_indicator_accessible_new (indicator); + root->priv->a11y_children = g_slist_append (root->priv->a11y_children, accessible); + } + } } static gint panel_root_accessible_get_n_children (AtkObject *accessible) { - guint n_children; + PanelRootAccessible *root = PANEL_ROOT_ACCESSIBLE (accessible); g_return_val_if_fail (PANEL_IS_ROOT_ACCESSIBLE (accessible), 0); - n_children = panel_service_get_n_indicators (panel_service_get_default ()); - - g_debug ("PanelRootAccessible has %d children", n_children); - - return n_children; + return g_slist_length (root->priv->a11y_children); } static AtkObject * panel_root_accessible_ref_child (AtkObject *accessible, gint i) { - AtkObject *child; + PanelRootAccessible *root = PANEL_ROOT_ACCESSIBLE (accessible); g_return_val_if_fail (PANEL_IS_ROOT_ACCESSIBLE (accessible), NULL); - child = panel_indicator_accessible_new (); /* FIXME */ - atk_object_set_parent (child, accessible); - - g_debug ("Returning ATK child %p", child); - - return child; + return g_object_ref (g_slist_nth_data (root->priv->a11y_children, i)); } static AtkObject * panel_root_accessible_get_parent (AtkObject *accessible) { - g_return_val_if_fail (PANEL_IS_ROOT_ACCESSIBLE (accessible), NULL); + g_return_val_if_fail (PANEL_IS_ROOT_ACCESSIBLE (accessible), NULL); - return NULL; + return NULL; } diff --git a/services/panel-service.c b/services/panel-service.c index c2fcd1d08..99ec9a2e0 100644 --- a/services/panel-service.c +++ b/services/panel-service.c @@ -14,6 +14,7 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * * Authored by: Neil Jagdish Patel <neil.patel@canonical.com> + * Rodrigo Moya <rodrigo.moya@canonical.com> */ #if HAVE_CONFIG_H @@ -23,8 +24,6 @@ #include "panel-service.h" #include <stdlib.h> -#include <libindicator/indicator.h> -#include <libindicator/indicator-object.h> #include <gtk/gtk.h> #include <gdk/gdkx.h> @@ -341,6 +340,14 @@ panel_service_get_n_indicators (PanelService *self) return g_slist_length (self->priv->indicators); } +IndicatorObject * +panel_service_get_indicator (PanelService *self, guint position) +{ + g_return_val_if_fail (PANEL_IS_SERVICE (self), NULL); + + return (IndicatorObject *) g_slist_nth_data (self->priv->indicators, position); +} + /* * Private Methods */ @@ -956,10 +963,13 @@ panel_service_show_entry (PanelService *self, { PanelServicePrivate *priv = self->priv; IndicatorObjectEntry *entry = g_hash_table_lookup (priv->id2entry_hash, entry_id); - IndicatorObject *object = g_hash_table_lookup (priv->entry2indicator_hash, entry); + IndicatorObject *object = g_hash_table_lookup (priv->entry2indicator_hash, entry); + GtkWidget *last_menu; if (priv->last_entry == entry) return; + + last_menu = GTK_WIDGET (priv->last_menu); if (GTK_IS_MENU (priv->last_menu)) { @@ -968,7 +978,6 @@ panel_service_show_entry (PanelService *self, g_signal_handler_disconnect (priv->last_menu, priv->last_menu_id); g_signal_handler_disconnect (priv->last_menu, priv->last_menu_move_id); - gtk_menu_popdown (GTK_MENU (priv->last_menu)); priv->last_entry = NULL; priv->last_menu = NULL; @@ -1009,6 +1018,13 @@ panel_service_show_entry (PanelService *self, g_signal_emit (self, _service_signals[ENTRY_ACTIVATED], 0, entry_id); } + + /* We popdown the old one last so we don't accidently send key focus back to the + * active application (which will make it change colour (as state changes), which + * then looks like flickering to the user. + */ + if (GTK_MENU (last_menu)) + gtk_menu_popdown (GTK_MENU (last_menu)); } void diff --git a/services/panel-service.h b/services/panel-service.h index 9429482ba..fda818fc8 100644 --- a/services/panel-service.h +++ b/services/panel-service.h @@ -20,6 +20,8 @@ #define _PANEL_SERVICE_H_ #include <glib-object.h> +#include <libindicator/indicator.h> +#include <libindicator/indicator-object.h> G_BEGIN_DECLS @@ -64,33 +66,35 @@ struct _PanelServiceClass void (*_view_padding6) (void); }; -GType panel_service_get_type (void) G_GNUC_CONST; +GType panel_service_get_type (void) G_GNUC_CONST; -PanelService * panel_service_get_default (); +PanelService * panel_service_get_default (); -PanelService * panel_service_get_default_with_indicators (GList *indicators); +PanelService * panel_service_get_default_with_indicators (GList *indicators); -guint panel_service_get_n_indicators (PanelService *self); +guint panel_service_get_n_indicators (PanelService *self); -GVariant * panel_service_sync (PanelService *self); +IndicatorObject * panel_service_get_indicator (PanelService *self, guint position); -GVariant * panel_service_sync_one (PanelService *self, - const gchar *indicator_id); +GVariant * panel_service_sync (PanelService *self); -void panel_service_show_entry (PanelService *self, - const gchar *entry_id, - guint32 timestamp, - gint32 x, - gint32 y, - gint32 button); +GVariant * panel_service_sync_one (PanelService *self, + const gchar *indicator_id); -void panel_service_scroll_entry (PanelService *self, - const gchar *entry_id, - gint32 delta); +void panel_service_show_entry (PanelService *self, + const gchar *entry_id, + guint32 timestamp, + gint32 x, + gint32 y, + gint32 button); -void panel_service_get_last_xy (PanelService *self, - gint *x, - gint *y); +void panel_service_scroll_entry (PanelService *self, + const gchar *entry_id, + gint32 delta); + +void panel_service_get_last_xy (PanelService *self, + gint *x, + gint *y); G_END_DECLS diff --git a/services/panel-util-accessible.c b/services/panel-util-accessible.c index 9fc3e1deb..89e59b1f2 100644 --- a/services/panel-util-accessible.c +++ b/services/panel-util-accessible.c @@ -22,7 +22,7 @@ G_DEFINE_TYPE(PanelUtilAccessible, panel_util_accessible, ATK_TYPE_UTIL) /* AtkUtil methods */ -static AtkObject *panel_util_accessible_get_root (void); +static AtkObject *panel_util_accessible_get_root (void); static AtkObject *root = NULL; @@ -53,7 +53,5 @@ panel_util_accessible_get_root (void) if (!root) root = panel_root_accessible_new (); - g_debug ("Returning root A11Y object at %p", root); - return root; } diff --git a/src/BamfLauncherIcon.cpp b/src/BamfLauncherIcon.cpp index df0112e01..28b8c592e 100644 --- a/src/BamfLauncherIcon.cpp +++ b/src/BamfLauncherIcon.cpp @@ -55,7 +55,7 @@ static void shortcut_activated (DbusmenuMenuitem* _sender, guint timestamp, gpoi } void -BamfLauncherIcon::Activate () +BamfLauncherIcon::ActivateLauncherIcon () { bool scaleWasActive = PluginAdapter::Default ()->IsScaleActive (); @@ -75,12 +75,12 @@ BamfLauncherIcon::Activate () if (GetQuirk (QUIRK_STARTING)) return; SetQuirk (QUIRK_STARTING, true); - OpenInstance (); + OpenInstanceLauncherIcon (); return; } else if (scaleWasActive) { - if (!Spread ()) + if (!Spread (0, false)) { PluginAdapter::Default ()->TerminateScale (); Focus (); @@ -93,8 +93,10 @@ BamfLauncherIcon::Activate () } else if (active && !scaleWasActive) { - Spread (); + Spread (0, false); } + + ubus_server_send_message (ubus_server_get_default (), UBUS_LAUNCHER_ACTION_DONE, NULL); } BamfLauncherIcon::BamfLauncherIcon (Launcher* IconManager, BamfApplication *app, CompScreen *screen) @@ -103,6 +105,8 @@ BamfLauncherIcon::BamfLauncherIcon (Launcher* IconManager, BamfApplication *app, m_App = app; m_Screen = screen; _remote_uri = 0; + _dnd_hover_timer = 0; + _dnd_hovered = false; _menu_desktop_shortcuts = NULL; char *icon_name = bamf_view_get_icon (BAMF_VIEW (m_App)); @@ -137,6 +141,7 @@ BamfLauncherIcon::BamfLauncherIcon (Launcher* IconManager, BamfApplication *app, /* hack */ SetProgress (0.0f); + } BamfLauncherIcon::~BamfLauncherIcon() @@ -278,10 +283,11 @@ BamfLauncherIcon::OpenInstanceWithUris (std::list<char *> uris) } void -BamfLauncherIcon::OpenInstance () +BamfLauncherIcon::OpenInstanceLauncherIcon () { std::list<char *> empty; OpenInstanceWithUris (empty); + ubus_server_send_message (ubus_server_get_default (), UBUS_LAUNCHER_ACTION_DONE, NULL); } void @@ -391,7 +397,7 @@ BamfLauncherIcon::Focus () } bool -BamfLauncherIcon::Spread () +BamfLauncherIcon::Spread (int state, bool force) { BamfView *view; GList *children, *l; @@ -410,11 +416,11 @@ BamfLauncherIcon::Spread () } } - if (windowList.size () > 1) + if (windowList.size () > 1 || (windowList.size () > 0 && force)) { std::string *match = PluginAdapter::Default ()->MatchStringForXids (&windowList); _launcher->SetLastSpreadIcon ((LauncherIcon *) this); - PluginAdapter::Default ()->InitiateScale (match); + PluginAdapter::Default ()->InitiateScale (match, state); delete match; g_list_free (children); return true; @@ -429,11 +435,9 @@ void BamfLauncherIcon::OnMouseClick (int button) { if (button == 1) - Activate (); + ActivateLauncherIcon (); else if (button == 2) - OpenInstance (); - - ubus_server_send_message (ubus_server_get_default (), UBUS_LAUNCHER_ACTION_DONE, NULL); + OpenInstanceLauncherIcon (); } void @@ -891,12 +895,38 @@ BamfLauncherIcon::ValidateUrisForLaunch (std::list<char *> uris) g_object_unref (info); } - g_strfreev (mimes); g_key_file_free (key_file); return results; } +gboolean +BamfLauncherIcon::OnDndHoveredTimeout (gpointer data) +{ + BamfLauncherIcon *self = (BamfLauncherIcon*) data; + if (self->_dnd_hovered && bamf_view_is_running (BAMF_VIEW (self->m_App))) + self->Spread (CompAction::StateInitEdgeDnd, true); + + return false; +} + +void +BamfLauncherIcon::OnDndEnter () +{ + _dnd_hovered = true; + _dnd_hover_timer = g_timeout_add (1000, &BamfLauncherIcon::OnDndHoveredTimeout, this); +} + +void +BamfLauncherIcon::OnDndLeave () +{ + _dnd_hovered = false; + + if (_dnd_hover_timer) + g_source_remove (_dnd_hover_timer); + _dnd_hover_timer = 0; +} + nux::DndAction BamfLauncherIcon::OnQueryAcceptDrop (std::list<char *> uris) { diff --git a/src/BamfLauncherIcon.h b/src/BamfLauncherIcon.h index 9f48c3553..2653c141e 100644 --- a/src/BamfLauncherIcon.h +++ b/src/BamfLauncherIcon.h @@ -41,7 +41,6 @@ public: const char* DesktopFile (); bool IsSticky (); - void Activate (); protected: void OnMouseClick (int button); @@ -56,6 +55,11 @@ protected: nux::DndAction OnQueryAcceptDrop (std::list<char *> uris); void OnAcceptDrop (std::list<char *> uris); + void OnDndEnter (); + void OnDndLeave (); + + void ActivateLauncherIcon (); + void OpenInstanceLauncherIcon (); std::list<char *> ValidateUrisForLaunch (std::list<char *> uris); @@ -66,15 +70,16 @@ private: std::map<std::string, DbusmenuMenuitem *> _menu_items; DbusmenuMenuitem *_menu_desktop_shortcuts; gchar *_remote_uri; + bool _dnd_hovered; + guint _dnd_hover_timer; void EnsureWindowState (); void UpdateMenus (); void OpenInstanceWithUris (std::list<char *> uris); - void OpenInstance (); void Focus (); - bool Spread (); + bool Spread (int state, bool force); void EnsureMenuItemsReady (); @@ -92,6 +97,8 @@ private: static void OnQuit (DbusmenuMenuitem *item, int time, BamfLauncherIcon *self); static void OnLaunch (DbusmenuMenuitem *item, int time, BamfLauncherIcon *self); static void OnTogglePin (DbusmenuMenuitem *item, int time, BamfLauncherIcon *self); + + static gboolean OnDndHoveredTimeout (gpointer data); }; #endif // BAMFLAUNCHERICON_H diff --git a/src/IconTexture.cpp b/src/IconTexture.cpp index b32717dce..580268636 100644 --- a/src/IconTexture.cpp +++ b/src/IconTexture.cpp @@ -23,6 +23,7 @@ #include "NuxGraphics/GLThread.h" #include "IconLoader.h" #include "IconTexture.h" +#include "TextureCache.h" #include <glib.h> #include <pango/pangocairo.h> @@ -43,6 +44,7 @@ IconTexture::IconTexture (const char *icon_name, unsigned int size) IconTexture::~IconTexture () { g_free (_icon_name); + _texture_cached->UnReference (); } void @@ -90,9 +92,21 @@ IconTexture::LoadIcon () } void +IconTexture::CreateTextureCallback (const char *texid, int width, int height, nux::BaseTexture **texture) +{ + nux::BaseTexture *texture2D = nux::CreateTexture2DFromPixbuf (_pixbuf_cached, true); + *texture = texture2D; +} + +void IconTexture::Refresh (GdkPixbuf *pixbuf) { - nux::BaseTexture *texture2D = nux::CreateTexture2DFromPixbuf (pixbuf, true); + // try and get a texture from the texture cache + char *id = g_strdup_printf ("IconTexture.%s", _icon_name); + _pixbuf_cached = pixbuf; + TextureCache *cache = TextureCache::GetDefault (); + nux::BaseTexture * texture2D = cache->FindTexture (id, _size, _size, + sigc::mem_fun (this, &IconTexture::CreateTextureCallback)); nux::TexCoordXForm texxform; texxform.SetTexCoordType (nux::TexCoordXForm::OFFSET_SCALE_COORD); @@ -111,7 +125,9 @@ IconTexture::Refresh (GdkPixbuf *pixbuf) true, rop); SetPaintLayer(texture_layer); - texture2D->UnReference (); + + texture2D->Reference (); + _texture_cached = texture2D; SetMinMaxSize (gdk_pixbuf_get_width (pixbuf) * (_size/(float)gdk_pixbuf_get_height (pixbuf)), _size); diff --git a/src/IconTexture.h b/src/IconTexture.h index 55af0a423..0365760c3 100644 --- a/src/IconTexture.h +++ b/src/IconTexture.h @@ -41,12 +41,16 @@ protected: void AddProperties (GVariantBuilder *builder); private: + void CreateTextureCallback (const char *texid, int width, int height, nux::BaseTexture **texture); void LoadIcon (); void Refresh (GdkPixbuf *pixbuf); void IconLoaded (const char *icon_name, guint size, GdkPixbuf *pixbuf); char *_icon_name; unsigned int _size; + + GdkPixbuf *_pixbuf_cached; // not guarunteed outside of a IconLoader callback + nux::BaseTexture *_texture_cached; }; #endif // ICON_TEXTURE_H diff --git a/src/Launcher.cpp b/src/Launcher.cpp index be507d11b..a7f752f01 100644 --- a/src/Launcher.cpp +++ b/src/Launcher.cpp @@ -190,6 +190,7 @@ Launcher::Launcher (nux::BaseWindow* parent, OnMouseMove.connect (sigc::mem_fun (this, &Launcher::RecvMouseMove)); OnMouseWheel.connect (sigc::mem_fun (this, &Launcher::RecvMouseWheel)); OnKeyPressed.connect (sigc::mem_fun (this, &Launcher::RecvKeyPressed)); + OnEndFocus.connect (sigc::mem_fun (this, &Launcher::exitKeyNavMode)); QuicklistManager::Default ()->quicklist_opened.connect (sigc::mem_fun(this, &Launcher::RecvQuicklistOpened)); QuicklistManager::Default ()->quicklist_closed.connect (sigc::mem_fun(this, &Launcher::RecvQuicklistClosed)); @@ -252,6 +253,7 @@ Launcher::Launcher (nux::BaseWindow* parent, _launcher_action_state = ACTION_NONE; _launch_animation = LAUNCH_ANIMATION_NONE; _urgent_animation = URGENT_ANIMATION_NONE; + _autohide_animation = FADE_SLIDE; _hidemode = LAUNCHER_HIDE_NEVER; _icon_under_mouse = NULL; _icon_mouse_down = NULL; @@ -287,13 +289,13 @@ Launcher::Launcher (nux::BaseWindow* parent, _floating = false; _hovered = false; _hidden = false; - _was_hidden = false; _mouse_inside_launcher = false; _mouse_inside_trigger = false; - _key_show_launcher = false; + _mouseover_launcher_locked = false; + _super_show_launcher = false; + _navmod_show_launcher = false; _placeview_show_launcher = false; _window_over_launcher = false; - _hide_on_action_done = false; _hide_on_drag_hover = false; _render_drag_window = false; _dnd_window_is_mapped = false; @@ -301,6 +303,9 @@ Launcher::Launcher (nux::BaseWindow* parent, _last_button_press = 0; _selection_atom = 0; + // set them to 1 instead of 0 to avoid :0 in case something is racy + _trigger_width = 1; + _trigger_height = 1; // 0 out timers to avoid wonky startups int i; @@ -346,12 +351,9 @@ Launcher::GetName () void Launcher::startKeyNavMode () { - if (_hidden) - { - _was_hidden = true; - _hidden = false; - EnsureHiddenState (); - } + + _navmod_show_launcher = true; + EnsureHiddenState (); if (_last_icon_index == -1) _current_icon_index = 0; @@ -363,12 +365,11 @@ Launcher::startKeyNavMode () void Launcher::exitKeyNavMode () { - if (_was_hidden) - { - _hidden = true; - _was_hidden = false; - EnsureHiddenState (); - } + if (!_navmod_show_launcher) + return; + + _navmod_show_launcher = false; + EnsureHiddenState (); _last_icon_index = _current_icon_index; _current_icon_index = -1; @@ -435,13 +436,43 @@ float Launcher::DnDStartProgress (struct timespec const ¤t) float Launcher::AutohideProgress (struct timespec const ¤t) { - if (_hidemode == LAUNCHER_HIDE_NEVER) - return 0.0f; - - if (_hidden) - return CLAMP ((float) (TimeDelta (¤t, &_times[TIME_AUTOHIDE])) / (float) ANIM_DURATION_SHORT, 0.0f, 1.0f); + + // bfb position progress + if (_mouse_inside_trigger) + { + /* + * most of the mouse movement should be done by the inferior part + * of the launcher, so prioritize this one + */ + + if(_mouseover_launcher_locked || ((_trigger_mouse_position.x == 0) && (_trigger_mouse_position.y == 0))) + return 0.0f; + + float _max_size_on_position; + float position_on_border = _trigger_mouse_position.x * _trigger_height / _trigger_mouse_position.y; + + if (position_on_border < _trigger_width) + _max_size_on_position = pow(pow(position_on_border, 2) + pow(_trigger_height, 2), 0.5); + else + { + position_on_border = _trigger_mouse_position.y * _trigger_width / _trigger_mouse_position.x; + _max_size_on_position = pow(pow(position_on_border, 2) + pow(_trigger_width, 2), 0.5); + } + // only triggered on _hidden = false, no need for check + return CLAMP (pow(pow(_trigger_mouse_position.x, 2) + pow(_trigger_mouse_position.y, 2), 0.5) / _max_size_on_position, 0.0f, 1.0f); + } + + // time-based progress else - return 1.0f - CLAMP ((float) (TimeDelta (¤t, &_times[TIME_AUTOHIDE])) / (float) ANIM_DURATION_SHORT, 0.0f, 1.0f); + { + float animation_progress; + animation_progress = CLAMP ((float) (TimeDelta (¤t, &_times[TIME_AUTOHIDE])) / (float) ANIM_DURATION_SHORT, 0.0f, 1.0f); + if (_hidden) + return animation_progress; + else + return 1.0f - animation_progress; + } + } float Launcher::DragHideProgress (struct timespec const ¤t) @@ -533,7 +564,7 @@ bool Launcher::AnimationInProgress () // hover out animation if (TimeDelta (¤t, &_times[TIME_LEAVE]) < ANIM_DURATION) return true; - + // drag start animation if (TimeDelta (¤t, &_times[TIME_DRAG_START]) < ANIM_DURATION) return true; @@ -542,9 +573,11 @@ bool Launcher::AnimationInProgress () if (TimeDelta (¤t, &_times[TIME_DRAG_END]) < ANIM_DURATION_LONG) return true; - // hide animation + // hide animation (time or position) if (TimeDelta (¤t, &_times[TIME_AUTOHIDE]) < ANIM_DURATION_SHORT) return true; + if (_mouse_inside_trigger && !_mouseover_launcher_locked) + return true; // collapse animation on DND out of launcher space if (TimeDelta (¤t, &_times[TIME_DRAG_THRESHOLD]) < ANIM_DURATION_SHORT) @@ -938,7 +971,7 @@ float Launcher::DragLimiter (float x) } void Launcher::RenderArgs (std::list<Launcher::RenderArg> &launcher_args, - nux::Geometry &box_geo) + nux::Geometry &box_geo, float *launcher_alpha) { nux::Geometry geo = GetGeometry (); LauncherModel::iterator it; @@ -1019,11 +1052,37 @@ void Launcher::RenderArgs (std::list<Launcher::RenderArg> &launcher_args, _launcher_drag_delta = 0; } - float autohide_progress = AutohideProgress (current); float autohide_offset = 0.0f; - if (_hidemode != LAUNCHER_HIDE_NEVER && autohide_progress > 0.0f) + *launcher_alpha = 1.0f; + if (_hidemode != LAUNCHER_HIDE_NEVER) { - autohide_offset -= geo.width * autohide_progress; + float autohide_progress = AutohideProgress (current); + + if (_autohide_animation == FADE_ONLY + || (_autohide_animation == FADE_SLIDE && _mouse_inside_trigger)) + { + if (autohide_progress > 0.0f) + { + if (_mouse_inside_trigger) + { + if (!_mouseover_launcher_locked) + *launcher_alpha = 1.0f - (autohide_progress / 1.5f); + } + else + *launcher_alpha = 1.0f - autohide_progress; + } + } + else + { + if (autohide_progress > 0.0f) + autohide_offset -= geo.width * autohide_progress; + } + /* _mouse_inside_trigger is particular because we don't change _hidden state + * as we can go back and for. We have to lock the launcher manually changing + * the _hidden state then + */ + if (autohide_progress == 0.0f && _mouse_inside_trigger && !_mouseover_launcher_locked) + ForceHiddenState (false); // lock the launcher } float drag_hide_progress = DragHideProgress (current); @@ -1094,17 +1153,14 @@ void Launcher::RenderArgs (std::list<Launcher::RenderArg> &launcher_args, void Launcher::StartKeyShowLauncher () { - _key_show_launcher = true; + _super_show_launcher = true; EnsureHiddenState (); } void Launcher::EndKeyShowLauncher () { - _key_show_launcher = false; - if (_hide_on_action_done) - EnsureHiddenState (); - else - SetupAutohideTimer (); + _super_show_launcher = false; + SetupAutohideTimer (); } void Launcher::OnPlaceViewShown (GVariant *data, void *val) @@ -1126,13 +1182,16 @@ void Launcher::OnTriggerUpdate (GVariant *data, gpointer user_data) gchar *prop_key; GVariant *prop_value; GVariantIter *prop_iter; - int x, y; + int x, y, trigger_width, trigger_height; Launcher *self = (Launcher*)user_data; - g_variant_get (data, "(iia{sv})", &x, &y, &prop_iter); + g_variant_get (data, "(iiiia{sv})", &x, &y, &trigger_width, &trigger_height, &prop_iter); self->_trigger_mouse_position = nux::Point2 (x, y); + self->_trigger_width = trigger_width; + self->_trigger_height = trigger_height; + g_return_if_fail (prop_iter != NULL); while (g_variant_iter_loop (prop_iter, "{sv}", &prop_key, &prop_value)) @@ -1140,20 +1199,11 @@ void Launcher::OnTriggerUpdate (GVariant *data, gpointer user_data) if (g_str_equal ("hovered", prop_key)) { self->_mouse_inside_trigger = g_variant_get_boolean (prop_value); - if (self->_mouse_inside_trigger) - { self->_hide_on_drag_hover = false; - self->EnsureHiddenState (); - self->EnsureHoverState (); - self->EnsureScrollTimer (); - } - else - { - self->SetupAutohideTimer (); - self->EnsureHoverState (); - self->EnsureScrollTimer (); - } + self->EnsureHiddenState (); + self->EnsureHoverState (); + self->EnsureScrollTimer (); } } } @@ -1161,19 +1211,33 @@ void Launcher::OnTriggerUpdate (GVariant *data, gpointer user_data) void Launcher::OnActionDone (GVariant *data, void *val) { Launcher *self = (Launcher*)val; - self->_hide_on_action_done = true; + self->_mouseover_launcher_locked = false; self->SetupAutohideTimer (); } +void Launcher::ForceHiddenState (bool hidden) +{ + // force hidden state skipping the animation + SetHidden (hidden); + _times[TIME_AUTOHIDE].tv_sec = 0; + _times[TIME_AUTOHIDE].tv_nsec = 0; +} + void Launcher::SetHidden (bool hidden) { if (hidden == _hidden) return; + // auto lock/unlock the launcher depending on the state switch + if (hidden) + _mouseover_launcher_locked = false; + else + _mouseover_launcher_locked = true; + _hidden = hidden; SetTimeStruct (&_times[TIME_AUTOHIDE], &_times[TIME_AUTOHIDE], ANIM_DURATION_SHORT); - _parent->EnableInputWindow(!hidden); + _parent->EnableInputWindow(!hidden, "launcher"); if (!hidden && _launcher_action_state == ACTION_DRAG_EXTERNAL) ProcessDndLeave (); @@ -1194,17 +1258,19 @@ void Launcher::EnsureHiddenState () { // compiler should optimize this, we do this for readability - bool mouse_over_launcher = _mouse_inside_trigger || (_mouse_inside_launcher && !_hide_on_action_done); + bool mouse_over_launcher = _mouseover_launcher_locked && (_mouse_inside_trigger || _mouse_inside_launcher); - bool required_for_external_purpose = _key_show_launcher || _placeview_show_launcher || + bool required_for_external_purpose = _super_show_launcher || _placeview_show_launcher || _navmod_show_launcher || QuicklistManager::Default ()->Current() || PluginAdapter::Default ()->IsScaleActive (); bool in_must_be_open_mode = _launcher_action_state != ACTION_NONE || _dnd_window_is_mapped; bool must_be_hidden = _hide_on_drag_hover && _hidemode != LAUNCHER_HIDE_NEVER; + bool autohide_handle_hold = _autohide_handle && !_hidden; + if (must_be_hidden || (!mouse_over_launcher && !required_for_external_purpose && - !in_must_be_open_mode && _window_over_launcher && !_autohide_handle)) + !in_must_be_open_mode && _window_over_launcher && !autohide_handle_hold)) SetHidden (true); else SetHidden (false); @@ -1286,8 +1352,6 @@ Launcher::OnWindowMapped (guint32 xid) { g_timeout_add (200, &Launcher::OnUpdateDragManagerTimeout, this); } - - EnsureHiddenState (); } void @@ -1298,7 +1362,6 @@ Launcher::OnWindowUnmapped (guint32 xid) { g_timeout_add (200, &Launcher::OnUpdateDragManagerTimeout, this); } - EnsureHiddenState (); } void @@ -1312,7 +1375,9 @@ Launcher::OnWindowMaybeIntellihide (guint32 xid) EnsureHiddenState (); } else + { CheckWindowOverLauncher (); + } } } @@ -1354,7 +1419,7 @@ void Launcher::SetHideMode (LauncherHideMode hidemode) } else { - _parent->EnableInputWindow(true); + _parent->EnableInputWindow(true, "launcher"); g_timeout_add (1000, &Launcher::StrutHack, this); _parent->InputWindowEnableStruts(true); } @@ -1363,6 +1428,19 @@ void Launcher::SetHideMode (LauncherHideMode hidemode) EnsureAnimation (); } +Launcher::AutoHideAnimation Launcher::GetAutoHideAnimation () +{ + return _autohide_animation; +} + +void Launcher::SetAutoHideAnimation (AutoHideAnimation animation) +{ + if (_autohide_animation == animation) + return; + + _autohide_animation = animation; +} + void Launcher::SetFloating (bool floating) { if (_floating == floating) @@ -1967,6 +2045,7 @@ void Launcher::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) std::list<Launcher::RenderArg> args; std::list<Launcher::RenderArg>::reverse_iterator rev_it; std::list<Launcher::RenderArg>::iterator it; + float launcher_alpha = 1.0f; // rely on the compiz event loop to come back to us in a nice throttling if (AnimationInProgress ()) @@ -1977,7 +2056,7 @@ void Launcher::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) ROP.SrcBlend = GL_ONE; ROP.DstBlend = GL_ONE_MINUS_SRC_ALPHA; - RenderArgs (args, bkg_box); + RenderArgs (args, bkg_box, &launcher_alpha); if (_drag_icon && _render_drag_window) { @@ -2032,6 +2111,13 @@ void Launcher::DrawContent(nux::GraphicsEngine& GfxContext, bool force_draw) gPainter.Paint2DQuadColor (GfxContext, nux::Geometry (bkg_box.x + bkg_box.width - 1, bkg_box.y, 1, bkg_box.height), nux::Color(0x60606060)); + // FIXME: can be removed for a bgk_box->SetAlpha once implemented + GfxContext.GetRenderStates ().SetPremultipliedBlend (nux::DST_IN); + nux::Color alpha_mask = nux::Color(0xAAAAAAAA); + alpha_mask.SetRGBA (alpha_mask.R () * launcher_alpha, alpha_mask.G () * launcher_alpha, + alpha_mask.B () * launcher_alpha, launcher_alpha); + gPainter.Paint2DQuadColor (GfxContext, bkg_box, alpha_mask); + GfxContext.GetRenderStates().SetColorMask (true, true, true, true); GfxContext.GetRenderStates ().SetBlend (false); @@ -2087,6 +2173,9 @@ void Launcher::StartIconDrag (LauncherIcon *icon) _drag_window->UnReference (); _drag_window = NULL; } + + if (_navmod_show_launcher) + exitKeyNavMode (); _offscreen_drag_texture = nux::GetThreadGLDeviceFactory()->CreateSystemCapableDeviceTexture (_icon_size, _icon_size, 1, nux::BITFMT_R8G8B8A8); _drag_window = new LauncherDragWindow (_offscreen_drag_texture); @@ -2236,10 +2325,19 @@ void Launcher::RecvMouseLeave(int x, int y, unsigned long button_flags, unsigned { SetMousePosition (x, y); _mouse_inside_launcher = false; - + if (_launcher_action_state == ACTION_NONE) EnsureHoverState (); + // exit immediatly on action and mouse leaving the launcher + if (!_mouseover_launcher_locked) + { + if (_autohide_handle > 0) + g_source_remove (_autohide_handle); + _autohide_handle = 0; + EnsureHiddenState (); + } + EventLogic (); EnsureAnimation (); } @@ -2337,8 +2435,21 @@ Launcher::RecvKeyPressed (unsigned int key_sym, exitKeyNavMode (); break; - // <RETURN>/<SPACE> (start/activate currently selected icon) + // <SPACE> (open a new instance) case XK_space: + { + LauncherModel::iterator it; + int i; + + // start currently selected icon + for (it = _model->begin (), i = 0; it != _model->end (); it++, i++) + if (i == _current_icon_index) + (*it)->OpenInstance (); + } + exitKeyNavMode (); + break; + + // <RETURN> (start/activate currently selected icon) case XK_Return: { LauncherModel::iterator it; @@ -2396,8 +2507,9 @@ void Launcher::EventLogic () launcher_icon->MouseEnter.emit (); launcher_icon->_mouse_inside = true; _icon_under_mouse = launcher_icon; - // reset trigger has the mouse moved to another item - _hide_on_action_done = false; + // reset trigger has the mouse moved to another item (only if the launcher is supposed to be seen) + if (!_hidden) + _mouseover_launcher_locked = true; } } @@ -2919,10 +3031,17 @@ Launcher::ProcessDndLeave () _dnd_hovered_icon->SetQuirk (LauncherIcon::QUIRK_VISIBLE, false); _dnd_hovered_icon->remove.emit (_dnd_hovered_icon); - _steal_drag = false; + } + + if (!_steal_drag && _dnd_hovered_icon) + { + _dnd_hovered_icon->SendDndLeave (); _dnd_hovered_icon = 0; } + _steal_drag = false; + _dnd_hovered_icon = 0; + EnsureHoverState (); } @@ -2955,6 +3074,7 @@ Launcher::ProcessDndMove (int x, int y, std::list<char *> mimes) std::list<char *>::iterator it; nux::Area *parent = GetToplevel (); char *remote_desktop_path = NULL; + char *uri_list_const = g_strdup ("text/uri-list"); if (!_data_checked) { @@ -2963,10 +3083,10 @@ Launcher::ProcessDndMove (int x, int y, std::list<char *> mimes) // get the data for (it = mimes.begin (); it != mimes.end (); it++) { - if (!g_str_equal (*it, "text/uri-list")) + if (!g_str_equal (*it, uri_list_const)) continue; - _drag_data = StringToUriList (nux::GetWindow ().GetDndData ("text/uri-list")); + _drag_data = StringToUriList (nux::GetWindow ().GetDndData (uri_list_const)); break; } @@ -2982,6 +3102,8 @@ Launcher::ProcessDndMove (int x, int y, std::list<char *> mimes) } } + g_free (uri_list_const); + SetMousePosition (x - parent->GetGeometry ().x, y - parent->GetGeometry ().y); if (_mouse_position.x == 0 && !_drag_edge_touching) @@ -3040,12 +3162,20 @@ Launcher::ProcessDndMove (int x, int y, std::list<char *> mimes) if (hovered_icon != _dnd_hovered_icon) { if (hovered_icon) + { + hovered_icon->SendDndEnter (); _drag_action = hovered_icon->QueryAcceptDrop (_drag_data); + } else + { _drag_action = nux::DNDACTION_NONE; + } + + if (_dnd_hovered_icon) + _dnd_hovered_icon->SendDndLeave (); + + _dnd_hovered_icon = hovered_icon; } - - _dnd_hovered_icon = hovered_icon; } bool accept; diff --git a/src/Launcher.h b/src/Launcher.h index d78b34968..447c72991 100644 --- a/src/Launcher.h +++ b/src/Launcher.h @@ -68,6 +68,13 @@ public: URGENT_ANIMATION_PULSE, URGENT_ANIMATION_WIGGLE, } UrgentAnimation; + + typedef enum + { + FADE_SLIDE, + SLIDE_ONLY, + FADE_ONLY, + } AutoHideAnimation; typedef enum { @@ -98,7 +105,7 @@ public: void SetHideMode (LauncherHideMode hidemode); LauncherHideMode GetHideMode (); - + void StartKeyShowLauncher (); void EndKeyShowLauncher (); @@ -111,6 +118,9 @@ public: void SetUrgentAnimation (UrgentAnimation animation); UrgentAnimation GetUrgentAnimation (); + void SetAutoHideAnimation (AutoHideAnimation animation); + AutoHideAnimation GetAutoHideAnimation (); + nux::BaseWindow* GetParent () { return _parent; }; static void SetTimeStruct (struct timespec *timer, struct timespec *sister = 0, int sister_relation = 0); @@ -224,27 +234,28 @@ private: void CheckWindowOverLauncher (); bool CheckIntersectWindow (CompWindow *window); - float DnDStartProgress (struct timespec const ¤t); - float DnDExitProgress (struct timespec const ¤t); - float GetHoverProgress (struct timespec const ¤t); - float AutohideProgress (struct timespec const ¤t); - float DragThresholdProgress (struct timespec const ¤t); - float DragHideProgress (struct timespec const ¤t); - float IconPresentProgress (LauncherIcon *icon, struct timespec const ¤t); - float IconUrgentProgress (LauncherIcon *icon, struct timespec const ¤t); - float IconShimmerProgress (LauncherIcon *icon, struct timespec const ¤t); - float IconUrgentPulseValue (LauncherIcon *icon, struct timespec const ¤t); - float IconUrgentWiggleValue (LauncherIcon *icon, struct timespec const ¤t); - float IconStartingBlinkValue (LauncherIcon *icon, struct timespec const ¤t); - float IconStartingPulseValue (LauncherIcon *icon, struct timespec const ¤t); - float IconBackgroundIntensity (LauncherIcon *icon, struct timespec const ¤t); - float IconProgressBias (LauncherIcon *icon, struct timespec const ¤t); - float IconDropDimValue (LauncherIcon *icon, struct timespec const ¤t); + float DnDStartProgress (struct timespec const ¤t); + float DnDExitProgress (struct timespec const ¤t); + float GetHoverProgress (struct timespec const ¤t); + float AutohideProgress (struct timespec const ¤t); + float DragThresholdProgress (struct timespec const ¤t); + float DragHideProgress (struct timespec const ¤t); + float IconPresentProgress (LauncherIcon *icon, struct timespec const ¤t); + float IconUrgentProgress (LauncherIcon *icon, struct timespec const ¤t); + float IconShimmerProgress (LauncherIcon *icon, struct timespec const ¤t); + float IconUrgentPulseValue (LauncherIcon *icon, struct timespec const ¤t); + float IconUrgentWiggleValue (LauncherIcon *icon, struct timespec const ¤t); + float IconStartingBlinkValue (LauncherIcon *icon, struct timespec const ¤t); + float IconStartingPulseValue (LauncherIcon *icon, struct timespec const ¤t); + float IconBackgroundIntensity (LauncherIcon *icon, struct timespec const ¤t); + float IconProgressBias (LauncherIcon *icon, struct timespec const ¤t); + float IconDropDimValue (LauncherIcon *icon, struct timespec const ¤t); float IconCenterTransitionProgress (LauncherIcon *icon, struct timespec const ¤t); - void SetHover (); - void UnsetHover (); - void SetHidden (bool hidden); + void SetHover (); + void UnsetHover (); + void ForceHiddenState (bool hidden); + void SetHidden (bool hidden); void SetDndDelta (float x, float y, nux::Geometry geo, struct timespec const ¤t); float DragLimiter (float x); @@ -262,7 +273,7 @@ private: struct timespec const ¤t); void RenderArgs (std::list<Launcher::RenderArg> &launcher_args, - nux::Geometry &box_geo); + nux::Geometry &box_geo, float *launcher_alpha); void DrawRenderArg (nux::GraphicsEngine& GfxContext, RenderArg const &arg, nux::Geometry geo); @@ -342,13 +353,13 @@ private: bool _hovered; bool _floating; bool _hidden; - bool _was_hidden; bool _mouse_inside_launcher; bool _mouse_inside_trigger; - bool _key_show_launcher; + bool _mouseover_launcher_locked; + bool _super_show_launcher; + bool _navmod_show_launcher; bool _placeview_show_launcher; bool _window_over_launcher; - bool _hide_on_action_done; bool _hide_on_drag_hover; bool _render_drag_window; @@ -365,6 +376,7 @@ private: LauncherActionState _launcher_action_state; LaunchAnimation _launch_animation; UrgentAnimation _urgent_animation; + AutoHideAnimation _autohide_animation; LauncherIcon* _icon_under_mouse; LauncherIcon* _icon_mouse_down; @@ -381,6 +393,9 @@ private: int _dnd_security; int _enter_y; int _last_button_press; + + int _trigger_width; + int _trigger_height; nux::BaseTexture* _icon_bkg_texture; nux::BaseTexture* _icon_shine_texture; diff --git a/src/LauncherController.cpp b/src/LauncherController.cpp index 3320c16d4..670083697 100644 --- a/src/LauncherController.cpp +++ b/src/LauncherController.cpp @@ -47,7 +47,11 @@ LauncherController::LauncherController(Launcher* launcher, CompScreen *screen, n _device_section = new DeviceLauncherSection (_launcher); _device_section->IconAdded.connect (sigc::mem_fun (this, &LauncherController::OnIconAdded)); - InsertExpoAction (); + _num_workspaces = _screen->vpSize ().width (); + if(_num_workspaces > 1) + { + InsertExpoAction (); + } InsertTrash (); g_timeout_add (500, (GSourceFunc) &LauncherController::BamfTimerCallback, this); @@ -160,20 +164,40 @@ LauncherController::InsertTrash () } void +LauncherController::UpdateNumWorkspaces (int workspaces) +{ + if ((_num_workspaces == 0) && (workspaces > 0)) + { + InsertExpoAction (); + } + else if((_num_workspaces > 0) && (workspaces == 0)) + { + RemoveExpoAction (); + } + + _num_workspaces = workspaces; +} + +void LauncherController::InsertExpoAction () { - SimpleLauncherIcon *expoIcon; - expoIcon = new SimpleLauncherIcon (_launcher); + _expoIcon = new SimpleLauncherIcon (_launcher); - expoIcon->SetTooltipText (_("Workspace Switcher")); - expoIcon->SetIconName ("workspace-switcher"); - expoIcon->SetQuirk (LauncherIcon::QUIRK_VISIBLE, true); - expoIcon->SetQuirk (LauncherIcon::QUIRK_RUNNING, false); - expoIcon->SetIconType (LauncherIcon::TYPE_EXPO); + _expoIcon->SetTooltipText (_("Workspace Switcher")); + _expoIcon->SetIconName ("workspace-switcher"); + _expoIcon->SetQuirk (LauncherIcon::QUIRK_VISIBLE, true); + _expoIcon->SetQuirk (LauncherIcon::QUIRK_RUNNING, false); + _expoIcon->SetIconType (LauncherIcon::TYPE_EXPO); - expoIcon->MouseClick.connect (sigc::mem_fun (this, &LauncherController::OnExpoClicked)); + _expoIcon->MouseClick.connect (sigc::mem_fun (this, &LauncherController::OnExpoClicked)); - RegisterIcon (expoIcon); + RegisterIcon (_expoIcon); +} + +void +LauncherController::RemoveExpoAction () +{ + _model->RemoveIcon (_expoIcon); } void diff --git a/src/LauncherController.h b/src/LauncherController.h index 42ac88707..73da08de6 100644 --- a/src/LauncherController.h +++ b/src/LauncherController.h @@ -49,6 +49,7 @@ public: LauncherController(Launcher* launcher, CompScreen *screen, nux::BaseWindow* window); ~LauncherController(); + void UpdateNumWorkspaces (int workspaces); private: BamfMatcher* _matcher; CompAction* _expo_action; @@ -61,6 +62,8 @@ private: PlaceLauncherSection* _place_section; DeviceLauncherSection* _device_section; LauncherEntryRemoteModel* _remote_model; + SimpleLauncherIcon* _expoIcon; + int _num_workspaces; void SortAndSave (); @@ -72,6 +75,7 @@ private: void OnLauncerEntryRemoteRemoved (LauncherEntryRemote *entry); void InsertExpoAction (); + void RemoveExpoAction (); void InsertTrash (); diff --git a/src/LauncherEntryRemoteModel.cpp b/src/LauncherEntryRemoteModel.cpp index 162892541..c82cf38ec 100644 --- a/src/LauncherEntryRemoteModel.cpp +++ b/src/LauncherEntryRemoteModel.cpp @@ -19,14 +19,6 @@ #include "LauncherEntryRemoteModel.h" -static void on_launcher_entry_signal_received (GDBusConnection *connection, - const gchar *sender_name, - const gchar *object_path, - const gchar *interface_name, - const gchar *signal_name, - GVariant *parameters, - gpointer user_data); - static void nux_object_destroy_notify (nux::Object *obj); /** @@ -68,7 +60,19 @@ LauncherEntryRemoteModel::LauncherEntryRemoteModel() NULL, // path NULL, // arg0 G_DBUS_SIGNAL_FLAGS_NONE, - on_launcher_entry_signal_received, + &on_launcher_entry_signal_received, + this, + NULL); + + _dbus_name_owner_changed_signal_id = + g_dbus_connection_signal_subscribe (_conn, + "org.freedesktop.DBus", // sender + "org.freedesktop.DBus", // interface + "NameOwnerChanged", // member + "/org/freedesktop/DBus", // path + NULL, // arg0 + G_DBUS_SIGNAL_FLAGS_NONE, + &on_dbus_name_owner_changed_signal_received, this, NULL); } @@ -228,14 +232,11 @@ LauncherEntryRemoteModel::RemoveEntry (LauncherEntryRemote *entry) { g_return_if_fail (entry != NULL); - /* We need a temp ref on entry to keep it alive during signal emission */ - entry->SinkReference (); + entry->Reference (); if (g_hash_table_remove (_entries_by_uri, entry->AppUri ())) - { - entry_removed.emit (entry); - } - + entry_removed.emit (entry); + entry->UnReference (); } @@ -289,8 +290,8 @@ LauncherEntryRemoteModel::HandleUpdateRequest (const gchar *sender_name, g_free (app_uri); } -static void -on_launcher_entry_signal_received (GDBusConnection *connection, +void +LauncherEntryRemoteModel::on_launcher_entry_signal_received (GDBusConnection *connection, const gchar *sender_name, const gchar *object_path, const gchar *interface_name, @@ -318,8 +319,48 @@ on_launcher_entry_signal_received (GDBusConnection *connection, g_warning ("Unknown signal '%s.%s' from %s", interface_name, signal_name, sender_name); } +} - +void +LauncherEntryRemoteModel::on_dbus_name_owner_changed_signal_received (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) +{ + LauncherEntryRemoteModel *self; + char *name, *before, *after; + + self = static_cast<LauncherEntryRemoteModel *> (user_data); + + if (parameters == NULL) + return; + + g_variant_get (parameters, "(sss)", &name, &before, &after); + + if (!after[0]) + { + // Name gone, find and destroy LauncherEntryRemote + GHashTableIter iter; + GList *remove = NULL, *l; + gpointer key, value; + + g_hash_table_iter_init (&iter, self->_entries_by_uri); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + /* do something with key and value */ + LauncherEntryRemote *entry = static_cast<LauncherEntryRemote *> (value); + if (g_str_equal (entry->DBusName (), name)) + remove = g_list_prepend (remove, entry); + } + + for (l = remove; l; l = l->next) + self->RemoveEntry (static_cast<LauncherEntryRemote *> (l->data)); + + g_list_free (remove); + } } static void diff --git a/src/LauncherEntryRemoteModel.h b/src/LauncherEntryRemoteModel.h index ed5b8dd39..b050f0025 100644 --- a/src/LauncherEntryRemoteModel.h +++ b/src/LauncherEntryRemoteModel.h @@ -49,9 +49,26 @@ public: private: LauncherEntryRemoteModel(); ~LauncherEntryRemoteModel(); + + static void on_launcher_entry_signal_received (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data); + + static void on_dbus_name_owner_changed_signal_received (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data); GDBusConnection *_conn; guint _launcher_entry_dbus_signal_id; + guint _dbus_name_owner_changed_signal_id; GHashTable *_entries_by_uri; }; diff --git a/src/LauncherIcon.cpp b/src/LauncherIcon.cpp index 12f344604..c5e11651a 100644 --- a/src/LauncherIcon.cpp +++ b/src/LauncherIcon.cpp @@ -29,6 +29,7 @@ #include "Nux/MenuPage.h" #include "NuxCore/Color.h" +#include "LauncherEntryRemoteModel.h" #include "LauncherIcon.h" #include "Launcher.h" @@ -139,6 +140,13 @@ LauncherIcon::AddProperties (GVariantBuilder *builder) void LauncherIcon::Activate () { + ActivateLauncherIcon (); +} + +void +LauncherIcon::OpenInstance () +{ + OpenInstanceLauncherIcon (); } nux::Color LauncherIcon::BackgroundColor () @@ -771,7 +779,7 @@ LauncherIcon::InsertEntryRemote (LauncherEntryRemote *remote) { if (std::find (_entry_list.begin (), _entry_list.end (), remote) != _entry_list.end ()) return; - + _entry_list.push_front (remote); remote->emblem_changed.connect (sigc::mem_fun(this, &LauncherIcon::OnRemoteEmblemChanged)); @@ -783,6 +791,7 @@ LauncherIcon::InsertEntryRemote (LauncherEntryRemote *remote) remote->count_visible_changed.connect (sigc::mem_fun(this, &LauncherIcon::OnRemoteCountVisibleChanged)); remote->progress_visible_changed.connect (sigc::mem_fun(this, &LauncherIcon::OnRemoteProgressVisibleChanged)); + if (remote->EmblemVisible ()) OnRemoteEmblemVisibleChanged (remote); @@ -798,10 +807,11 @@ LauncherIcon::RemoveEntryRemote (LauncherEntryRemote *remote) { if (std::find (_entry_list.begin (), _entry_list.end (), remote) == _entry_list.end ()) return; - + _entry_list.remove (remote); - printf ("Remove\n"); + DeleteEmblem (); + SetQuirk (QUIRK_PROGRESS, false); } void diff --git a/src/LauncherIcon.h b/src/LauncherIcon.h index 6745714df..752070b4c 100644 --- a/src/LauncherIcon.h +++ b/src/LauncherIcon.h @@ -95,7 +95,8 @@ public: void SetCenter (nux::Point3 center); nux::Point3 GetCenter (); - virtual void Activate (); + void Activate (); + void OpenInstance (); void SaveCenter (); @@ -135,6 +136,8 @@ public: nux::DndAction QueryAcceptDrop (std::list<char *> paths) { return OnQueryAcceptDrop (paths); } void AcceptDrop (std::list<char *> paths) { return OnAcceptDrop (paths); } + void SendDndEnter () { OnDndEnter (); } + void SendDndLeave () { OnDndLeave (); } sigc::signal<void, int> MouseDown; sigc::signal<void, int> MouseUp; @@ -180,6 +183,11 @@ protected: virtual nux::DndAction OnQueryAcceptDrop (std::list<char *> files) { return nux::DNDACTION_NONE; } virtual void OnAcceptDrop (std::list<char *> files) {} + virtual void OnDndEnter () {} + virtual void OnDndLeave () {} + + virtual void ActivateLauncherIcon () {} + virtual void OpenInstanceLauncherIcon () {} nux::BaseTexture * TextureFromGtkTheme (const char *name, int size); nux::BaseTexture * TextureFromPath (const char *name, int size); diff --git a/src/PanelHomeButton.cpp b/src/PanelHomeButton.cpp index 9260b2aec..17ecb0236 100644 --- a/src/PanelHomeButton.cpp +++ b/src/PanelHomeButton.cpp @@ -32,14 +32,17 @@ #include <pango/pangocairo.h> #include <gtk/gtk.h> +#include "PanelStyle.h" + #define PANEL_HEIGHT 24 #define BUTTON_WIDTH 66 +NUX_IMPLEMENT_OBJECT_TYPE (PanelHomeButton); + PanelHomeButton::PanelHomeButton () : TextureArea (NUX_TRACKER_LOCATION), _util_cg (CAIRO_FORMAT_ARGB32, BUTTON_WIDTH, PANEL_HEIGHT) { - _pixbuf = gdk_pixbuf_new_from_file (PKGDATADIR"/bfb.png", NULL); SetMinMaxSize (BUTTON_WIDTH, PANEL_HEIGHT); OnMouseClick.connect (sigc::mem_fun (this, &PanelHomeButton::RecvMouseClick)); @@ -49,12 +52,12 @@ PanelHomeButton::PanelHomeButton () OnMouseLeave.connect (sigc::mem_fun(this, &PanelHomeButton::RecvMouseLeave)); OnMouseMove.connect (sigc::mem_fun(this, &PanelHomeButton::RecvMouseMove)); + PanelStyle::GetDefault ()->changed.connect (sigc::mem_fun (this, &PanelHomeButton::Refresh)); Refresh (); } PanelHomeButton::~PanelHomeButton () { - g_object_unref (_pixbuf); } void @@ -62,14 +65,18 @@ PanelHomeButton::Refresh () { int width = BUTTON_WIDTH; int height = PANEL_HEIGHT; + GdkPixbuf *pixbuf; nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, width, height); cairo_t *cr = cairo_graphics.GetContext(); cairo_set_line_width (cr, 1); - gdk_cairo_set_source_pixbuf (cr, _pixbuf, - (BUTTON_WIDTH-gdk_pixbuf_get_width (_pixbuf))/2, - (PANEL_HEIGHT-gdk_pixbuf_get_height (_pixbuf))/2); + pixbuf = PanelStyle::GetDefault ()->GetHomeButton (); + gdk_cairo_set_source_pixbuf (cr, pixbuf, + (BUTTON_WIDTH-gdk_pixbuf_get_width (pixbuf))/2, + (PANEL_HEIGHT-gdk_pixbuf_get_height (pixbuf))/2); + g_object_unref (pixbuf); + cairo_paint (cr); cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.2f); @@ -100,7 +107,7 @@ PanelHomeButton::Refresh () nux::TextureLayer* texture_layer = new nux::TextureLayer (texture2D->GetDeviceTexture(), texxform, // The Oject that defines the texture wraping and coordinate transformation. nux::Color::White, // The color used to modulate the texture. - false, // Write the alpha value of the texture to the destination buffer. + true, // Write the alpha value of the texture to the destination buffer. rop // Use the given raster operation to set the blending when the layer is being rendered. ); @@ -134,10 +141,12 @@ PanelHomeButton::RecvMouseEnter (int x, int y, unsigned long button_flags, unsig { GVariantBuilder builder; - g_variant_builder_init (&builder, G_VARIANT_TYPE ("(iia{sv})")); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(iiiia{sv})")); g_variant_builder_add (&builder, "i", x); g_variant_builder_add (&builder, "i", y); - + g_variant_builder_add (&builder, "i", BUTTON_WIDTH); + g_variant_builder_add (&builder, "i", PANEL_HEIGHT); + g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{sv}")); g_variant_builder_add (&builder, "{sv}", "hovered", g_variant_new_boolean (true)); g_variant_builder_close (&builder); @@ -152,9 +161,11 @@ PanelHomeButton::RecvMouseLeave (int x, int y, unsigned long button_flags, unsig { GVariantBuilder builder; - g_variant_builder_init (&builder, G_VARIANT_TYPE ("(iia{sv})")); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(iiiia{sv})")); g_variant_builder_add (&builder, "i", x); g_variant_builder_add (&builder, "i", y); + g_variant_builder_add (&builder, "i", BUTTON_WIDTH); + g_variant_builder_add (&builder, "i", PANEL_HEIGHT); g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{sv}")); g_variant_builder_add (&builder, "{sv}", "hovered", g_variant_new_boolean (false)); @@ -170,9 +181,11 @@ PanelHomeButton::RecvMouseMove(int x, int y, int dx, int dy, unsigned long butto { GVariantBuilder builder; - g_variant_builder_init (&builder, G_VARIANT_TYPE ("(iia{sv})")); + g_variant_builder_init (&builder, G_VARIANT_TYPE ("(iiiia{sv})")); g_variant_builder_add (&builder, "i", x); g_variant_builder_add (&builder, "i", y); + g_variant_builder_add (&builder, "i", BUTTON_WIDTH); + g_variant_builder_add (&builder, "i", PANEL_HEIGHT); g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{sv}")); g_variant_builder_close (&builder); @@ -197,5 +210,4 @@ PanelHomeButton::AddProperties (GVariantBuilder *builder) g_variant_builder_add (builder, "{sv}", "y", g_variant_new_int32 (geo.y)); g_variant_builder_add (builder, "{sv}", "width", g_variant_new_int32 (geo.width)); g_variant_builder_add (builder, "{sv}", "height", g_variant_new_int32 (geo.height)); - g_variant_builder_add (builder, "{sv}", "have-pixbuf", g_variant_new_boolean (GDK_IS_PIXBUF (_pixbuf))); } diff --git a/src/PanelHomeButton.h b/src/PanelHomeButton.h index f84210aec..ed0044f91 100644 --- a/src/PanelHomeButton.h +++ b/src/PanelHomeButton.h @@ -29,6 +29,7 @@ class PanelHomeButton : public nux::TextureArea, public Introspectable { + NUX_DECLARE_OBJECT_TYPE (PanelHomeButton, nux::TextureArea); public: PanelHomeButton (); ~PanelHomeButton (); @@ -50,7 +51,6 @@ private: private: nux::CairoGraphics _util_cg; - GdkPixbuf *_pixbuf; }; #endif // PANEL_HOME_BUTTON_H diff --git a/src/PanelIndicatorObjectEntryView.cpp b/src/PanelIndicatorObjectEntryView.cpp index e223aa3c3..fe97fc9a9 100644 --- a/src/PanelIndicatorObjectEntryView.cpp +++ b/src/PanelIndicatorObjectEntryView.cpp @@ -26,6 +26,7 @@ #include "Nux/WindowCompositor.h" #include "PanelIndicatorObjectEntryView.h" +#include "PanelStyle.h" #include <glib.h> #include <pango/pangocairo.h> @@ -47,7 +48,8 @@ PanelIndicatorObjectEntryView::PanelIndicatorObjectEntryView (IndicatorObjectEnt InputArea::OnMouseDown.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::OnMouseDown)); InputArea::OnMouseWheel.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::OnMouseWheel)); - + + PanelStyle::GetDefault ()->changed.connect (sigc::mem_fun (this, &PanelIndicatorObjectEntryView::Refresh)); Refresh (); } @@ -141,6 +143,9 @@ PanelIndicatorObjectEntryView::Refresh () int text_width = 0; int text_height = 0; + PanelStyle *style = PanelStyle::GetDefault (); + nux::Color textcol = style->GetTextColor (); + nux::Color textshadowcol = style->GetTextShadow (); // First lets figure out our size if (pixbuf && _proxy->icon_visible) @@ -194,6 +199,11 @@ PanelIndicatorObjectEntryView::Refresh () cr = cairo_graphics.GetContext(); cairo_set_line_width (cr, 1); + cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); + cairo_paint (cr); + + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + if (_proxy->GetActive ()) draw_menu_bg (cr, width, height); @@ -215,13 +225,20 @@ PanelIndicatorObjectEntryView::Refresh () pango_cairo_update_layout (cr, layout); // Once for the homies that couldn't be here - cairo_set_source_rgb (cr, 50/255.0f, 50/255.0f, 45/255.0f); + cairo_set_source_rgba (cr, + textshadowcol.GetRed (), + textshadowcol.GetGreen (), + textshadowcol.GetBlue (), + 1.0f - textshadowcol.GetRed ()); cairo_move_to (cr, x, ((height - text_height)/2)-1); pango_cairo_show_layout (cr, layout); cairo_stroke (cr); // Once again for the homies that could - cairo_set_source_rgba (cr, 223/255.0f, 219/255.0f, 210/255.0f, + cairo_set_source_rgba (cr, + textcol.GetRed (), + textcol.GetGreen (), + textcol.GetBlue (), _proxy->label_sensitive ? 1.0f : 0.0f); cairo_move_to (cr, x, (height - text_height)/2); pango_cairo_show_layout (cr, layout); @@ -244,23 +261,17 @@ PanelIndicatorObjectEntryView::Refresh () texxform.SetWrap (nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT); nux::ROPConfig rop; - rop.Blend = true; // Enable the blending. By default rop.Blend is false. - rop.SrcBlend = GL_ONE; // Set the source blend factor. - rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; // Set the destination blend factor. + rop.Blend = true; + rop.SrcBlend = GL_ONE; + rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; nux::TextureLayer* texture_layer = new nux::TextureLayer (texture2D->GetDeviceTexture(), - texxform, // The Oject that defines the texture wraping and coordinate transformation. - nux::Color::White, // The color used to modulate the texture. - false, // Write the alpha value of the texture to the destination buffer. - rop // Use the given raster operation to set the blending when the layer is being rendered. - ); - + texxform, + nux::Color::White, + true, + rop); SetPaintLayer (texture_layer); - // We don't need the texture anymore. Since it hasn't been reference, it ref count should still be 1. - // UnReference it and it will be destroyed. texture2D->UnReference (); - - // The texture layer has been cloned by this object when calling SetPaintLayer. It is safe to delete it now. delete texture_layer; NeedRedraw (); @@ -281,6 +292,11 @@ draw_menu_bg (cairo_t *cr, int width, int height) /* FIXME */ double mpi = 3.14159265358979323846; + PanelStyle *style = PanelStyle::GetDefault (); + nux::Color bgtop = style->GetBackgroundTop (); + nux::Color bgbot = style->GetBackgroundBottom (); + nux::Color line = style->GetTextShadow (); + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); cairo_set_line_width (cr, 1.0); @@ -294,15 +310,31 @@ draw_menu_bg (cairo_t *cr, int width, int height) cairo_arc (cr, x+xos+radius, y+yos+radius, radius, mpi, mpi*1.5); cairo_pattern_t * pat = cairo_pattern_create_linear (x+xos, y, x+xos, y+height-yos*2+2); - cairo_pattern_add_color_stop_rgba (pat, 0.0, 83/255.0f, 82/255.0f, 78/255.0f, 1.0f); - cairo_pattern_add_color_stop_rgba (pat, 1.0, 66/255.0f, 65/255.0f, 63/255.0f, 1.0f); + cairo_pattern_add_color_stop_rgba (pat, 0.0, + bgtop.GetRed (), + bgtop.GetGreen (), + bgtop.GetBlue (), + 1.0f - bgbot.GetRed ()); + cairo_pattern_add_color_stop_rgba (pat, 1.0, + bgbot.GetRed (), + bgbot.GetGreen (), + bgbot.GetBlue (), + 1.0f - bgtop.GetRed ()); cairo_set_source (cr, pat); cairo_fill_preserve (cr); cairo_pattern_destroy (pat); pat = cairo_pattern_create_linear (x+xos, y, x+xos, y+height-yos*2+2); - cairo_pattern_add_color_stop_rgba (pat, 0.0, 62/255.0f, 61/255.0f, 58/255.0f, 1.0f); - cairo_pattern_add_color_stop_rgba (pat, 1.0, 54/255.0f, 54/255.0f, 52/255.0f, 1.0f); + cairo_pattern_add_color_stop_rgba (pat, 0.0, + line.GetRed (), + line.GetGreen (), + line.GetBlue (), + 1.0f); + cairo_pattern_add_color_stop_rgba (pat, 1.0, + line.GetRed (), + line.GetGreen (), + line.GetBlue (), + 1.0f); cairo_set_source (cr, pat); cairo_stroke (cr); cairo_pattern_destroy (pat); @@ -318,8 +350,16 @@ draw_menu_bg (cairo_t *cr, int width, int height) cairo_arc (cr, x+xos+radius, y+yos+radius, radius, mpi, mpi*1.5); pat = cairo_pattern_create_linear (x+xos, y, x+xos, y+height-yos*2+3); - cairo_pattern_add_color_stop_rgba (pat, 0.0, 92/255.0f, 90/255.0f, 85/255.0f, 1.0f); - cairo_pattern_add_color_stop_rgba (pat, 1.0, 70/255.0f, 69/255.0f, 66/255.0f, 1.0f); + cairo_pattern_add_color_stop_rgba (pat, 0.0, + bgbot.GetRed (), + bgbot.GetGreen (), + bgbot.GetBlue (), + 1.0f); + cairo_pattern_add_color_stop_rgba (pat, 1.0, + bgbot.GetRed (), + bgbot.GetGreen (), + bgbot.GetBlue (), + 1.0f); cairo_set_source (cr, pat); cairo_stroke (cr); cairo_pattern_destroy (pat); diff --git a/src/PanelIndicatorObjectView.cpp b/src/PanelIndicatorObjectView.cpp index 4f642028f..f4a1ef474 100644 --- a/src/PanelIndicatorObjectView.cpp +++ b/src/PanelIndicatorObjectView.cpp @@ -1,4 +1,4 @@ -// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*- + /* * Copyright (C) 2010 Canonical Ltd * @@ -33,6 +33,7 @@ PanelIndicatorObjectView::PanelIndicatorObjectView () : View (NUX_TRACKER_LOCATION), + _layout (NULL), _proxy (NULL), _entries () { @@ -65,7 +66,9 @@ long PanelIndicatorObjectView::ProcessEvent (nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo) { long ret = TraverseInfo; - ret = _layout->ProcessEvent (ievent, ret, ProcessEventInfo); + + if (_layout) + ret = _layout->ProcessEvent (ievent, ret, ProcessEventInfo); return ret; } @@ -79,7 +82,8 @@ void PanelIndicatorObjectView::DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw) { GfxContext.PushClippingRectangle (GetGeometry() ); - _layout->ProcessDraw (GfxContext, force_draw); + if (_layout) + _layout->ProcessDraw (GfxContext, force_draw); GfxContext.PopClippingRectangle(); } diff --git a/src/PanelMenuView.cpp b/src/PanelMenuView.cpp index 92487b9b6..cce86510b 100644 --- a/src/PanelMenuView.cpp +++ b/src/PanelMenuView.cpp @@ -29,6 +29,7 @@ #include "Nux/WindowCompositor.h" #include "PanelMenuView.h" +#include "PanelStyle.h" #include "WindowManager.h" @@ -56,6 +57,7 @@ PanelMenuView::PanelMenuView (int padding) _title_tex (NULL), _is_inside (false), _is_maximized (false), + _is_own_window (false), _last_active_view (NULL) { WindowManager *win_manager; @@ -98,6 +100,8 @@ PanelMenuView::PanelMenuView (int padding) win_manager->window_restored.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowRestored)); win_manager->window_unmapped.connect (sigc::mem_fun (this, &PanelMenuView::OnWindowUnmapped)); + PanelStyle::GetDefault ()->changed.connect (sigc::mem_fun (this, &PanelMenuView::Refresh)); + Refresh (); } @@ -223,14 +227,18 @@ PanelMenuView::Draw (nux::GraphicsEngine& GfxContext, bool force_draw) nux::ColorLayer layer (nux::Color (0x00000000), true, rop); gPainter.PushDrawLayer (GfxContext, GetGeometry (), &layer); - if (_is_maximized) + if (_is_own_window) + { + + } + else if (_is_maximized) { if (!_is_inside && !_last_active_view) gPainter.PushDrawLayer (GfxContext, GetGeometry (), _title_layer); } else { - if (_is_inside || _last_active_view) + if ((_is_inside || _last_active_view) && _entries.size ()) { if (_gradient_texture == NULL) { @@ -273,9 +281,10 @@ PanelMenuView::Draw (nux::GraphicsEngine& GfxContext, bool force_draw) } _gradient_texture->UnlockRect (0); } + guint alpha = 0, src = 0, dest = 0; - GfxContext.GetRenderStates ().SetBlend (true); - GfxContext.GetRenderStates ().SetPremultipliedBlend (nux::SRC_OVER); + GfxContext.GetRenderStates ().GetBlend (alpha, src, dest); + GfxContext.GetRenderStates ().SetBlend (true, GL_ONE, GL_ONE_MINUS_SRC_ALPHA); nux::TexCoordXForm texxform0; nux::TexCoordXForm texxform1; @@ -289,8 +298,7 @@ PanelMenuView::Draw (nux::GraphicsEngine& GfxContext, bool force_draw) texxform1, nux::Color::White); - GfxContext.GetRenderStates ().SetBlend(false); - + GfxContext.GetRenderStates ().SetBlend (alpha, src, dest); // The previous blend is too aggressive on the texture and therefore there // is a slight loss of clarity. This fixes that geo.width = button_width * (factor - 1); @@ -317,14 +325,17 @@ PanelMenuView::DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw) GfxContext.PushClippingRectangle (geo); - if (_is_inside || _last_active_view) + if (!_is_own_window) { - _layout->ProcessDraw (GfxContext, force_draw); - } + if (_is_inside || _last_active_view) + { + _layout->ProcessDraw (GfxContext, force_draw); + } - if (_is_maximized) - { - _window_buttons->ProcessDraw (GfxContext, true); + if (_is_maximized) + { + _window_buttons->ProcessDraw (GfxContext, true); + } } GfxContext.PopClippingRectangle(); @@ -333,7 +344,20 @@ PanelMenuView::DrawContent (nux::GraphicsEngine &GfxContext, bool force_draw) gchar * PanelMenuView::GetActiveViewName () { - gchar *label = NULL; + gchar *label = NULL; + BamfWindow *window; + + // There's probably a better way to do this, but we really only want to ignore our own windows + // as there could be cases where windows like ours have menus and we don't want them to fall + // into this statement. Still, will investigate better ways to do this. + window = bamf_matcher_get_active_window (_matcher); + if (BAMF_IS_WINDOW (window) + && g_str_has_prefix (bamf_view_get_name (BAMF_VIEW (window)), "nux input")) + { + _is_own_window = true; + } + else + _is_own_window = false; if (_is_maximized) { @@ -403,7 +427,7 @@ PanelMenuView::Refresh () char *font_description = NULL; GdkScreen *screen = gdk_screen_get_default (); int dpi = 0; - const int text_margin = 20; + const int text_margin = 30; int x = 0; int y = 0; @@ -448,6 +472,11 @@ PanelMenuView::Refresh () cr = cairo_graphics.GetContext(); cairo_set_line_width (cr, 1); + cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); + cairo_paint (cr); + + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + x = _padding; y = 0; @@ -456,43 +485,27 @@ PanelMenuView::Refresh () if (label) { + nux::Color col = PanelStyle::GetDefault ()->GetTextColor (); + float red = col.GetRed (), blue = col.GetBlue (), green = col.GetGreen (); + pango_cairo_update_layout (cr, layout); y += (height - text_height)/2; double startalpha = 1.0 - ((double)text_margin/(double)width); - // Once for the homies that couldn't be here - if (text_width >= width) - { - linpat = cairo_pattern_create_linear (x, y-1, width-x, y-1+text_height); - cairo_pattern_add_color_stop_rgb (linpat, 0, 50/255.0f, 50/255.0f, 45/255.0f); - cairo_pattern_add_color_stop_rgb (linpat, startalpha, 50/255.0f, 50/255.0f, 45/255.0f); - cairo_pattern_add_color_stop_rgba (linpat, startalpha, 0, 0.0, 0.0, 0); - cairo_pattern_add_color_stop_rgba (linpat, 1, 0, 0.0, 0.0, 0); - cairo_set_source(cr, linpat); - cairo_pattern_destroy(linpat); - } - else - { - cairo_set_source_rgb (cr, 50/255.0f, 50/255.0f, 45/255.0f); - } - cairo_move_to (cr, x, y-1); - pango_cairo_show_layout (cr, layout); - cairo_stroke (cr); - // Once again for the homies that could - if (text_width >= width) + if (x+text_width >= width-1) { - linpat = cairo_pattern_create_linear (x, y, width-x, y+text_height); - cairo_pattern_add_color_stop_rgb (linpat, 0, 223/255.0f, 219/255.0f, 210/255.0f); - cairo_pattern_add_color_stop_rgb (linpat, startalpha, 223/255.0f, 219/255.0f, 210/255.0f); + linpat = cairo_pattern_create_linear (x, y, width-1, y+text_height); + cairo_pattern_add_color_stop_rgb (linpat, 0, red, green, blue); + cairo_pattern_add_color_stop_rgb (linpat, startalpha, red, green, blue); cairo_pattern_add_color_stop_rgba (linpat, 1, 0, 0.0, 0.0, 0); cairo_set_source(cr, linpat); cairo_pattern_destroy(linpat); } else { - cairo_set_source_rgb (cr, 223/255.0f, 219/255.0f, 210/255.0f); + cairo_set_source_rgb (cr, red, green, blue); } cairo_move_to (cr, x, y); pango_cairo_show_layout (cr, layout); @@ -524,7 +537,7 @@ PanelMenuView::Refresh () _title_layer = new nux::TextureLayer (texture2D->GetDeviceTexture(), texxform, nux::Color::White, - false, + true, rop); @@ -636,7 +649,15 @@ PanelMenuView::OnActiveWindowChanged (BamfView *old_view, _is_maximized = WindowManager::Default ()->IsWindowMaximized (xid); if (_decor_map.find (xid) == _decor_map.end ()) + { _decor_map[xid] = true; + + // if we've just started tracking this window and it is maximized, let's + // make sure it's undecorated just in case it slipped by us earlier + // (I'm looking at you, Chromium!) + if (_is_maximized) + WindowManager::Default ()->Undecorate (xid); + } // first see if we need to remove and old callback if (_name_changed_callback_id != 0) diff --git a/src/PanelMenuView.h b/src/PanelMenuView.h index 8e1407018..9e243c3f5 100644 --- a/src/PanelMenuView.h +++ b/src/PanelMenuView.h @@ -106,6 +106,7 @@ private: bool _is_inside; bool _is_grabbed; bool _is_maximized; + bool _is_own_window; PanelIndicatorObjectEntryView *_last_active_view; WindowButtons * _window_buttons; diff --git a/src/PanelStyle.cpp b/src/PanelStyle.cpp new file mode 100644 index 000000000..13230f4ba --- /dev/null +++ b/src/PanelStyle.cpp @@ -0,0 +1,274 @@ +/* + * 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: Mirco Müller <mirco.mueller@canonical.com> + * Neil Jagdish Patel <neil.patel@canonical.com> + */ + +#include "config.h" + +#include <math.h> +#include <gtk/gtk.h> + +#include <Nux/Nux.h> +#include <NuxGraphics/GraphicsEngine.h> +#include <NuxImage/CairoGraphics.h> + +#include "PanelStyle.h" + +static PanelStyle *_style = NULL; + +PanelStyle::PanelStyle () +: _theme_name (NULL) +{ + _offscreen = gtk_offscreen_window_new (); + gtk_widget_set_name (_offscreen, "UnityPanelWidget"); + gtk_widget_set_size_request (_offscreen, 100, 24); + gtk_widget_show_all (_offscreen); + + g_signal_connect (gtk_settings_get_default (), "notify::gtk-theme-name", + G_CALLBACK (PanelStyle::OnStyleChanged), this); + + Refresh (); +} + +PanelStyle::~PanelStyle () +{ + gtk_widget_destroy (_offscreen); + + if (_style == this) + _style = NULL; + + g_free (_theme_name); +} + +PanelStyle * +PanelStyle::GetDefault () +{ + if (G_UNLIKELY (!_style)) + _style = new PanelStyle (); + + return _style; +} + +void +PanelStyle::Refresh () +{ + GtkStyle* style = NULL; + + if (_theme_name) + g_free (_theme_name); + + _theme_name = NULL; + g_object_get (gtk_settings_get_default (), "gtk-theme-name", &_theme_name, NULL); + + style = gtk_widget_get_style (_offscreen); + + _text.SetRed ((float) style->text[0].red / (float) 0xffff); + _text.SetGreen ((float) style->text[0].green / (float) 0xffff); + _text.SetBlue ((float) style->text[0].blue / (float) 0xffff); + _text.SetAlpha (1.0f); + + _text_shadow.SetRed ((float) style->dark[0].red / (float) 0xffff); + _text_shadow.SetGreen ((float) style->dark[0].green / (float) 0xffff); + _text_shadow.SetBlue ((float) style->dark[0].blue / (float) 0xffff); + _text_shadow.SetAlpha (1.0f); + + _bg_top.SetRed ((float) style->bg[1].red / (float) 0xffff); + _bg_top.SetGreen ((float) style->bg[1].green / (float) 0xffff); + _bg_top.SetBlue ((float) style->bg[1].blue / (float) 0xffff); + _bg_top.SetAlpha (1.0f); + + _bg_bottom.SetRed ((float) style->bg[0].red / (float) 0xffff); + _bg_bottom.SetGreen ((float) style->bg[0].green / (float) 0xffff); + _bg_bottom.SetBlue ((float) style->bg[0].blue / (float) 0xffff); + _bg_bottom.SetAlpha (1.0f); + + changed.emit (); +} + +nux::Color& +PanelStyle::GetTextColor () +{ + return _text; +} + +nux::Color& +PanelStyle::GetBackgroundTop () +{ + return _bg_top; +} + +nux::Color& +PanelStyle::GetBackgroundBottom () +{ + return _bg_bottom; +} + +nux::Color& +PanelStyle::GetTextShadow () +{ + return _text_shadow; +} + +void +PanelStyle::OnStyleChanged (GObject* gobject, + GParamSpec* pspec, + gpointer data) +{ + PanelStyle* self = (PanelStyle*) data; + + self->Refresh (); +} + +GdkPixbuf * +PanelStyle::GetBackground (int width, int height) +{ + gtk_widget_set_size_request (_offscreen, width, height); + gdk_window_process_updates (gtk_widget_get_window (_offscreen), TRUE); + + return gtk_offscreen_window_get_pixbuf (GTK_OFFSCREEN_WINDOW (_offscreen)); +} + +nux::BaseTexture * +PanelStyle::GetWindowButton (WindowButtonType type, WindowState state) +{ +#define ICON_LOCATION "/usr/share/themes/%s/metacity-1/%s%s.png" + nux::BaseTexture * texture = NULL; + const char *names[] = { "close", "minimize", "unmaximize" }; + const char *states[] = { "", "_focused_prelight", "_focused_pressed" }; + + // I wish there was a magic bullet here, but not all themes actually set the panel to be + // the same style as the window titlebars (e.g. Clearlooks) so we can just grab the + // metacity window buttons as that would look horrible + if (g_strcmp0 (_theme_name, "Ambiance") == 0 + || g_strcmp0 (_theme_name, "Radiance") == 0) + { + char *filename; + GdkPixbuf *pixbuf; + GError *error = NULL; + + filename = g_strdup_printf (ICON_LOCATION, _theme_name, names[type], states[state]); + + pixbuf = gdk_pixbuf_new_from_file (filename, &error); + if (error) + { + g_warning ("Unable to load window button %s: %s", filename, error->message); + g_error_free (error); + error = NULL; + } + else + texture = nux::CreateTexture2DFromPixbuf (pixbuf, true); + + g_free (filename); + g_object_unref (pixbuf); + } + else + { + texture = GetWindowButtonForTheme (type, state); + } + + return texture; +} + +nux::BaseTexture * +PanelStyle::GetWindowButtonForTheme (WindowButtonType type, WindowState state) +{ + nux::BaseTexture *texture = NULL; + int width = 18, height = 18; + float w = width/3.0f; + float h = height/3.0f; + nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, 22, 22); + cairo_t *cr; + nux::Color main = _text; + + if (type == WINDOW_BUTTON_CLOSE) + { + main = nux::Color (1.0f, 0.3f, 0.3f, 0.8f); + } + + if (state == WINDOW_STATE_PRELIGHT) + main = main * 1.2f; + else if (state == WINDOW_STATE_PRESSED) + main = main * 0.8f; + + cr = cairo_graphics.GetContext(); + cairo_translate (cr, 0.5, 0.5); + cairo_set_line_width (cr, 1.5f); + + cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); + cairo_paint (cr); + + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + + cairo_set_source_rgba (cr, main.GetRed (), main.GetGreen (), main.GetBlue (), main.GetAlpha ()); + + cairo_arc (cr, width/2.0f, height/2.0f, (width - 2)/2.0f, 0.0f, 360 * (M_PI/180)); + cairo_stroke (cr); + + if (type == WINDOW_BUTTON_CLOSE) + { + cairo_move_to (cr, w, h); + cairo_line_to (cr, width - w, height - h); + cairo_move_to (cr, width -w, h); + cairo_line_to (cr, w, height - h); + } + else if (type == WINDOW_BUTTON_MINIMIZE) + { + cairo_move_to (cr, w, height/2.0f); + cairo_line_to (cr, width - w, height/2.0f); + } + else + { + cairo_move_to (cr, w, h); + cairo_line_to (cr, width - w, h); + cairo_line_to (cr, width - w, height - h); + cairo_line_to (cr, w, height -h); + cairo_close_path (cr); + } + + cairo_stroke (cr); + + cairo_destroy (cr); + + nux::NBitmapData* bitmap = cairo_graphics.GetBitmap(); + texture = nux::GetThreadGLDeviceFactory ()->CreateSystemCapableTexture (); + texture->Update(bitmap); + delete bitmap; + + return texture; +} + +GdkPixbuf * +PanelStyle::GetHomeButton () +{ + GdkPixbuf *pixbuf = NULL; + + if (g_str_has_prefix (_theme_name, "Ambiance")) + pixbuf = gdk_pixbuf_new_from_file (PKGDATADIR"/bfb.png", NULL); + else + pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), + "start-here", + 24, + (GtkIconLookupFlags)0, + NULL); + if (pixbuf == NULL) + pixbuf = gtk_icon_theme_load_icon (gtk_icon_theme_get_default (), + "distributor-logo", + 24, + (GtkIconLookupFlags)0, + NULL); + return pixbuf; +} diff --git a/src/PanelStyle.h b/src/PanelStyle.h new file mode 100644 index 000000000..c721faa88 --- /dev/null +++ b/src/PanelStyle.h @@ -0,0 +1,79 @@ +/* + * 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: Mirco Müller <mirco.mueller@canonical.com> + * Neil Jagdish Patel <neil.patel@canonical.com> + */ + +#ifndef PANEL_STYLE_H +#define PANEL_STYLE_H + +#include <Nux/Nux.h> + +#include <gtk/gtk.h> + +class PanelStyle : public nux::Object +{ + public: + typedef enum + { + WINDOW_BUTTON_CLOSE = 0, + WINDOW_BUTTON_MINIMIZE, + WINDOW_BUTTON_UNMAXIMIZE + + } WindowButtonType; + + typedef enum + { + WINDOW_STATE_NORMAL, + WINDOW_STATE_PRELIGHT, + WINDOW_STATE_PRESSED + + } WindowState; + + static PanelStyle * GetDefault (); + + PanelStyle (); + ~PanelStyle (); + + nux::Color& GetTextColor (); + nux::Color& GetBackgroundTop (); + nux::Color& GetBackgroundBottom (); + nux::Color& GetTextShadow (); + + GdkPixbuf * GetBackground (int width, int height); + + nux::BaseTexture * GetWindowButton (WindowButtonType type, WindowState state); + + GdkPixbuf * GetHomeButton (); + + sigc::signal<void> changed; + + private: + void Refresh (); + static void OnStyleChanged (GObject* gobject, + GParamSpec* pspec, + gpointer data); + nux::BaseTexture * GetWindowButtonForTheme (WindowButtonType type, WindowState state); + private: + GtkWidget *_offscreen; + char *_theme_name; + nux::Color _text; + nux::Color _bg_top; + nux::Color _bg_bottom; + nux::Color _text_shadow; +}; + +#endif // PANEL_STYLE_H diff --git a/src/PanelTray.cpp b/src/PanelTray.cpp new file mode 100644 index 000000000..8f2737b3b --- /dev/null +++ b/src/PanelTray.cpp @@ -0,0 +1,231 @@ +/* + * 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: Neil Jagdish Patel <neil.patel@canonical.com> + */ + +#include "PanelTray.h" + +#define SETTINGS_NAME "com.canonical.Unity.Panel" +#define PADDING 3 + +PanelTray::PanelTray () +: _n_children (0), + _last_x (0), + _last_y (0) +{ + _settings = g_settings_new (SETTINGS_NAME); + _whitelist = g_settings_get_strv (_settings, "systray-whitelist"); + + _window = gtk_window_new (GTK_WINDOW_POPUP); + gtk_window_set_type_hint (GTK_WINDOW (_window), GDK_WINDOW_TYPE_HINT_DOCK); + //gtk_window_set_keep_above (GTK_WINDOW (_window), TRUE); + gtk_window_set_skip_pager_hint (GTK_WINDOW (_window), TRUE); + gtk_window_set_skip_taskbar_hint (GTK_WINDOW (_window), TRUE); + gtk_window_resize (GTK_WINDOW (_window), 1, 24); + gtk_window_move (GTK_WINDOW (_window), 200, 12); + gtk_widget_set_name (_window, "UnityPanelApplet"); + gtk_widget_set_colormap (_window, gdk_screen_get_rgba_colormap (gdk_screen_get_default ())); + gtk_widget_realize (_window); + gdk_window_set_back_pixmap (_window->window, NULL, FALSE); + gtk_widget_set_app_paintable (_window, TRUE); + g_signal_connect (_window, "expose-event", G_CALLBACK (PanelTray::OnTrayExpose), this); + + if (!g_getenv ("UNITY_PANEL_TRAY_DISABLE")) + { + _tray = na_tray_new_for_screen (gdk_screen_get_default (), + GTK_ORIENTATION_HORIZONTAL, + (NaTrayFilterCallback)FilterTrayCallback, + this); + g_signal_connect (na_tray_get_manager (_tray), "tray_icon_removed", + G_CALLBACK (PanelTray::OnTrayIconRemoved), this); + + gtk_container_add (GTK_CONTAINER (_window), GTK_WIDGET (_tray)); + gtk_widget_show (GTK_WIDGET (_tray)); + + gtk_widget_show_all (_window); + } +} + +PanelTray::~PanelTray () +{ + g_strfreev (_whitelist); + g_object_unref (_settings); +} + +void +PanelTray::Draw (nux::GraphicsEngine& gfx_content, bool force_draw) +{ + nux::Geometry geo = GetGeometry (); + + if (geo.x != _last_x || geo.y != _last_y) + { + _last_x = geo.x; + _last_y = geo.y; + + gtk_window_move (GTK_WINDOW (_window), geo.x + PADDING, geo.y); + } +} + +Window +PanelTray::GetTrayWindow () +{ + return GDK_WINDOW_XWINDOW (_window->window); +} + +void +PanelTray::Sync () +{ + SetMinMaxSize ((_n_children * 24) + (PADDING * 2), 24); + ComputeChildLayout (); + + QueueDraw (); +} + +gboolean +PanelTray::FilterTrayCallback (NaTray *tray, NaTrayChild *icon, PanelTray *self) +{ + char *title; + char *res_name = NULL; + char *res_class = NULL; + char *name; + int i = 0; + bool accept = false; + + title = na_tray_child_get_title (icon); + na_tray_child_get_wm_class (icon, &res_name, &res_class); + + while ((name = self->_whitelist[i])) + { + if (g_strcmp0 (name, "all") == 0) + { + accept = true; + break; + } + else if (!name || g_strcmp0 (name, "") == 0) + { + accept = false; + break; + } + else if (g_str_has_prefix (title, name) + || g_str_has_prefix (res_name, name) + || g_str_has_prefix (res_class, name)) + { + accept = true; + break; + } + + i++; + } + + if (accept) + { + if (na_tray_child_has_alpha (icon)) + na_tray_child_set_composited (icon, TRUE); + + self->_n_children++; + g_idle_add ((GSourceFunc)IdleSync, self); + } + + g_debug ("TrayChild %s: %s %s", na_tray_child_get_title (icon), res_name, res_class); + + g_free (res_name); + g_free (res_class); + g_free (title); + + return accept ? TRUE : FALSE; +} + +void +PanelTray::OnTrayIconRemoved (NaTrayManager *manager, NaTrayChild *child, PanelTray *self) +{ + g_idle_add ((GSourceFunc)IdleSync, self); + self->_n_children--; +} + +gboolean +PanelTray::IdleSync (PanelTray *self) +{ + self->Sync (); + return FALSE; +} + +gboolean +PanelTray::OnTrayExpose (GtkWidget *widget, GdkEventExpose *ev, PanelTray *tray) +{ + cairo_t *cr = gdk_cairo_create (widget->window); + GtkAllocation alloc; + + gtk_widget_get_allocation (widget, &alloc); + + gdk_cairo_region (cr, ev->region); + cairo_clip (cr); + + cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); + cairo_paint (cr); + + cairo_set_operator (cr, CAIRO_OPERATOR_OVER); + cairo_set_source_rgba (cr, 0.0f, 0.0f, 0.0f, 0.0f); + cairo_rectangle (cr, 0, 0, alloc.width, alloc.height); + cairo_fill (cr); + + cairo_destroy (cr); + + gtk_container_propagate_expose (GTK_CONTAINER (widget), + gtk_bin_get_child (GTK_BIN (widget)), + ev); + + return FALSE; +} + +// +// We don't use these +// +void +PanelTray::OnEntryAdded (IndicatorObjectEntryProxy *proxy) +{ + +} + +void +PanelTray::OnEntryMoved (IndicatorObjectEntryProxy *proxy) +{ + +} + +void +PanelTray::OnEntryRemoved (IndicatorObjectEntryProxy *proxy) +{ + +} + +const gchar * +PanelTray::GetName () +{ + return "PanelTray"; +} + +const gchar * +PanelTray::GetChildsName () +{ + return ""; +} + +void +PanelTray::AddProperties (GVariantBuilder *builder) +{ + +} + diff --git a/src/PanelTray.h b/src/PanelTray.h new file mode 100644 index 000000000..94cd6d52e --- /dev/null +++ b/src/PanelTray.h @@ -0,0 +1,73 @@ +/* + * 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: Neil Jagdish Patel <neil.patel@canonical.com> + */ + +#ifndef PANEL_TRAY_H +#define PANEL_TRAY_H + +#include <Nux/View.h> +#include <gtk/gtk.h> + +#include <gdk/gdkx.h> + +#include "IndicatorObjectProxy.h" +#include "Introspectable.h" +#include "PanelIndicatorObjectView.h" + +#include <unity-misc/na-tray.h> +#include <unity-misc/na-tray-child.h> +#include <unity-misc/na-tray-manager.h> + +class PanelTray : public PanelIndicatorObjectView +{ +public: + + PanelTray (); + ~PanelTray (); + + void Draw (nux::GraphicsEngine& gfx_content, bool force_draw); + + Window GetTrayWindow (); + + void Sync (); + + void OnEntryAdded (IndicatorObjectEntryProxy *proxy); + void OnEntryMoved (IndicatorObjectEntryProxy *proxy); + void OnEntryRemoved (IndicatorObjectEntryProxy *proxy); + +public: + int _n_children; + char **_whitelist; +protected: + const gchar * GetName (); + const gchar * GetChildsName (); + void AddProperties (GVariantBuilder *builder); + +private: + static gboolean FilterTrayCallback (NaTray *tray, NaTrayChild *child, PanelTray *self); + static void OnTrayIconRemoved (NaTrayManager *manager, NaTrayChild *child, PanelTray *self); + static gboolean IdleSync (PanelTray *tray); + static gboolean OnTrayExpose (GtkWidget *widget, GdkEventExpose *ev, PanelTray *tray); + +private: + GSettings *_settings; + GtkWidget *_window; + NaTray *_tray; + int _last_x; + int _last_y; +}; +#endif diff --git a/src/PanelView.cpp b/src/PanelView.cpp index 21a6f9eb3..feac1d762 100644 --- a/src/PanelView.cpp +++ b/src/PanelView.cpp @@ -32,13 +32,21 @@ #include <glib.h> #include "PanelView.h" +#include "PanelStyle.h" #include "IndicatorObjectFactoryRemote.h" #include "PanelIndicatorObjectView.h" +NUX_IMPLEMENT_OBJECT_TYPE (PanelView); + PanelView::PanelView (NUX_FILE_LINE_DECL) -: View (NUX_FILE_LINE_PARAM) +: View (NUX_FILE_LINE_PARAM), + _is_dirty (true), + _opacity (1.0f) { + _style = new PanelStyle (); + _style->changed.connect (sigc::mem_fun (this, &PanelView::ForceUpdateBackground)); + _bg_layer = new nux::ColorLayer (nux::Color (0xff595853), true); _layout = new nux::HLayout ("", NUX_TRACKER_LOCATION); @@ -53,6 +61,10 @@ PanelView::PanelView (NUX_FILE_LINE_DECL) _layout->AddView (_menu_view, 1, nux::eCenter, nux::eFull); AddChild (_menu_view); + _tray = new PanelTray (); + _layout->AddView (_tray, 0, nux::eCenter, nux::eFull); + AddChild (_tray); + _remote = new IndicatorObjectFactoryRemote (); _remote->OnObjectAdded.connect (sigc::mem_fun (this, &PanelView::OnObjectAdded)); _remote->OnMenuPointerMoved.connect (sigc::mem_fun (this, &PanelView::OnMenuPointerMoved)); @@ -62,16 +74,11 @@ PanelView::PanelView (NUX_FILE_LINE_DECL) PanelView::~PanelView () { + _style->UnReference (); delete _remote; delete _bg_layer; } -PanelHomeButton * -PanelView::HomeButton () -{ - return _home_button; -} - const gchar* PanelView::GetName () { return "Panel"; @@ -150,32 +157,16 @@ PanelView::UpdateBackground () { nux::Geometry geo = GetGeometry (); - if (geo.width == _last_width && geo.height == _last_height) + if (geo.width == _last_width && geo.height == _last_height && !_is_dirty) return; _last_width = geo.width; _last_height = geo.height; + _is_dirty = false; - nux::CairoGraphics cairo_graphics(CAIRO_FORMAT_ARGB32, _last_width, _last_height); - cairo_t *cr = cairo_graphics.GetContext(); - cairo_set_line_width (cr, 1); - - cairo_pattern_t *pat = cairo_pattern_create_linear (0, 0, 0, _last_height); - cairo_pattern_add_color_stop_rgb (pat, 0.0f, 89/255.0f, 88/255.0f, 83/255.0f); - cairo_pattern_add_color_stop_rgb (pat, 1.0f, 50/255.0f, 50/255.0f, 45/255.0f); - cairo_set_source (cr, pat); - cairo_rectangle (cr, 0, 0, _last_width, _last_height); - cairo_fill (cr); - cairo_pattern_destroy (pat); - - cairo_destroy (cr); - - nux::NBitmapData* bitmap = cairo_graphics.GetBitmap(); - - nux::BaseTexture* texture2D = nux::GetThreadGLDeviceFactory ()->CreateSystemCapableTexture (); - texture2D->Update(bitmap); - delete bitmap; - + GdkPixbuf *pixbuf = _style->GetBackground (geo.width, geo.height); + nux::BaseTexture * texture2D = nux::CreateTexture2DFromPixbuf (pixbuf, true); + g_object_unref (pixbuf); nux::TexCoordXForm texxform; texxform.SetTexCoordType (nux::TexCoordXForm::OFFSET_COORD); texxform.SetWrap (nux::TEXWRAP_REPEAT, nux::TEXWRAP_REPEAT); @@ -183,42 +174,78 @@ PanelView::UpdateBackground () delete _bg_layer; nux::ROPConfig rop; - rop.Blend = false; // Disable the blending. By default rop.Blend is false. - rop.SrcBlend = GL_ONE; // Set the source blend factor. - rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; // Set the destination blend factor. + rop.Blend = true; + rop.SrcBlend = GL_ONE; + rop.DstBlend = GL_ONE_MINUS_SRC_ALPHA; + nux::Color col = nux::Color::White; + col.SetAlpha (_opacity); _bg_layer = new nux::TextureLayer (texture2D->GetDeviceTexture(), - texxform, // The Oject that defines the texture wraping and coordinate transformation. - nux::Color::White, // The color used to modulate the texture. - true, // Write the alpha value of the texture to the destination buffer. - rop // Use the given raster operation to set the blending when the layer is being rendered. - ); - + texxform, + col, + true, + rop); texture2D->UnReference (); NeedRedraw (); } +void +PanelView::ForceUpdateBackground () +{ + std::list<Area *>::iterator it; + + _is_dirty = true; + UpdateBackground (); + + std::list<Area *> my_children = _layout->GetChildren (); + for (it = my_children.begin(); it != my_children.end(); it++) + { + PanelIndicatorObjectView *view = static_cast<PanelIndicatorObjectView *> (*it); + + view->QueueDraw (); + if (view->_layout == NULL) + continue; + + std::list<Area *>::iterator it2; + + std::list<Area *> its_children = view->_layout->GetChildren (); + for (it2 = its_children.begin(); it2 != its_children.end(); it2++) + { + PanelIndicatorObjectEntryView *entry = static_cast<PanelIndicatorObjectEntryView *> (*it2); + entry->QueueDraw (); + } + } + _home_button->QueueDraw (); + QueueDraw (); +} + // // Signals // void PanelView::OnObjectAdded (IndicatorObjectProxy *proxy) { - PanelIndicatorObjectView *view = new PanelIndicatorObjectView (proxy); - + PanelIndicatorObjectView *view; + // Appmenu is treated differently as it needs to expand // We could do this in a more special way, but who has the time for special? if (g_strstr_len (proxy->GetName ().c_str (), -1, "appmenu") != NULL) + { + view = _menu_view; _menu_view->SetProxy (proxy); + } else + { + view = new PanelIndicatorObjectView (proxy); + _layout->AddView (view, 0, nux::eCenter, nux::eFull); + AddChild (view); + } _layout->SetContentDistribution (nux::eStackLeft); - AddChild (view); - - this->ComputeChildLayout (); + ComputeChildLayout (); NeedRedraw (); } @@ -305,3 +332,61 @@ PanelView::OnEntryActivated (const char *entry_id) if (g_strcmp0 (entry_id, "") == 0) _menu_view->AllMenusClosed (); } + +// +// Useful Public Methods +// +PanelHomeButton * +PanelView::HomeButton () +{ + return _home_button; +} + +void +PanelView::StartFirstMenuShow () +{ + +} + +void +PanelView::EndFirstMenuShow () +{ + std::list<Area *>::iterator it; + + std::list<Area *> my_children = _layout->GetChildren (); + for (it = my_children.begin(); it != my_children.end(); it++) + { + PanelIndicatorObjectView *view = static_cast<PanelIndicatorObjectView *> (*it); + + if (view->_layout == NULL) + continue; + + std::list<Area *>::iterator it2; + + std::list<Area *> its_children = view->_layout->GetChildren (); + for (it2 = its_children.begin(); it2 != its_children.end(); it2++) + { + PanelIndicatorObjectEntryView *entry = static_cast<PanelIndicatorObjectEntryView *> (*it2); + + entry->Activate (); + return; + } + } +} + +Window +PanelView::GetTrayWindow () +{ + return _tray->GetTrayWindow (); +} + +void +PanelView::SetOpacity (float opacity) +{ + if (_opacity == opacity) + return; + + _opacity = opacity; + + ForceUpdateBackground (); +} diff --git a/src/PanelView.h b/src/PanelView.h index dff7801a6..3876c1140 100644 --- a/src/PanelView.h +++ b/src/PanelView.h @@ -24,13 +24,18 @@ #include <Nux/TextureArea.h> #include <NuxGraphics/GraphicsEngine.h> -#include "PanelHomeButton.h" -#include "PanelMenuView.h" +#include <gdk/gdkx.h> + #include "IndicatorObjectFactoryRemote.h" #include "Introspectable.h" +#include "PanelHomeButton.h" +#include "PanelMenuView.h" +#include "PanelTray.h" +#include "PanelStyle.h" class PanelView : public Introspectable, public nux::View { + NUX_DECLARE_OBJECT_TYPE (PanelView, nux::View); public: PanelView (NUX_FILE_LINE_PROTO); ~PanelView (); @@ -49,6 +54,13 @@ public: PanelHomeButton * HomeButton (); + void StartFirstMenuShow (); + void EndFirstMenuShow (); + + Window GetTrayWindow (); + + void SetOpacity (float opacity); + protected: // Introspectable methods const gchar * GetName (); @@ -57,17 +69,23 @@ protected: private: void UpdateBackground (); + void ForceUpdateBackground (); private: IndicatorObjectFactoryRemote *_remote; PanelHomeButton *_home_button; PanelMenuView *_menu_view; + PanelTray *_tray; nux::AbstractPaintLayer *_bg_layer; nux::HLayout *_layout; - + int _last_width; int _last_height; + + PanelStyle *_style; + bool _is_dirty; + float _opacity; }; #endif // PANEL_VIEW_H diff --git a/src/PlaceFactoryFile.cpp b/src/PlaceFactoryFile.cpp index c4332127a..bfd25f4c6 100644 --- a/src/PlaceFactoryFile.cpp +++ b/src/PlaceFactoryFile.cpp @@ -28,8 +28,8 @@ static void on_directory_enumeration_ready (GObject *source, PlaceFactoryFile::PlaceFactoryFile (const char *directory) { //FIXME: This is a temporary Alpha 2 fix - g_spawn_command_line_async ("killall unity-files-daemon", NULL); - g_spawn_command_line_async ("killall unity-applications-daemon", NULL); + g_spawn_command_line_sync ("killall unity-files-daemon", NULL, NULL, NULL, NULL); + g_spawn_command_line_sync ("killall unity-applications-daemon", NULL, NULL, NULL, NULL); /* Use the default lookup location */ if (directory == NULL) diff --git a/src/PlacesController.cpp b/src/PlacesController.cpp index ad2aa125c..a4843de9c 100644 --- a/src/PlacesController.cpp +++ b/src/PlacesController.cpp @@ -48,7 +48,7 @@ PlacesController::PlacesController () _window_layout = new nux::HLayout (); _window = new nux::BaseWindow ("Dash"); - _window->SetBackgroundColor (nux::Color (0.0, 0.0, 0.0, 0.7)); + _window->SetBackgroundColor (nux::Color (0.0, 0.0, 0.0, 0.85)); _window->SinkReference (); _window->SetConfigureNotifyCallback(&PlacesController::WindowConfigureCallback, this); _window->ShowWindow(false); @@ -78,7 +78,7 @@ void PlacesController::Show () return; _window->ShowWindow (true, false); - _window->EnableInputWindow (true, 1); + _window->EnableInputWindow (true, "places", true); _window->GrabPointer (); _window->GrabKeyboard (); _window->NeedRedraw (); diff --git a/src/PlacesGroup.cpp b/src/PlacesGroup.cpp index 724cd29ee..7357a06f4 100644 --- a/src/PlacesGroup.cpp +++ b/src/PlacesGroup.cpp @@ -115,7 +115,7 @@ void PlacesGroup::AddLayout (nux::Layout *layout) // By setting the stretch factor of the GridHLayout to 0, the height of the grid // will be forced to the height that is necessary to include all its elements. - _group_layout->AddLayout (_content, 0); + _group_layout->AddLayout (_content, 1); NeedRedraw (); } diff --git a/src/PlacesResultsController.cpp b/src/PlacesResultsController.cpp index cd36fc4b8..ac495c568 100644 --- a/src/PlacesResultsController.cpp +++ b/src/PlacesResultsController.cpp @@ -81,6 +81,10 @@ PlacesResultsController::AddResultToGroup (const char *groupname, { group->SetVisible (true); _results_view->ReJiggyGroups (); + + group->QueueDraw (); + group->ComputeChildLayout (); + group->GetLayout ()->QueueDraw (); } } @@ -102,6 +106,12 @@ PlacesResultsController::RemoveResultFromGroup (const char *groupname, group->SetVisible (false); _results_view->ReJiggyGroups (); } + else + { + group->QueueDraw (); + group->GetLayout ()->QueueDraw (); + group->ComputeChildLayout (); + } } else { @@ -155,7 +165,7 @@ PlacesResultsController::CreateGroup (const char *groupname) nux::GridHLayout *layout = new nux::GridHLayout (NUX_TRACKER_LOCATION); layout->ForceChildrenSize (true); - layout->SetChildrenSize (140, 90); + layout->SetChildrenSize (140, 100); layout->EnablePartialVisibility (false); layout->SetVerticalExternalMargin (4); diff --git a/src/PlacesResultsView.cpp b/src/PlacesResultsView.cpp index f11f2a2c3..d01c8509b 100644 --- a/src/PlacesResultsView.cpp +++ b/src/PlacesResultsView.cpp @@ -57,6 +57,9 @@ PlacesResultsView::ReJiggyGroups () if ((*it)->IsVisible ()) { _layout->AddView ((*it), 0, nux::MINOR_POSITION_CENTER, nux::MINOR_SIZE_FULL); + _layout->QueueDraw (); + (*it)->QueueDraw (); + QueueDraw (); } } } diff --git a/src/PlacesSimpleTile.cpp b/src/PlacesSimpleTile.cpp index 1ab0da43c..2a45badd3 100644 --- a/src/PlacesSimpleTile.cpp +++ b/src/PlacesSimpleTile.cpp @@ -47,16 +47,12 @@ PlacesSimpleTile::PlacesSimpleTile (const char *icon_name, const char *label, in _layout->AddLayout (new nux::SpaceLayout (0, 0, 12, 12)); _layout->AddView (_icontex, 0, nux::eCenter, nux::eFull); - _layout->AddSpace (6, 0); + _layout->AddLayout (new nux::SpaceLayout (0, 0, 12, 12)); _layout->AddView (_cairotext, 0, nux::eCenter, nux::eFull); SetMinimumSize (160, 128); SetMaximumSize (160, 128); - int textwidth, textheight; - textwidth = textheight = 0; - _cairotext->GetTextExtents (textwidth, textheight); - AddChild (_icontex); SetCompositionLayout (_layout); @@ -73,6 +69,20 @@ PlacesSimpleTile::~PlacesSimpleTile () g_free (_uri); } +nux::Geometry +PlacesSimpleTile::GetHighlightGeometry () +{ + nux::Geometry base = GetGeometry (); + nux::Geometry icontex_base = _icontex->GetGeometry (); + + _highlight_geometry.x = (base.width - icontex_base.width) / 2; + _highlight_geometry.y = 12; + _highlight_geometry.width = icontex_base.width; + _highlight_geometry.height = icontex_base.height; + + return _highlight_geometry; +} + const char * PlacesSimpleTile::GetLabel () { diff --git a/src/PlacesSimpleTile.h b/src/PlacesSimpleTile.h index 5141a1a95..5835cf13c 100644 --- a/src/PlacesSimpleTile.h +++ b/src/PlacesSimpleTile.h @@ -58,6 +58,8 @@ public: void SetURI (const char *uri); protected: + nux::Geometry GetHighlightGeometry (); + nux::Geometry _highlight_geometry; const gchar* GetName (); const gchar *GetChildsName (); void AddProperties (GVariantBuilder *builder); diff --git a/src/PlacesTile.cpp b/src/PlacesTile.cpp index 74c1ed559..aa015df2f 100644 --- a/src/PlacesTile.cpp +++ b/src/PlacesTile.cpp @@ -19,14 +19,18 @@ * */ +#include "config.h" + +#include "TextureCache.h" #include "Nux/Nux.h" #include "PlacesTile.h" + PlacesTile::PlacesTile (NUX_FILE_LINE_DECL) : -View (NUX_FILE_LINE_PARAM), -_hilight_background (NULL), -_hilight_layer (NULL), -_last_width (0), -_last_height (0) + View (NUX_FILE_LINE_PARAM), + _hilight_background (NULL), + _hilight_layer (NULL), + _last_width (0), + _last_height (0) { _state = STATE_DEFAULT; @@ -42,47 +46,123 @@ _last_height (0) PlacesTile::~PlacesTile () { + if (_hilight_background) + { + _hilight_background->UnReference (); + con_obj.disconnect (); + } + + if (_hilight_layer) + delete _hilight_layer; } -void -PlacesTile::UpdateBackground () +nux::Geometry +PlacesTile::GetHighlightGeometry () { - nux::Geometry base = GetGeometry (); - if ((base.width == _last_width) && (base.height == _last_height)) - return; - - _last_width = base.width; - _last_height = base.height; + return GetGeometry (); +} - nux::CairoGraphics *cairo_graphics = new nux::CairoGraphics (CAIRO_FORMAT_ARGB32, base.width, base.height); +void +PlacesTile::DrawHighlight (const char *texid, int width, int height, nux::BaseTexture **texture) +{ + nux::Geometry base = GetGeometry (); + nux::Geometry highlight_geo = GetHighlightGeometry (); + nux::CairoGraphics *cairo_graphics = new nux::CairoGraphics (CAIRO_FORMAT_ARGB32, highlight_geo.width + 6, highlight_geo.height + 6); cairo_t *cr = cairo_graphics->GetContext(); - + cairo_scale (cr, 1.0f, 1.0f); - + cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.0); cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR); cairo_paint (cr); + + // draw tiled background + // set up clip path cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); - - DrawRoundedRectangle (cr, 1.0, 6.0, 6.0, 15.0, base.width - 12 , base.height - 12); - cairo_set_source_rgba (cr, 0.25, 0.25, 0.25, 0.25); - cairo_fill_preserve (cr); - cairo_set_source_rgba (cr, 1, 1, 1, 1.0); + DrawRoundedRectangle (cr, 1.0, 0, 0, 5.0, highlight_geo.width + 6, highlight_geo.height + 6); + cairo_clip (cr); + + int w, h; + cairo_surface_t *image; + cairo_pattern_t *pattern; + + cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 1.0); + image = cairo_image_surface_create_from_png (PKGDATADIR"/places-tile-bg-tilable.png"); + w = cairo_image_surface_get_width (image); + h = cairo_image_surface_get_height (image); + + + pattern = cairo_pattern_create_for_surface (image); + cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT); + + cairo_set_source (cr, pattern); + + cairo_rectangle (cr, 0, 0, base.width, base.height); + cairo_fill (cr); + + cairo_pattern_destroy (pattern); + cairo_surface_destroy (image); + + // draw the outline + cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE); + + DrawRoundedRectangle (cr, 1.0, 0, 0, 5.0, highlight_geo.width + 6, highlight_geo.height + 6); + cairo_set_source_rgba (cr, 0.66, 0.66, 0.66, 1.0); cairo_set_line_width (cr, 1.0); cairo_stroke (cr); - + cairo_destroy (cr); - - nux::NBitmapData* bitmap = cairo_graphics->GetBitmap(); - if (_hilight_background) - _hilight_background->UnReference (); + nux::NBitmapData *bitmap = cairo_graphics->GetBitmap(); + nux::BaseTexture *tex = nux::GetThreadGLDeviceFactory()->CreateSystemCapableTexture (); + tex->Update (bitmap); + *texture = tex; - _hilight_background = nux::GetThreadGLDeviceFactory()->CreateSystemCapableTexture (); - _hilight_background->Update (bitmap); delete bitmap; +} + +//texture->OnDestroyed.connect (sigc::mem_fun (this, &TextureCache::OnDestroyNotify)); + +void +PlacesTile::OnDestroyNotify (nux::Trackable *Object) +{ + g_warning ("Texture destroyed before we were ready"); + _hilight_background = NULL; + UpdateBackground (); +} + +void +PlacesTile::UpdateBackground () +{ + nux::Geometry base = GetGeometry (); + nux::Geometry highlight_geo = GetHighlightGeometry (); + + if ((base.width == _last_width) && (base.height == _last_height)) + return; + + _last_width = base.width; + _last_height = base.height; + + // try and get a texture from the texture cache + TextureCache *cache = TextureCache::GetDefault (); + nux::BaseTexture * hilight_tex = cache->FindTexture ("PlacesTile.HilightTexture", + highlight_geo.width, highlight_geo.height, + sigc::mem_fun (this, &PlacesTile::DrawHighlight)); + + if (_hilight_background) + { + _hilight_background->UnReference (); + con_obj.disconnect (); + } + + con_obj = hilight_tex->OnDestroyed.connect (sigc::mem_fun (this, &PlacesTile::OnDestroyNotify)); + + _hilight_background = hilight_tex; + _hilight_background->Reference (); + //g_debug ("_hilight_backgrounds reference count %i", _hilight_background->GetReferenceCount ()); + nux::ROPConfig rop; rop.Blend = true; rop.SrcBlend = GL_ONE; @@ -96,13 +176,10 @@ PlacesTile::UpdateBackground () delete _hilight_layer; _hilight_layer = new nux::TextureLayer (_hilight_background->GetDeviceTexture(), - texxform, - nux::Color::White, - true, - rop); - _hilight_background->UnReference (); - _hilight_background = NULL; - delete cairo_graphics; + texxform, + nux::Color::White, + true, + rop); } static inline double @@ -125,13 +202,13 @@ PlacesTile::DrawRoundedRectangle (cairo_t* cr, double height) { double radius = cornerRadius / aspect; - + // top-left, right of the corner cairo_move_to (cr, _align (x + radius), _align (y)); - + // top-right, left of the corner cairo_line_to (cr, _align (x + width - radius), _align (y)); - + // top-right, below the corner cairo_arc (cr, _align (x + width - radius), @@ -139,10 +216,10 @@ PlacesTile::DrawRoundedRectangle (cairo_t* cr, radius, -90.0f * G_PI / 180.0f, 0.0f * G_PI / 180.0f); - + // bottom-right, above the corner cairo_line_to (cr, _align (x + width), _align (y + height - radius)); - + // bottom-right, left of the corner cairo_arc (cr, _align (x + width - radius), @@ -150,10 +227,10 @@ PlacesTile::DrawRoundedRectangle (cairo_t* cr, radius, 0.0f * G_PI / 180.0f, 90.0f * G_PI / 180.0f); - + // bottom-left, right of the corner cairo_line_to (cr, _align (x + radius), _align (y + height)); - + // bottom-left, above the corner cairo_arc (cr, _align (x + radius), @@ -161,7 +238,7 @@ PlacesTile::DrawRoundedRectangle (cairo_t* cr, radius, 90.0f * G_PI / 180.0f, 180.0f * G_PI / 180.0f); - + // top-left, right of the corner cairo_arc (cr, _align (x + radius), @@ -171,7 +248,6 @@ PlacesTile::DrawRoundedRectangle (cairo_t* cr, 270.0f * G_PI / 180.0f); } - long PlacesTile::ProcessEvent (nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo) { long ret = TraverseInfo; @@ -183,15 +259,19 @@ void PlacesTile::Draw (nux::GraphicsEngine& gfxContext, bool forceDraw) { UpdateBackground (); - + nux::Geometry hl_geo = GetHighlightGeometry (); nux::Geometry base = GetGeometry (); + + nux::Geometry total_highlight_geo = nux::Geometry (base.x + hl_geo.x - 3, base.y + hl_geo.y - 3, + hl_geo.width + 7, hl_geo.height + 7); + gfxContext.PushClippingRectangle (base); nux::GetPainter ().PaintBackground (gfxContext, GetGeometry ()); if (_state == STATE_HOVER) { - gPainter.PushDrawLayer (gfxContext, GetGeometry (), _hilight_layer); + gPainter.PushDrawLayer (gfxContext, total_highlight_geo, _hilight_layer); gPainter.PopBackground (); } diff --git a/src/PlacesTile.h b/src/PlacesTile.h index 5e416ebdb..2927e8254 100644 --- a/src/PlacesTile.h +++ b/src/PlacesTile.h @@ -74,6 +74,10 @@ protected: virtual void PreLayoutManagement (); virtual long PostLayoutManagement (long LayoutResult); + virtual nux::Geometry GetHighlightGeometry (); + + void DrawHighlight (const char *texid, int width, int height, nux::BaseTexture **texture); + void RecvMouseEnter (int x, int y, unsigned long button_flags, unsigned long key_flags); void RecvMouseLeave (int x, int y, unsigned long button_flags, unsigned long key_flags); @@ -89,6 +93,9 @@ protected: sigc::signal<void, PlacesTile*, int, int> sigMouseClick; sigc::signal<void, PlacesTile*, int, int> sigMouseDrag; + sigc::connection con_obj; + void OnDestroyNotify (nux::Trackable *Object); + TileState _state; nux::Layout *_layout; nux::BaseTexture *_hilight_background; @@ -104,6 +111,7 @@ protected: double width, double height); + private: int _last_width; int _last_height; diff --git a/src/PlacesView.cpp b/src/PlacesView.cpp index defd913c7..5ae0fb35f 100644 --- a/src/PlacesView.cpp +++ b/src/PlacesView.cpp @@ -88,7 +88,23 @@ PlacesView::~PlacesView () long PlacesView::ProcessEvent(nux::IEvent &ievent, long TraverseInfo, long ProcessEventInfo) { + // FIXME: This breaks with multi-monitor + nux::Geometry homebutton (0.0f, 0.0f, 66.0f, 24.0f); long ret = TraverseInfo; + + if (ievent.e_event == nux::NUX_KEYDOWN + && ievent.GetKeySym () == NUX_VK_ESCAPE) + { + SetActiveEntry (NULL, 0, ""); + return TraverseInfo; + } + + if (ievent.e_event == nux::NUX_MOUSE_RELEASED) + { + if (homebutton.IsPointInside (ievent.e_x, ievent.e_y)) + SetActiveEntry (NULL, 0, ""); + return TraverseInfo; + } ret = _layout->ProcessEvent (ievent, ret, ProcessEventInfo); return ret; diff --git a/src/PluginAdapter.cpp b/src/PluginAdapter.cpp index 86801088e..37bfc5143 100644 --- a/src/PluginAdapter.cpp +++ b/src/PluginAdapter.cpp @@ -146,7 +146,7 @@ MultiActionList::RemoveAction (CompAction *a) } void -MultiActionList::InitiateAll (CompOption::Vector &extraArgs) +MultiActionList::InitiateAll (CompOption::Vector &extraArgs, int state) { CompOption::Vector argument; if (!m_ActionList.size ()) @@ -168,7 +168,7 @@ MultiActionList::InitiateAll (CompOption::Vector &extraArgs) a = m_ActionList.front (); /* Initiate the first available action with the arguments */ - a->initiate () (a, 0, argument); + a->initiate () (a, state, argument); } void @@ -237,7 +237,7 @@ PluginAdapter::MatchStringForXids (std::list<Window> *windows) } void -PluginAdapter::InitiateScale (std::string *match) +PluginAdapter::InitiateScale (std::string *match, int state) { CompOption::Vector argument; CompMatch m (*match); @@ -252,15 +252,14 @@ PluginAdapter::InitiateScale (std::string *match) { if (m.evaluate (w)) { - if (std::find (m_SpreadedWindows.begin (), m_SpreadedWindows.end (), w->id ()) == - m_SpreadedWindows.end ()) + if (std::find (m_SpreadedWindows.begin (), m_SpreadedWindows.end (), w->id ()) == m_SpreadedWindows.end ()) m_SpreadedWindows.push_back (w->id ()); xids.push_back (w->id ()); } } initiate_spread.emit (xids); - m_ScaleActionList.InitiateAll (argument); + m_ScaleActionList.InitiateAll (argument, state); } void @@ -284,7 +283,7 @@ PluginAdapter::InitiateExpo () { CompOption::Vector argument (0); - m_ExpoActionList.InitiateAll (argument); + m_ExpoActionList.InitiateAll (argument, 0); } // WindowManager implementation diff --git a/src/PluginAdapter.h b/src/PluginAdapter.h index dd9e4c17a..379672469 100644 --- a/src/PluginAdapter.h +++ b/src/PluginAdapter.h @@ -35,7 +35,7 @@ public: m_ActionList (n), _primary_action (NULL) {}; - void InitiateAll (CompOption::Vector &extraArgs); + void InitiateAll (CompOption::Vector &extraArgs, int state); void TerminateAll (CompOption::Vector &extraArgs); void AddNewAction (CompAction *, bool primary); @@ -64,7 +64,7 @@ public: void OnScreenGrabbed (); void OnScreenUngrabbed (); - void InitiateScale (std::string *match); + void InitiateScale (std::string *match, int state = 0); void TerminateScale (); bool IsScaleActive (); diff --git a/src/QuicklistView.cpp b/src/QuicklistView.cpp index 427ca7566..254919cdc 100644 --- a/src/QuicklistView.cpp +++ b/src/QuicklistView.cpp @@ -185,7 +185,7 @@ void QuicklistView::Show () { // FIXME: ShowWindow shouldn't need to be called first ShowWindow (true); - EnableInputWindow (true, 1); + EnableInputWindow (true, "quicklist", true); GrabPointer (); NeedRedraw (); diff --git a/src/StaticCairoText.cpp b/src/StaticCairoText.cpp index 0c218ce94..afc1c6821 100644 --- a/src/StaticCairoText.cpp +++ b/src/StaticCairoText.cpp @@ -55,8 +55,9 @@ StaticCairoText::~StaticCairoText () g_signal_handlers_disconnect_by_func (settings, (void *) &StaticCairoText::OnFontChanged, this); + if (_texture2D) - delete (_texture2D); + _texture2D->UnReference (); if (_fontstring) g_free (_fontstring); @@ -433,8 +434,11 @@ void StaticCairoText::UpdateTexture () // an actual opengl texture. if (_texture2D) + { _texture2D->UnReference (); - + _texture2D = NULL; + } + _texture2D = GetThreadGLDeviceFactory()->CreateSystemCapableTexture (); _texture2D->Update (bitmap); diff --git a/src/TextureCache.cpp b/src/TextureCache.cpp new file mode 100644 index 000000000..f19e80e1c --- /dev/null +++ b/src/TextureCache.cpp @@ -0,0 +1,95 @@ +/* + * 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 Gordon Allott <gord.allott@canonical.com> + */ + +#include "TextureCache.h" + +TextureCache::TextureCache() +{ + +} + +TextureCache::~TextureCache() +{ + +} + +TextureCache * +TextureCache::GetDefault () +{ + static TextureCache *default_loader = NULL; + + if (G_UNLIKELY (!default_loader)) + default_loader = new TextureCache (); + + return default_loader; +} + +char * +TextureCache::Hash (const char *id, int width, int height) +{ + return g_strdup_printf ("%s-%ix%i", id, width, height); +} + +nux::BaseTexture * +TextureCache::FindTexture (const char *texture_id, int width, int height, CreateTextureCallback slot) +{ + nux::BaseTexture *texture = NULL; + if (texture_id == NULL) + { + g_error ("Did not supply a texture id to TextureCache::FindTexture"); + return NULL; + } + + char *key = Hash (texture_id, width, height); + texture = _cache[key]; + + if (texture == NULL) + { + // no texture yet, lets make one + slot (texture_id, width, height, &texture); + + //texture->add_destroy_notify_callback (payload, &(TextureCache::OnDestroyNotify)); + //sigc::mem_fun(myalerter, &AlienAlerter::alert) + texture->OnDestroyed.connect (sigc::mem_fun (this, &TextureCache::OnDestroyNotify)); + + _cache[key] = texture; + _cache_inverse[texture] = key; + } + + g_free (key); + + return texture; +} + +void +TextureCache::OnDestroyNotify (nux::Trackable *Object) +{ + nux::BaseTexture *texture = (nux::BaseTexture *)Object; + std::string key = _cache_inverse[texture]; + + if (key.empty ()) + { + g_error ("Texture cache has got into a weird state, we have problems"); + return; + } + + _cache.erase (_cache.find (key)); + _cache_inverse.erase (_cache_inverse.find (texture)); + + return; +} diff --git a/src/TextureCache.h b/src/TextureCache.h new file mode 100644 index 000000000..346d08d8d --- /dev/null +++ b/src/TextureCache.h @@ -0,0 +1,54 @@ +/* + * 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 Gordon Allott <gord.allott@canonical.com> + */ + +#ifndef TEXTURECACHE_H +#define TEXTURECACHE_H +#include <Nux/Nux.h> +#include <string> +#include <map> +#include <vector> +#include <sigc++/sigc++.h> + +/* Basically a nice simple texture cache system, you ask the cache for a texture by id + * if the texture does not exist it calls the callback function you provide it with to create the + * texture, then returns it. + * you should remember to ref/unref the textures yourself however + */ + +class TextureCache +{ + +public: + // id, width, height, texture + typedef sigc::slot<void, const char *, int, int, nux::BaseTexture **> CreateTextureCallback; + + /* don't new this class, use getdefault */ + + static TextureCache * GetDefault (); + nux::BaseTexture * FindTexture (const char *texture_id, int width, int height, CreateTextureCallback callback); + +protected: + TextureCache (); + ~TextureCache (); + char * Hash (const char *id, int width, int height); + std::map<std::string, nux::BaseTexture *> _cache; + std::map<nux::BaseTexture *, std::string> _cache_inverse; // just for faster lookups + void OnDestroyNotify (nux::Trackable *Object); +}; + +#endif // TEXTURECACHE_H diff --git a/src/WindowButtons.cpp b/src/WindowButtons.cpp index 49c6d09ae..fd4fc3e13 100644 --- a/src/WindowButtons.cpp +++ b/src/WindowButtons.cpp @@ -29,33 +29,20 @@ #include <glib.h> - -// FIXME: This will be all automatic in the future -#define AMBIANCE "/usr/share/themes/Ambiance/metacity-1" - -enum -{ - BUTTON_CLOSE=0, - BUTTON_MINIMISE, - BUTTON_UNMAXIMISE -}; - +#include "PanelStyle.h" class WindowButton : public nux::Button { // A single window button public: - WindowButton (int type) + WindowButton (PanelStyle::WindowButtonType type) : nux::Button ("X", NUX_TRACKER_LOCATION), + _type (type), _normal_tex (NULL), _prelight_tex (NULL), _pressed_tex (NULL) { - if (type == BUTTON_CLOSE) - LoadImages ("close"); - else if (type == BUTTON_MINIMISE) - LoadImages ("minimize"); - else - LoadImages ("unmaximize"); + LoadImages (); + PanelStyle::GetDefault ()->changed.connect (sigc::mem_fun (this, &WindowButton::LoadImages)); } ~WindowButton () @@ -101,60 +88,29 @@ public: GfxContext.PopClippingRectangle(); } - void LoadImages (const char *name) + void LoadImages () { - //FIXME: We need to somehow be theme aware. Or, at least support the themes - // we know and have a good default fallback - gchar *filename; - GError *error = NULL; - GdkPixbuf *_normal; - GdkPixbuf *_prelight; - GdkPixbuf *_pressed; - - filename = g_strdup_printf ("%s/%s.png", AMBIANCE, name); - _normal = gdk_pixbuf_new_from_file (filename, &error); - if (error) - { - g_warning ("Unable to load window button %s: %s", filename, error->message); - g_error_free (error); - error = NULL; - } - else - _normal_tex = nux::CreateTexture2DFromPixbuf (_normal, true); - g_free (filename); - g_object_unref (_normal); + PanelStyle *style = PanelStyle::GetDefault (); - filename = g_strdup_printf ("%s/%s_focused_prelight.png", AMBIANCE, name); - _prelight = gdk_pixbuf_new_from_file (filename, &error); - if (error) - { - g_warning ("Unable to load window button %s: %s", filename, error->message); - g_error_free (error); - error = NULL; - } - else - _prelight_tex = nux::CreateTexture2DFromPixbuf (_prelight, true); - g_free (filename); - g_object_unref (_prelight); + if (_normal_tex) + _normal_tex->UnReference (); + if (_prelight_tex) + _prelight_tex->UnReference (); + if (_pressed_tex) + _pressed_tex->UnReference (); - filename = g_strdup_printf ("%s/%s_focused_pressed.png", AMBIANCE, name); - _pressed = gdk_pixbuf_new_from_file (filename, &error); - if (error) - { - g_warning ("Unable to load window button %s: %s", name, error->message); - g_error_free (error); - error = NULL; - } - else - _pressed_tex = nux::CreateTexture2DFromPixbuf (_pressed, true); - g_free (filename); - g_object_unref (_pressed); + _normal_tex = style->GetWindowButton (_type, PanelStyle::WINDOW_STATE_NORMAL); + _prelight_tex = style->GetWindowButton (_type, PanelStyle::WINDOW_STATE_PRELIGHT); + _pressed_tex = style->GetWindowButton (_type, PanelStyle::WINDOW_STATE_PRESSED); if (_normal_tex) - SetMinimumSize (_normal_tex->GetWidth (), _normal_tex->GetHeight ()); + SetMinMaxSize (_normal_tex->GetWidth (), _normal_tex->GetHeight ()); + + QueueDraw (); } private: + PanelStyle::WindowButtonType _type; nux::BaseTexture *_normal_tex; nux::BaseTexture *_prelight_tex; nux::BaseTexture *_pressed_tex; @@ -166,19 +122,19 @@ WindowButtons::WindowButtons () { WindowButton *but; - but = new WindowButton (BUTTON_CLOSE); + but = new WindowButton (PanelStyle::WINDOW_BUTTON_CLOSE); AddView (but, 0, nux::eCenter, nux::eFix); but->sigClick.connect (sigc::mem_fun (this, &WindowButtons::OnCloseClicked)); but->OnMouseEnter.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseEnter)); but->OnMouseLeave.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseLeave)); - but = new WindowButton (BUTTON_MINIMISE); + but = new WindowButton (PanelStyle::WINDOW_BUTTON_MINIMIZE); AddView (but, 0, nux::eCenter, nux::eFix); but->sigClick.connect (sigc::mem_fun (this, &WindowButtons::OnMinimizeClicked)); but->OnMouseEnter.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseEnter)); but->OnMouseLeave.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseLeave)); - but = new WindowButton (BUTTON_UNMAXIMISE); + but = new WindowButton (PanelStyle::WINDOW_BUTTON_UNMAXIMIZE); AddView (but, 0, nux::eCenter, nux::eFix); but->sigClick.connect (sigc::mem_fun (this, &WindowButtons::OnRestoreClicked)); but->OnMouseEnter.connect (sigc::mem_fun (this, &WindowButtons::RecvMouseEnter)); diff --git a/src/WindowButtons.h b/src/WindowButtons.h index 0f6b3247c..23e635a44 100644 --- a/src/WindowButtons.h +++ b/src/WindowButtons.h @@ -19,6 +19,7 @@ #ifndef WINDOW_BUTTONS_H #define WINDOW_BUTTONS_H +#include <Nux/HLayout.h> #include <Nux/View.h> #include "Introspectable.h" diff --git a/src/nux-area-accessible.cpp b/src/nux-area-accessible.cpp index 66c434fdd..e201704af 100644 --- a/src/nux-area-accessible.cpp +++ b/src/nux-area-accessible.cpp @@ -49,32 +49,21 @@ static void nux_area_accessible_get_extents (AtkComponent *component, -#define NUX_AREA_ACCESSIBLE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NUX_TYPE_AREA_ACCESSIBLE, NuxAreaAccessiblePrivate)) - G_DEFINE_TYPE_WITH_CODE (NuxAreaAccessible, nux_area_accessible, NUX_TYPE_OBJECT_ACCESSIBLE, G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init)) -struct _NuxAreaAccessiblePrivate -{ -}; - static void nux_area_accessible_class_init (NuxAreaAccessibleClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass); /* AtkObject */ atk_class->initialize = nux_area_accessible_initialize; - - g_type_class_add_private (gobject_class, sizeof (NuxAreaAccessiblePrivate)); } static void nux_area_accessible_init (NuxAreaAccessible *area_accessible) { - area_accessible->priv = NUX_AREA_ACCESSIBLE_GET_PRIVATE (area_accessible); } AtkObject* diff --git a/src/nux-area-accessible.h b/src/nux-area-accessible.h index 076d7da9b..89e53c84a 100644 --- a/src/nux-area-accessible.h +++ b/src/nux-area-accessible.h @@ -34,14 +34,10 @@ G_BEGIN_DECLS typedef struct _NuxAreaAccessible NuxAreaAccessible; typedef struct _NuxAreaAccessibleClass NuxAreaAccessibleClass; -typedef struct _NuxAreaAccessiblePrivate NuxAreaAccessiblePrivate; struct _NuxAreaAccessible { NuxObjectAccessible parent; - - /* < private > */ - NuxAreaAccessiblePrivate *priv; }; struct _NuxAreaAccessibleClass diff --git a/src/nux-base-window-accessible.cpp b/src/nux-base-window-accessible.cpp index ffb37eaf6..a8aa6d49e 100644 --- a/src/nux-base-window-accessible.cpp +++ b/src/nux-base-window-accessible.cpp @@ -48,20 +48,11 @@ static AtkObject *nux_base_window_accessible_ref_child (AtkObject *obj, static AtkObject *nux_base_window_accessible_get_parent (AtkObject *obj); -#define NUX_BASE_WINDOW_ACCESSIBLE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NUX_TYPE_BASE_WINDOW_ACCESSIBLE, NuxBaseWindowAccessiblePrivate)) - G_DEFINE_TYPE (NuxBaseWindowAccessible, nux_base_window_accessible, NUX_TYPE_VIEW_ACCESSIBLE) -struct _NuxBaseWindowAccessiblePrivate -{ - -}; - static void nux_base_window_accessible_class_init (NuxBaseWindowAccessibleClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass); /* AtkObject */ @@ -69,14 +60,11 @@ nux_base_window_accessible_class_init (NuxBaseWindowAccessibleClass *klass) atk_class->get_n_children = nux_base_window_accessible_get_n_children; atk_class->ref_child = nux_base_window_accessible_ref_child; atk_class->get_parent = nux_base_window_accessible_get_parent; - - g_type_class_add_private (gobject_class, sizeof (NuxBaseWindowAccessiblePrivate)); } static void nux_base_window_accessible_init (NuxBaseWindowAccessible *base_window_accessible) { - base_window_accessible->priv = NUX_BASE_WINDOW_ACCESSIBLE_GET_PRIVATE (base_window_accessible); } AtkObject* diff --git a/src/nux-base-window-accessible.h b/src/nux-base-window-accessible.h index e52cba12a..f28e25ea4 100644 --- a/src/nux-base-window-accessible.h +++ b/src/nux-base-window-accessible.h @@ -37,14 +37,10 @@ G_BEGIN_DECLS typedef struct _NuxBaseWindowAccessible NuxBaseWindowAccessible; typedef struct _NuxBaseWindowAccessibleClass NuxBaseWindowAccessibleClass; -typedef struct _NuxBaseWindowAccessiblePrivate NuxBaseWindowAccessiblePrivate; struct _NuxBaseWindowAccessible { NuxViewAccessible parent; - - /* < private > */ - NuxBaseWindowAccessiblePrivate *priv; }; struct _NuxBaseWindowAccessibleClass diff --git a/src/nux-layout-accessible.cpp b/src/nux-layout-accessible.cpp index 841b2b43d..b3a5000dc 100644 --- a/src/nux-layout-accessible.cpp +++ b/src/nux-layout-accessible.cpp @@ -44,33 +44,22 @@ static AtkObject *nux_layout_accessible_ref_child (AtkObject *obj, gint i); -#define NUX_LAYOUT_ACCESSIBLE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NUX_TYPE_LAYOUT_ACCESSIBLE, NuxLayoutAccessiblePrivate)) - G_DEFINE_TYPE (NuxLayoutAccessible, nux_layout_accessible, NUX_TYPE_AREA_ACCESSIBLE) -struct _NuxLayoutAccessiblePrivate -{ -}; - static void nux_layout_accessible_class_init (NuxLayoutAccessibleClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass); /* AtkObject */ atk_class->initialize = nux_layout_accessible_initialize; atk_class->ref_child = nux_layout_accessible_ref_child; atk_class->get_n_children = nux_layout_accessible_get_n_children; - - g_type_class_add_private (gobject_class, sizeof (NuxLayoutAccessiblePrivate)); } static void nux_layout_accessible_init (NuxLayoutAccessible *layout_accessible) { - layout_accessible->priv = NUX_LAYOUT_ACCESSIBLE_GET_PRIVATE (layout_accessible); } AtkObject* diff --git a/src/nux-layout-accessible.h b/src/nux-layout-accessible.h index be67d51eb..b19060ad9 100644 --- a/src/nux-layout-accessible.h +++ b/src/nux-layout-accessible.h @@ -37,14 +37,10 @@ G_BEGIN_DECLS typedef struct _NuxLayoutAccessible NuxLayoutAccessible; typedef struct _NuxLayoutAccessibleClass NuxLayoutAccessibleClass; -typedef struct _NuxLayoutAccessiblePrivate NuxLayoutAccessiblePrivate; struct _NuxLayoutAccessible { NuxAreaAccessible parent; - - /* < private > */ - NuxLayoutAccessiblePrivate *priv; }; struct _NuxLayoutAccessibleClass diff --git a/src/nux-view-accessible.cpp b/src/nux-view-accessible.cpp index b4e47f4d0..ce671452c 100644 --- a/src/nux-view-accessible.cpp +++ b/src/nux-view-accessible.cpp @@ -53,36 +53,25 @@ static void on_end_focus_cb (AtkObject *accessible); static void nux_view_accessible_focus_handler (AtkObject *accessible, gboolean focus_in); -#define NUX_VIEW_ACCESSIBLE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), NUX_TYPE_VIEW_ACCESSIBLE, NuxViewAccessiblePrivate)) - G_DEFINE_TYPE_WITH_CODE (NuxViewAccessible, nux_view_accessible, NUX_TYPE_AREA_ACCESSIBLE, G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init)) -struct _NuxViewAccessiblePrivate -{ -}; - static void nux_view_accessible_class_init (NuxViewAccessibleClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass); /* AtkObject */ atk_class->initialize = nux_view_accessible_initialize; atk_class->ref_state_set = nux_view_accessible_ref_state_set; - - g_type_class_add_private (gobject_class, sizeof (NuxViewAccessiblePrivate)); } static void nux_view_accessible_init (NuxViewAccessible *view_accessible) { - view_accessible->priv = NUX_VIEW_ACCESSIBLE_GET_PRIVATE (view_accessible); } AtkObject* diff --git a/src/nux-view-accessible.h b/src/nux-view-accessible.h index ba127b4cd..06e93c66a 100644 --- a/src/nux-view-accessible.h +++ b/src/nux-view-accessible.h @@ -37,14 +37,10 @@ G_BEGIN_DECLS typedef struct _NuxViewAccessible NuxViewAccessible; typedef struct _NuxViewAccessibleClass NuxViewAccessibleClass; -typedef struct _NuxViewAccessiblePrivate NuxViewAccessiblePrivate; struct _NuxViewAccessible { NuxAreaAccessible parent; - - /* < private > */ - NuxViewAccessiblePrivate *priv; }; struct _NuxViewAccessibleClass diff --git a/src/unity-launcher-accessible.cpp b/src/unity-launcher-accessible.cpp index 686c1a0de..7c4f340d5 100644 --- a/src/unity-launcher-accessible.cpp +++ b/src/unity-launcher-accessible.cpp @@ -17,12 +17,12 @@ */ /** - * SECTION:nux-view-accessible - * @Title: NuxViewAccessible + * SECTION:unity-launcher-accessible + * @Title: UnityLauncherAccessible * @short_description: Implementation of the ATK interfaces for #Launcher * @see_also: Launcher * - * #NuxViewAccessible implements the required ATK interfaces for + * #UnityLauncherAccessible implements the required ATK interfaces for * #Launcher, ie: exposing the different LauncherIcon on the model as * #child of the object. * @@ -45,33 +45,22 @@ static gint unity_launcher_accessible_get_n_children (AtkObject *obj); static AtkObject *unity_launcher_accessible_ref_child (AtkObject *obj, gint i); -#define UNITY_LAUNCHER_ACCESSIBLE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), UNITY_TYPE_LAUNCHER_ACCESSIBLE, UnityLauncherAccessiblePrivate)) - G_DEFINE_TYPE (UnityLauncherAccessible, unity_launcher_accessible, NUX_TYPE_VIEW_ACCESSIBLE) -struct _UnityLauncherAccessiblePrivate -{ -}; - static void unity_launcher_accessible_class_init (UnityLauncherAccessibleClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass); /* AtkObject */ atk_class->get_n_children = unity_launcher_accessible_get_n_children; atk_class->ref_child = unity_launcher_accessible_ref_child; atk_class->initialize = unity_launcher_accessible_initialize; - - g_type_class_add_private (gobject_class, sizeof (UnityLauncherAccessiblePrivate)); } static void unity_launcher_accessible_init (UnityLauncherAccessible *self) { - self->priv = UNITY_LAUNCHER_ACCESSIBLE_GET_PRIVATE (self); } AtkObject* diff --git a/src/unity-launcher-accessible.h b/src/unity-launcher-accessible.h index 2039cfce7..321cf1c8f 100644 --- a/src/unity-launcher-accessible.h +++ b/src/unity-launcher-accessible.h @@ -34,14 +34,10 @@ G_BEGIN_DECLS typedef struct _UnityLauncherAccessible UnityLauncherAccessible; typedef struct _UnityLauncherAccessibleClass UnityLauncherAccessibleClass; -typedef struct _UnityLauncherAccessiblePrivate UnityLauncherAccessiblePrivate; struct _UnityLauncherAccessible { NuxViewAccessible parent; - - /* < private > */ - UnityLauncherAccessiblePrivate *priv; }; struct _UnityLauncherAccessibleClass diff --git a/src/unity-launcher-icon-accessible.cpp b/src/unity-launcher-icon-accessible.cpp index bde5c8815..1be0fee9f 100644 --- a/src/unity-launcher-icon-accessible.cpp +++ b/src/unity-launcher-icon-accessible.cpp @@ -41,32 +41,21 @@ static void unity_launcher_icon_accessible_initialize (AtkObject *acces static const gchar * unity_launcher_icon_accessible_get_name (AtkObject *obj); -#define UNITY_LAUNCHER_ICON_ACCESSIBLE_GET_PRIVATE(obj) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((obj), UNITY_TYPE_LAUNCHER_ICON_ACCESSIBLE, UnityLauncherIconAccessiblePrivate)) - G_DEFINE_TYPE (UnityLauncherIconAccessible, unity_launcher_icon_accessible, NUX_TYPE_OBJECT_ACCESSIBLE) -struct _UnityLauncherIconAccessiblePrivate -{ -}; - static void unity_launcher_icon_accessible_class_init (UnityLauncherIconAccessibleClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass); /* AtkObject */ atk_class->initialize = unity_launcher_icon_accessible_initialize; atk_class->get_name = unity_launcher_icon_accessible_get_name; - - g_type_class_add_private (gobject_class, sizeof (UnityLauncherIconAccessiblePrivate)); } static void unity_launcher_icon_accessible_init (UnityLauncherIconAccessible *launcher_icon_accessible) { - launcher_icon_accessible->priv = UNITY_LAUNCHER_ICON_ACCESSIBLE_GET_PRIVATE (launcher_icon_accessible); } AtkObject* diff --git a/src/unity-launcher-icon-accessible.h b/src/unity-launcher-icon-accessible.h index fe50e0949..926614a82 100644 --- a/src/unity-launcher-icon-accessible.h +++ b/src/unity-launcher-icon-accessible.h @@ -34,14 +34,10 @@ G_BEGIN_DECLS typedef struct _UnityLauncherIconAccessible UnityLauncherIconAccessible; typedef struct _UnityLauncherIconAccessibleClass UnityLauncherIconAccessibleClass; -typedef struct _UnityLauncherIconAccessiblePrivate UnityLauncherIconAccessiblePrivate; struct _UnityLauncherIconAccessible { NuxObjectAccessible parent; - - /* < private > */ - UnityLauncherIconAccessiblePrivate *priv; }; struct _UnityLauncherIconAccessibleClass diff --git a/src/unity-panel-home-button-accessible.cpp b/src/unity-panel-home-button-accessible.cpp new file mode 100644 index 000000000..132d384fd --- /dev/null +++ b/src/unity-panel-home-button-accessible.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2011 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: Rodrigo Moya <rodrigo.moya@canonical.com> + */ + +/** + * SECTION:unity-panel-home-button-accessible + * @Title: UnityPanelHomeButtonAccessible + * @short_description: Implementation of the ATK interfaces for #PanelHomeButton + * @see_also: PanelHomeButton + * + * #UnityPanelHomeButtonAccessible implements the required ATK interfaces for + * #PanelHomeButton. + * + */ + +#include <glib/gi18n-lib.h> +#include <Nux/Nux.h> +#include "PanelHomeButton.h" +#include "unity-panel-home-button-accessible.h" + +#include "unitya11y.h" + +/* GObject */ +static void unity_panel_home_button_accessible_class_init (UnityPanelHomeButtonAccessibleClass *klass); +static void unity_panel_home_button_accessible_init (UnityPanelHomeButtonAccessible *self); + +/* AtkObject */ +static void unity_panel_home_button_accessible_initialize (AtkObject *accessible, gpointer data); + +G_DEFINE_TYPE (UnityPanelHomeButtonAccessible, unity_panel_home_button_accessible, NUX_TYPE_VIEW_ACCESSIBLE) + +static void +unity_panel_home_button_accessible_class_init (UnityPanelHomeButtonAccessibleClass *klass) +{ + AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass); + + /* AtkObject */ + atk_class->initialize = unity_panel_home_button_accessible_initialize; +} + +static void +unity_panel_home_button_accessible_init (UnityPanelHomeButtonAccessible *self) +{ +} + +AtkObject * +unity_panel_home_button_accessible_new (nux::Object *object) +{ + AtkObject *accessible; + + g_return_val_if_fail (dynamic_cast<PanelHomeButton *>(object), NULL); + + accessible = ATK_OBJECT (g_object_new (UNITY_TYPE_PANEL_HOME_BUTTON_ACCESSIBLE, NULL)); + + atk_object_initialize (accessible, object); + + return accessible; +} + +static void +unity_panel_home_button_accessible_initialize (AtkObject *accessible, gpointer data) +{ + ATK_OBJECT_CLASS (unity_panel_home_button_accessible_parent_class)->initialize (accessible, data); + + accessible->role = ATK_ROLE_PUSH_BUTTON; + atk_object_set_name (accessible, _("Home Button")); +} diff --git a/src/unity-panel-home-button-accessible.h b/src/unity-panel-home-button-accessible.h new file mode 100644 index 000000000..54539fcee --- /dev/null +++ b/src/unity-panel-home-button-accessible.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2011 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: Rodrigo Moya <rodrigo.moya@canonical.com> + */ + +#ifndef UNITY_PANEL_HOME_BUTTON_ACCESSIBLE_H +#define UNITY_PANEL_HOME_BUTTON_ACCESSIBLE_H + +#include <atk/atk.h> + +#include "nux-view-accessible.h" + +G_BEGIN_DECLS + +#define UNITY_TYPE_PANEL_HOME_BUTTON_ACCESSIBLE (unity_panel_home_button_accessible_get_type ()) +#define UNITY_PANEL_HOME_BUTTON_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_TYPE_PANEL_HOME_BUTTON_ACCESSIBLE, UnityPanelHomeButtonAccessible)) +#define UNITY_PANEL_HOME_BUTTON_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_TYPE_PANEL_HOME_BUTTON_ACCESSIBLE, UnityPanelHomeButtonAccessibleClass)) +#define UNITY_IS_PANEL_HOME_BUTTON_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_TYPE_PANEL_HOME_BUTTON_ACCESSIBLE)) +#define UNITY_IS_PANEL_HOME_BUTTON_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_TYPE_PANEL_HOME_BUTTON_ACCESSIBLE)) +#define UNITY_PANEL_HOME_BUTTON_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_TYPE_PANEL_HOME_BUTTON_ACCESSIBLE, UnityPanelHomeButtonAccessibleClass)) + +typedef struct _UnityPanelHomeButtonAccessible UnityPanelHomeButtonAccessible; +typedef struct _UnityPanelHomeButtonAccessibleClass UnityPanelHomeButtonAccessibleClass; + +struct _UnityPanelHomeButtonAccessible +{ + NuxViewAccessible parent; +}; + +struct _UnityPanelHomeButtonAccessibleClass +{ + NuxViewAccessibleClass parent_class; +}; + +GType unity_panel_home_button_accessible_get_type (void); +AtkObject *unity_panel_home_button_accessible_new (nux::Object *object); + +G_END_DECLS + +#endif diff --git a/src/unity-panel-view-accessible.cpp b/src/unity-panel-view-accessible.cpp new file mode 100644 index 000000000..8378e2c85 --- /dev/null +++ b/src/unity-panel-view-accessible.cpp @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2011 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: Rodrigo Moya <rodrigo.moya@canonical.com> + */ + +/** + * SECTION:unity-panel-view-accessible + * @Title: UnityPanelViewAccessible + * @short_description: Implementation of the ATK interfaces for #PanelView + * @see_also: PanelView + * + * #UnityPanelViewAccessible implements the required ATK interfaces for + * #PanelView, ie: exposing the different items contained in the panel + * as children. + * + */ + +#include <glib/gi18n-lib.h> +#include <Nux/Nux.h> +#include "PanelView.h" +#include "unity-panel-view-accessible.h" + +#include "unitya11y.h" + +/* GObject */ +static void unity_panel_view_accessible_class_init (UnityPanelViewAccessibleClass *klass); +static void unity_panel_view_accessible_init (UnityPanelViewAccessible *self); + +/* AtkObject */ +static void unity_panel_view_accessible_initialize (AtkObject *accessible, gpointer data); +static gint unity_panel_view_accessible_get_n_children (AtkObject *accessible); +static AtkObject *unity_panel_view_accessible_ref_child (AtkObject *accessible, gint i); + +G_DEFINE_TYPE (UnityPanelViewAccessible, unity_panel_view_accessible, NUX_TYPE_VIEW_ACCESSIBLE) + +static void +unity_panel_view_accessible_class_init (UnityPanelViewAccessibleClass *klass) +{ + AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass); + + /* AtkObject */ + atk_class->initialize = unity_panel_view_accessible_initialize; + atk_class->get_n_children = unity_panel_view_accessible_get_n_children; + atk_class->ref_child = unity_panel_view_accessible_ref_child; +} + +static void +unity_panel_view_accessible_init (UnityPanelViewAccessible *self) +{ +} + +AtkObject * +unity_panel_view_accessible_new (nux::Object *object) +{ + AtkObject *accessible; + + g_return_val_if_fail (dynamic_cast<PanelView *>(object), NULL); + + accessible = ATK_OBJECT (g_object_new (UNITY_TYPE_PANEL_VIEW_ACCESSIBLE, NULL)); + + atk_object_initialize (accessible, object); + + return accessible; +} + +static void +unity_panel_view_accessible_initialize (AtkObject *accessible, gpointer data) +{ + ATK_OBJECT_CLASS (unity_panel_view_accessible_parent_class)->initialize (accessible, data); + + accessible->role = ATK_ROLE_PANEL; +} + +static gint +unity_panel_view_accessible_get_n_children (AtkObject *accessible) +{ + nux::Object *nux_object = NULL; + PanelView *panel; + PanelHomeButton *home_button; + gint rc = 0; + + g_return_val_if_fail (UNITY_IS_PANEL_VIEW_ACCESSIBLE (accessible), 0); + + nux_object = nux_object_accessible_get_object (NUX_OBJECT_ACCESSIBLE (accessible)); + if (!nux_object) /* state is defunct */ + return 0; + + panel = dynamic_cast<PanelView *>(nux_object); + if ((home_button = panel->HomeButton ()) != NULL) + rc = 1; + + return rc; +} + +static AtkObject * +unity_panel_view_accessible_ref_child (AtkObject *accessible, gint i) +{ + nux::Object *nux_object = NULL; + PanelView *panel; + PanelHomeButton *home_button; + AtkObject *child_accessible = NULL; + + g_return_val_if_fail (UNITY_IS_PANEL_VIEW_ACCESSIBLE (accessible), NULL); + + nux_object = nux_object_accessible_get_object (NUX_OBJECT_ACCESSIBLE (accessible)); + if (!nux_object) /* state is defunct */ + return NULL; + + panel = dynamic_cast<PanelView *>(nux_object); + if ((home_button = panel->HomeButton ()) != NULL) + { + nux::Object *child = NULL; + + child = dynamic_cast<nux::Object *>(home_button); + child_accessible = unity_a11y_get_accessible (child); + if (child_accessible != NULL) + g_object_ref (child_accessible); + } + + return child_accessible; +} diff --git a/src/unity-panel-view-accessible.h b/src/unity-panel-view-accessible.h new file mode 100644 index 000000000..921b06b20 --- /dev/null +++ b/src/unity-panel-view-accessible.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2011 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: Rodrigo Moya <rodrigo.moya@canonical.com> + */ + +#ifndef UNITY_PANEL_VIEW_ACCESSIBLE_H +#define UNITY_PANEL_VIEW_ACCESSIBLE_H + +#include <atk/atk.h> + +#include "nux-view-accessible.h" + +G_BEGIN_DECLS + +#define UNITY_TYPE_PANEL_VIEW_ACCESSIBLE (unity_panel_view_accessible_get_type ()) +#define UNITY_PANEL_VIEW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), UNITY_TYPE_PANEL_VIEW_ACCESSIBLE, UnityPanelViewAccessible)) +#define UNITY_PANEL_VIEW_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), UNITY_TYPE_PANEL_VIEW_ACCESSIBLE, UnityPanelViewAccessibleClass)) +#define UNITY_IS_PANEL_VIEW_ACCESSIBLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), UNITY_TYPE_PANEL_VIEW_ACCESSIBLE)) +#define UNITY_IS_PANEL_VIEW_ACCESSIBLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), UNITY_TYPE_PANEL_VIEW_ACCESSIBLE)) +#define UNITY_PANEL_VIEW_ACCESSIBLE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), UNITY_TYPE_PANEL_VIEW_ACCESSIBLE, UnityPanelViewAccessibleClass)) + +typedef struct _UnityPanelViewAccessible UnityPanelViewAccessible; +typedef struct _UnityPanelViewAccessibleClass UnityPanelViewAccessibleClass; + +struct _UnityPanelViewAccessible +{ + NuxViewAccessible parent; +}; + +struct _UnityPanelViewAccessibleClass +{ + NuxViewAccessibleClass parent_class; +}; + +GType unity_panel_view_accessible_get_type (void); +AtkObject *unity_panel_view_accessible_new (nux::Object *object); + +G_END_DECLS + +#endif diff --git a/src/unity-util-accessible.cpp b/src/unity-util-accessible.cpp index 821d65e44..48b70078d 100644 --- a/src/unity-util-accessible.cpp +++ b/src/unity-util-accessible.cpp @@ -109,27 +109,27 @@ add_listener (GSignalEmissionHook listener, type = g_type_from_name (object_type); if (type) - { - signal_id = g_signal_lookup (signal_name, type); - if (signal_id > 0) { - UnityUtilListenerInfo *listener_info; - - rc = listener_idx; - listener_info = g_new0 (UnityUtilListenerInfo, 1); - listener_info->idx = listener_idx; - listener_info->hook_id = g_signal_add_emission_hook (signal_id, 0, listener, - g_strdup (hook_data), - (GDestroyNotify) g_free); - listener_info->signal_id = signal_id; - - g_hash_table_insert (listener_list, &(listener_info->idx), listener_info); - - listener_idx++; + signal_id = g_signal_lookup (signal_name, type); + if (signal_id > 0) + { + UnityUtilListenerInfo *listener_info; + + rc = listener_idx; + listener_info = g_new0 (UnityUtilListenerInfo, 1); + listener_info->idx = listener_idx; + listener_info->hook_id = g_signal_add_emission_hook (signal_id, 0, listener, + g_strdup (hook_data), + (GDestroyNotify) g_free); + listener_info->signal_id = signal_id; + + g_hash_table_insert (listener_list, &(listener_info->idx), listener_info); + + listener_idx++; + } + else + g_debug ("Signal type %s not supported\n", signal_name); } - else - g_debug ("Signal type %s not supported\n", signal_name); - } else g_warning ("Invalid object type %s\n", object_type); @@ -145,19 +145,19 @@ unity_util_accessible_add_global_event_listener (GSignalEmissionHook listener, split_string = g_strsplit (event_type, ":", 3); if (split_string) - { - if (g_str_equal ("window", split_string[0])) - { - /* FIXME: need to specifically process window: events (create, destroy, - minimize, maximize, restore, activate, deactivate) */ - } - else { - rc = add_listener (listener, split_string[1], split_string[2], event_type); - } + if (g_str_equal ("window", split_string[0])) + { + /* FIXME: need to specifically process window: events (create, destroy, + minimize, maximize, restore, activate, deactivate) */ + } + else + { + rc = add_listener (listener, split_string[1], split_string[2], event_type); + } - g_strfreev (split_string); - } + g_strfreev (split_string); + } return rc; } @@ -166,27 +166,27 @@ static void unity_util_accessible_remove_global_event_listener (guint remove_listener) { if (remove_listener > 0) - { - UnityUtilListenerInfo *listener_info; - - listener_info = (UnityUtilListenerInfo *) g_hash_table_lookup (listener_list, &remove_listener); - if (listener_info != NULL) { - if (listener_info->hook_id != 0 && listener_info->signal_id != 0) - { - g_signal_remove_emission_hook (listener_info->signal_id, - listener_info->hook_id); - g_hash_table_remove (listener_list, &remove_listener); - } + UnityUtilListenerInfo *listener_info; + + listener_info = (UnityUtilListenerInfo *) g_hash_table_lookup (listener_list, &remove_listener); + if (listener_info != NULL) + { + if (listener_info->hook_id != 0 && listener_info->signal_id != 0) + { + g_signal_remove_emission_hook (listener_info->signal_id, + listener_info->hook_id); + g_hash_table_remove (listener_list, &remove_listener); + } + else + { + g_warning ("Invalid listener hook_id %ld or signal_id %d", + listener_info->hook_id, listener_info->signal_id); + } + } else - { - g_warning ("Invalid listener hook_id %ld or signal_id %d", - listener_info->hook_id, listener_info->signal_id); - } + g_warning ("No listener with the specified ID: %d", remove_listener); } - else - g_warning ("No listener with the specified ID: %d", remove_listener); - } else g_warning ("Invalid listener_id: %d", remove_listener); } diff --git a/src/unitya11y.cpp b/src/unitya11y.cpp index 358366ac0..ed66bb358 100644 --- a/src/unitya11y.cpp +++ b/src/unitya11y.cpp @@ -32,8 +32,11 @@ /* unity accessible objects */ #include "Launcher.h" #include "LauncherIcon.h" +#include "PanelView.h" #include "unity-launcher-accessible.h" #include "unity-launcher-icon-accessible.h" +#include "unity-panel-view-accessible.h" +#include "unity-panel-home-button-accessible.h" static GHashTable *accessible_table = NULL; /* FIXME: remove accessible objects when not required anymore */ @@ -243,6 +246,12 @@ unity_a11y_create_accessible (nux::Object *object) if (object->Type().IsDerivedFromType (LauncherIcon::StaticObjectType)) return unity_launcher_icon_accessible_new (object); + if (object->Type().IsDerivedFromType (PanelView::StaticObjectType)) + return unity_panel_view_accessible_new (object); + + if (object->Type().IsDerivedFromType (PanelHomeButton::StaticObjectType)) + return unity_panel_home_button_accessible_new (object); + /* NUX classes */ if (object->Type().IsDerivedFromType (nux::BaseWindow::StaticObjectType)) return nux_base_window_accessible_new (object); diff --git a/src/unityshell.cpp b/src/unityshell.cpp index 497656237..9b754c1d7 100644 --- a/src/unityshell.cpp +++ b/src/unityshell.cpp @@ -223,6 +223,28 @@ UnityScreen::showLauncherKeyTerminate (CompAction *action, } bool +UnityScreen::showPanelFirstMenuKeyInitiate (CompAction *action, + CompAction::State state, + CompOption::Vector &options) +{ + // to receive the Terminate event + if (state & CompAction::StateInitKey) + action->setState (action->state () | CompAction::StateTermKey); + + panelView->StartFirstMenuShow (); + return false; +} + +bool +UnityScreen::showPanelFirstMenuKeyTerminate (CompAction *action, + CompAction::State state, + CompOption::Vector &options) +{ + panelView->EndFirstMenuShow (); + return false; +} + +bool UnityScreen::setKeyboardFocusKeyInitiate (CompAction *action, CompAction::State state, CompOption::Vector &options) @@ -473,11 +495,34 @@ UnityScreen::optionChanged (CompOption *opt, case UnityshellOptions::UrgentAnimation: launcher->SetUrgentAnimation ((Launcher::UrgentAnimation) optionGetUrgentAnimation ()); break; + case UnityshellOptions::PanelOpacity: + panelView->SetOpacity (optionGetPanelOpacity ()); + case UnityshellOptions::AutohideAnimation: + launcher->SetAutoHideAnimation ((Launcher::AutoHideAnimation) optionGetAutohideAnimation ()); + break; default: break; } } +/* Handle changes in the number of workspaces by showing the switcher + * or not showing the switcher */ +bool +UnityScreen::setOptionForPlugin(const char *plugin, const char *name, + CompOption::Value &v) +{ + bool status; + status = screen->setOptionForPlugin (plugin, name, v); + if (status) + { + if (strcmp (plugin, "core") == 0 && strcmp (name, "hsize") == 0) + { + controller->UpdateNumWorkspaces(screen->vpSize ().width ()); + } + } + return status; +} + static gboolean write_logger_data_to_disk (gpointer data) { @@ -537,14 +582,18 @@ UnityScreen::UnityScreen (CompScreen *screen) : debugger = new DebugDBusInterface (this); - optionSetLauncherHideModeNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); - optionSetBacklightModeNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); - optionSetLaunchAnimationNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); - optionSetUrgentAnimationNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); - optionSetShowLauncherInitiate (boost::bind (&UnityScreen::showLauncherKeyInitiate, this, _1, _2, _3)); - optionSetShowLauncherTerminate (boost::bind (&UnityScreen::showLauncherKeyTerminate, this, _1, _2, _3)); - optionSetKeyboardFocusInitiate (boost::bind (&UnityScreen::setKeyboardFocusKeyInitiate, this, _1, _2, _3)); + optionSetLauncherHideModeNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); + optionSetBacklightModeNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); + optionSetLaunchAnimationNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); + optionSetUrgentAnimationNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); + optionSetPanelOpacityNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); + optionSetAutohideAnimationNotify (boost::bind (&UnityScreen::optionChanged, this, _1, _2)); + optionSetShowLauncherInitiate (boost::bind (&UnityScreen::showLauncherKeyInitiate, this, _1, _2, _3)); + optionSetShowLauncherTerminate (boost::bind (&UnityScreen::showLauncherKeyTerminate, this, _1, _2, _3)); + optionSetKeyboardFocusInitiate (boost::bind (&UnityScreen::setKeyboardFocusKeyInitiate, this, _1, _2, _3)); //optionSetKeyboardFocusTerminate (boost::bind (&UnityScreen::setKeyboardFocusKeyTerminate, this, _1, _2, _3)); + optionSetPanelFirstMenuInitiate (boost::bind (&UnityScreen::showPanelFirstMenuKeyInitiate, this, _1, _2, _3)); + optionSetPanelFirstMenuTerminate(boost::bind (&UnityScreen::showPanelFirstMenuKeyTerminate, this, _1, _2, _3)); ubus_server_register_interest (ubus_server_get_default (), UBUS_LAUNCHER_EXIT_KEY_NAV, @@ -603,7 +652,7 @@ void UnityScreen::initLauncher (nux::NThread* thread, void* InitData) self->launcherWindow->SetLayout(layout); self->launcherWindow->SetBackgroundColor(nux::Color(0x00000000)); self->launcherWindow->ShowWindow(true); - self->launcherWindow->EnableInputWindow(true); + self->launcherWindow->EnableInputWindow(true, "launcher"); self->launcherWindow->InputWindowEnableStruts(true); /* FIXME: this should not be manual, should be managed with a @@ -634,8 +683,14 @@ void UnityScreen::initLauncher (nux::NThread* thread, void* InitData) self->panelWindow->SetLayout(layout); self->panelWindow->SetBackgroundColor(nux::Color(0x00000000)); self->panelWindow->ShowWindow(true); - self->panelWindow->EnableInputWindow(true); + self->panelWindow->EnableInputWindow(true, "panel"); self->panelWindow->InputWindowEnableStruts(true); + + /* FIXME: this should not be manual, should be managed with a + show/hide callback like in GAIL*/ + if (unity_a11y_initialized () == TRUE) + unity_util_accessible_add_window (self->panelWindow); + LOGGER_END_PROCESS ("initLauncher-Panel"); /* Setup Places */ diff --git a/src/unityshell.h b/src/unityshell.h index faf5e68d8..58dc2b1c3 100644 --- a/src/unityshell.h +++ b/src/unityshell.h @@ -104,6 +104,14 @@ class UnityScreen : CompOption::Vector &options); bool + showPanelFirstMenuKeyInitiate (CompAction *action, + CompAction::State state, + CompOption::Vector &options); + bool + showPanelFirstMenuKeyTerminate (CompAction *action, + CompAction::State state, + CompOption::Vector &options); + bool setKeyboardFocusKeyInitiate (CompAction* action, CompAction::State state, CompOption::Vector& options); @@ -111,6 +119,11 @@ class UnityScreen : /* handle option changes and change settings inside of the * panel and dock views */ void optionChanged (CompOption *, Options num); + + /* Handle changes in the number of workspaces by showing the switcher + * or not showing the switcher */ + bool setOptionForPlugin(const char *plugin, const char *name, + CompOption::Value &v); /* init plugin actions for screen */ bool initPluginForScreen (CompPlugin *p); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5e4e4fa0a..6878004df 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -14,6 +14,7 @@ pkg_check_modules (TEST_UNIT_DEPS REQUIRED ${TEST_DEPS} indicator) set (CFLAGS ${TEST_UNIT_DEPS_CFLAGS} ${TEST_UNIT_DEPS_CFLAGS_OTHER} + ${MAINTAINER_CFLAGS} "-DTESTDATADIR=${TESTDATADIR}" "-DGETTEXT_PACKAGE=\"unity\"" "-DINDICATORDIR=\"${CMAKE_BINARY_DIR}/tests\"" @@ -75,6 +76,8 @@ add_executable (test-unit add_executable (test-panel TestPanel.cpp + ../src/PanelStyle.cpp + ../src/PanelStyle.h ../src/PanelView.cpp ../src/PanelView.h ../src/PanelIndicatorObjectView.cpp @@ -83,6 +86,8 @@ add_executable (test-panel ../src/PanelIndicatorObjectEntryView.h ../src/PanelTitlebarGrabAreaView.h ../src/PanelTitlebarGrabAreaView.cpp + ../src/PanelTray.cpp + ../src/PanelTray.h ../src/IndicatorObjectFactory.h ../src/IndicatorObjectProxy.h ../src/IndicatorObjectEntryProxy.h @@ -132,6 +137,8 @@ add_executable (test-places ../src/PlacesGroup.h ../src/PlacesView.cpp ../src/PlacesView.h + ../src/TextureCache.h + ../src/TextureCache.cpp ../src/UBusMessages.h ../src/Introspectable.cpp ../src/Introspectable.h @@ -167,6 +174,8 @@ add_executable (test-places-tiles ../src/IconTexture.h ../src/Introspectable.cpp ../src/Introspectable.h + ../src/TextureCache.h + ../src/TextureCache.cpp ) @@ -186,6 +195,8 @@ add_executable (test-places-group ../src/PlacesTile.h ../src/PlacesSimpleTile.cpp ../src/PlacesSimpleTile.h + ../src/TextureCache.h + ../src/TextureCache.cpp ) add_executable (test-places-results @@ -208,6 +219,8 @@ add_executable (test-places-results ../src/Introspectable.h ../src/StaticCairoText.cpp ../src/StaticCairoText.h + ../src/TextureCache.h + ../src/TextureCache.cpp ) add_executable (test-quicklist diff --git a/tests/TestPanel.cpp b/tests/TestPanel.cpp index 98be4284a..7e3cd1c07 100644 --- a/tests/TestPanel.cpp +++ b/tests/TestPanel.cpp @@ -33,8 +33,8 @@ void ThreadWidgetInit(nux::NThread* thread, void* InitData) nux::VLayout *layout = new nux::VLayout(TEXT(""), NUX_TRACKER_LOCATION); PanelView *view = new PanelView (); - view->SetMinMaxSize(1024, 24); - layout->AddView(view, 1, nux::eCenter, nux::eFix); + //view->SetMinMaxSize(1024, 24); + layout->AddView(view, 1, nux::eCenter, nux::eFull); layout->SetContentDistribution(nux::eStackCenter); nux::GetGraphicsThread()->SetLayout (layout); diff --git a/tests/TestPlacesGroup.cpp b/tests/TestPlacesGroup.cpp index abadd659c..a1965c40e 100644 --- a/tests/TestPlacesGroup.cpp +++ b/tests/TestPlacesGroup.cpp @@ -134,8 +134,9 @@ ControlThread (nux::NThread* thread, nux::SleepForMilliseconds (3000); printf ("ControlThread successfully started\n"); - nux::WindowThread* mainWindowThread = NUX_STATIC_CAST (nux::WindowThread*, - data); + nux::WindowThread* mainWindowThread; + + mainWindowThread = NUX_STATIC_CAST (nux::WindowThread*, data); } diff --git a/tests/TestPlacesResults.cpp b/tests/TestPlacesResults.cpp index 18eb2491a..f4953c138 100644 --- a/tests/TestPlacesResults.cpp +++ b/tests/TestPlacesResults.cpp @@ -135,8 +135,9 @@ ControlThread (nux::NThread* thread, nux::SleepForMilliseconds (3000); printf ("ControlThread successfully started\n"); - nux::WindowThread* mainWindowThread = NUX_STATIC_CAST (nux::WindowThread*, - data); + nux::WindowThread* mainWindowThread; + + mainWindowThread = NUX_STATIC_CAST (nux::WindowThread*, data); } diff --git a/tests/TestPlacesTiles.cpp b/tests/TestPlacesTiles.cpp index 64a627044..ab8d2f427 100644 --- a/tests/TestPlacesTiles.cpp +++ b/tests/TestPlacesTiles.cpp @@ -83,8 +83,9 @@ ControlThread (nux::NThread* thread, nux::SleepForMilliseconds (3000); printf ("ControlThread successfully started\n"); - nux::WindowThread* mainWindowThread = NUX_STATIC_CAST (nux::WindowThread*, - data); + nux::WindowThread* mainWindowThread; + + mainWindowThread = NUX_STATIC_CAST (nux::WindowThread*, data); } diff --git a/tools/autopilot.py b/tools/autopilot.py index f6978c827..459a52e9d 100755 --- a/tools/autopilot.py +++ b/tools/autopilot.py @@ -31,206 +31,204 @@ class UnityUtil(object): INTROSPECTION_IFACE = 'com.canonical.Unity.Debug.Introspection' def __init__(self): - self._bus = dbus.SessionBus() - self._introspection_proxy_obj = self._bus.get_object(self.UNITY_BUS_NAME, self.INTROSPECTION_PATH) - self._introspection_iface = dbus.Interface(self._introspection_proxy_obj, - self.INTROSPECTION_IFACE) + self._bus = dbus.SessionBus() + self._introspection_proxy_obj = self._bus.get_object(self.UNITY_BUS_NAME, self.INTROSPECTION_PATH) + self._introspection_iface = dbus.Interface(self._introspection_proxy_obj, + self.INTROSPECTION_IFACE) def run_unity(self): - ''' Runs unity with --reset to ensure that a default Unity/compiz session - is being tested. If unity --reset does not return 0, a CalledProcessError - will be raised. No exception does not mean that everything is ok, is_running - should still be called after.''' - ret = subprocess.check_call ('unity', '--reset') - - + ''' Runs unity with --reset to ensure that a default Unity/compiz session + is being tested. If unity --reset does not return 0, a CalledProcessError + will be raised. No exception does not mean that everything is ok, is_running + should still be called after.''' + ret = subprocess.check_call ('unity', '--reset') + def is_running(self): - '''Checks if Unity is running by examing the session bus, and checking if - 'com.canonical.Unity' is currently owned.''' - return self._bus.name_has_owner(self.UNITY_BUS_NAME) - + '''Checks if Unity is running by examing the session bus, and checking if + 'com.canonical.Unity' is currently owned.''' + return self._bus.name_has_owner(self.UNITY_BUS_NAME) + class Mouse(object): - '''Wrapper around xlib to make moving the mouse easier''' + '''Wrapper around xlib to make moving the mouse easier''' - def __init__(self): - self._display = Display() + def __init__(self): + self._display = Display() - def press(self, button=1): - '''Press mouse button at current mouse location''' - fake_input(self._display, X.ButtonPress, button) - self._display.sync() + def press(self, button=1): + '''Press mouse button at current mouse location''' + fake_input(self._display, X.ButtonPress, button) + self._display.sync() - def release(self, button=1): - '''Releases mouse button at current mouse location''' - fake_input(self._display, X.ButtonRelease, button) - self._display.sync() + def release(self, button=1): + '''Releases mouse button at current mouse location''' + fake_input(self._display, X.ButtonRelease, button) + self._display.sync() - def click(self, button=1): - '''Click mouse at current location''' - self.press(button) - sleep(0.25) - self.release(button) + def click(self, button=1): + '''Click mouse at current location''' + self.press(button) + sleep(0.25) + self.release(button) - def move(self, x, y): - '''Moves mouse to location (x, y)''' - def perform_move(x, y): - fake_input(self._display, X.MotionNotify, x=x, y=y) - self._display.sync() - sleep(0.001) + def move(self, x, y): + '''Moves mouse to location (x, y)''' + def perform_move(x, y): + fake_input(self._display, X.MotionNotify, x=x, y=y) + self._display.sync() + sleep(0.001) - dest_x, dest_y = x, y - curr_x, curr_y = self.position() - - # calculate a path from our current position to our destination - dy = float(curr_y - dest_y) - dx = float(curr_x - dest_x) - slope = dy/dx if dx > 0 else 0 - yint = curr_y - (slope * curr_x) - xscale = 1 if dest_x > curr_x else -1 + dest_x, dest_y = x, y + curr_x, curr_y = self.position() - while (int(curr_x) != dest_x): - curr_x += xscale; - curr_y = int(slope * curr_x + yint) if curr_y > 0 else dest_y + # calculate a path from our current position to our destination + dy = float(curr_y - dest_y) + dx = float(curr_x - dest_x) + slope = dy/dx if dx > 0 else 0 + yint = curr_y - (slope * curr_x) + xscale = 1 if dest_x > curr_x else -1 + + while (int(curr_x) != dest_x): + curr_x += xscale; + curr_y = int(slope * curr_x + yint) if curr_y > 0 else dest_y - perform_move(curr_x, curr_y) + perform_move(curr_x, curr_y) - if (curr_y != dest_y): - yscale = 1 if dest_y > curr_y else -1 - while (curr_y != dest_y): - curr_y += yscale - perform_move(curr_x, curr_y) + if (curr_y != dest_y): + yscale = 1 if dest_y > curr_y else -1 + while (curr_y != dest_y): + curr_y += yscale + perform_move(curr_x, curr_y) - - def position(self): - '''Returns the current position of the mouse pointer''' - coord = self._display.screen().root.query_pointer()._data - x, y = coord["root_x"], coord["root_y"] - return x, y + def position(self): + '''Returns the current position of the mouse pointer''' + coord = self._display.screen().root.query_pointer()._data + x, y = coord["root_x"], coord["root_y"] + return x, y - def reset(self): - fake_input (self._display, X.MotionNotify, x = 800, y = 500) - self._display.sync() + def reset(self): + fake_input (self._display, X.MotionNotify, x = 800, y = 500) + self._display.sync() class UnityTests(object): - '''Runs a series of unity actions, triggering GL calls''' + '''Runs a series of unity actions, triggering GL calls''' - _bfb_x = 24 - _bfb_y = 10 - - # this is totally lame. This should not be hard coded, but until I can get - # unity to run in gdb and debug why introspection is crashing and hardlocking - # this is the best I can do. - _dest_x = 32 - _dest_y = 57 + _bfb_x = 24 + _bfb_y = 10 - def __init__(self): - self._mouse = Mouse() - self._unity = UnityUtil() + # this is totally lame. This should not be hard coded, but until I can get + # unity to run in gdb and debug why introspection is crashing and hardlocking + # this is the best I can do. + _dest_x = 32 + _dest_y = 57 + + def __init__(self): + self._mouse = Mouse() + self._unity = UnityUtil() - def show_tooltip(self): - '''Move mouse to a launcher and hover to show the tooltip''' - print 'Showing tool tip...' - self._mouse.reset() - self._mouse.move (self._bfb_x, self._bfb_y) - sleep (0.25) - self._mouse.move(self._dest_x, self._dest_y) - return self._unity.is_running() + def show_tooltip(self): + '''Move mouse to a launcher and hover to show the tooltip''' + print 'Showing tool tip...' + self._mouse.reset() + self._mouse.move (self._bfb_x, self._bfb_y) + sleep (0.25) + self._mouse.move(self._dest_x, self._dest_y) + return self._unity.is_running() - def show_quicklist(self): - '''Move mouse to a launcher and right click''' - print 'Showing quicklist...' - self._mouse.reset() - self._mouse.move (self._bfb_x, self._bfb_y) - sleep (0.25) - self._mouse.move(self._dest_x, self._dest_y) - sleep(0.25) - self._mouse.click(button=3) - sleep(2) - # hides quicklist - self._mouse.click(button=3) - return self._unity.is_running() + def show_quicklist(self): + '''Move mouse to a launcher and right click''' + print 'Showing quicklist...' + self._mouse.reset() + self._mouse.move (self._bfb_x, self._bfb_y) + sleep (0.25) + self._mouse.move(self._dest_x, self._dest_y) + sleep(0.25) + self._mouse.click(button=3) + sleep(2) + # hides quicklist + self._mouse.click(button=3) + return self._unity.is_running() - def drag_launcher(self): - '''Click a launcher icon and drag down to move the whole launcher''' - print 'Dragging entire launcher...' - self._mouse.reset() - self._mouse.move (self._bfb_x, self._bfb_y) - sleep (0.25) - self._mouse.move(self._dest_x, self._dest_y) - sleep(0.25) - print self._mouse.position() - print 'pressing' - self._mouse.press() - self._mouse.move(self._dest_x, self._dest_y + 300) - sleep(0.25) - print 'releasing' - self._mouse.release() - return self._unity.is_running() + def drag_launcher(self): + '''Click a launcher icon and drag down to move the whole launcher''' + print 'Dragging entire launcher...' + self._mouse.reset() + self._mouse.move (self._bfb_x, self._bfb_y) + sleep (0.25) + self._mouse.move(self._dest_x, self._dest_y) + sleep(0.25) + print self._mouse.position() + print 'pressing' + self._mouse.press() + self._mouse.move(self._dest_x, self._dest_y + 300) + sleep(0.25) + print 'releasing' + self._mouse.release() + return self._unity.is_running() - def drag_launcher_icon_along_edge_drop(self): - '''Click a launcher icon and drag it along the edge of the launcher - to test moving icons around on the launcher''' - print 'Moving launcher icon along edge...' - self._mouse.reset() - self._mouse.move (self._bfb_x, self._bfb_y) - sleep (0.25) - self._mouse.move(self._dest_x, self._dest_y) - self._mouse.press() - self._mouse.move(self._dest_x + 25, self._dest_y) - self._mouse.move(self._dest_x + 25, self._dest_y + 500) - self._mouse.release() - return self._unity.is_running() + def drag_launcher_icon_along_edge_drop(self): + '''Click a launcher icon and drag it along the edge of the launcher + to test moving icons around on the launcher''' + print 'Moving launcher icon along edge...' + self._mouse.reset() + self._mouse.move (self._bfb_x, self._bfb_y) + sleep (0.25) + self._mouse.move(self._dest_x, self._dest_y) + self._mouse.press() + self._mouse.move(self._dest_x + 25, self._dest_y) + self._mouse.move(self._dest_x + 25, self._dest_y + 500) + self._mouse.release() + return self._unity.is_running() - def drag_launcher_icon_out_and_drop(self): - '''Click a launcher icon and drag it straight out so that when dropped - it returns to its original position''' - print 'Dragging launcher straight out and dropping...' - self._mouse.reset() - self._mouse.move (self._bfb_x, self._bfb_y) - sleep (0.25) - self._mouse.move(self._dest_x, self._dest_y) - self._mouse.press() - self._mouse.move(self._dest_x + 300, self._dest_y) - self._mouse.release() - return self._unity.is_running() + def drag_launcher_icon_out_and_drop(self): + '''Click a launcher icon and drag it straight out so that when dropped + it returns to its original position''' + print 'Dragging launcher straight out and dropping...' + self._mouse.reset() + self._mouse.move (self._bfb_x, self._bfb_y) + sleep (0.25) + self._mouse.move(self._dest_x, self._dest_y) + self._mouse.press() + self._mouse.move(self._dest_x + 300, self._dest_y) + self._mouse.release() + return self._unity.is_running() - def drag_launcher_icon_out_and_move(self): - '''Click a launcher icon and drag it diagonally so that it changes position''' - print 'Dragging a launcher icon out, and moving it...''' - self._mouse.reset() - self._mouse.move (self._bfb_x, self._bfb_y) - sleep (0.25) - self._mouse.move(self._dest_x, self._dest_y) - self._mouse.press() - self._mouse.move(self._dest_x + 300, self._dest_y) - self._mouse.move(self._dest_x + 300, self._dest_y + 300) - self._mouse.release() - return self._unity.is_running() + def drag_launcher_icon_out_and_move(self): + '''Click a launcher icon and drag it diagonally so that it changes position''' + print 'Dragging a launcher icon out, and moving it...''' + self._mouse.reset() + self._mouse.move (self._bfb_x, self._bfb_y) + sleep (0.25) + self._mouse.move(self._dest_x, self._dest_y) + self._mouse.press() + self._mouse.move(self._dest_x + 300, self._dest_y) + self._mouse.move(self._dest_x + 300, self._dest_y + 300) + self._mouse.release() + return self._unity.is_running() if __name__ == "__main__": - tests = UnityTests() - if (not tests.show_tooltip()): - print 'FAIL: SHOW TOOLTIP CRASHED UNITY' - exit (1) - sleep(1.5) - if (not tests.show_quicklist()): - print 'FAIL: SHOW QUICKLIST CRASHED UNITY' - exit (1) - sleep(1.5) - if (not tests.drag_launcher()): - print 'FAIL: DRAG LAUNCHER CRASHED UNITY' - exit (1) - sleep(1.5) - if (not tests.drag_launcher_icon_along_edge_drop()): - print 'FAIL: DRAG LAUNCHER ICON ALONG EDGE CRASHED UNITY' - exit (1) - sleep(1.5) - if (not tests.drag_launcher_icon_out_and_drop()): - print 'FAIL: DRAG LAUNCHER ICON OUT AND DROP CRASHED UNITY' - exit (1) - sleep(1.5) - if (not tests.drag_launcher_icon_out_and_move()): - print 'FAIL: DRAG LAUNCHER ICON OUT AND MOVE CRASHED UNITY' - exit (1) + tests = UnityTests() + if (not tests.show_tooltip()): + print 'FAIL: SHOW TOOLTIP CRASHED UNITY' + exit (1) + sleep(1.5) + if (not tests.show_quicklist()): + print 'FAIL: SHOW QUICKLIST CRASHED UNITY' + exit (1) + sleep(1.5) + if (not tests.drag_launcher()): + print 'FAIL: DRAG LAUNCHER CRASHED UNITY' + exit (1) + sleep(1.5) + if (not tests.drag_launcher_icon_along_edge_drop()): + print 'FAIL: DRAG LAUNCHER ICON ALONG EDGE CRASHED UNITY' + exit (1) + sleep(1.5) + if (not tests.drag_launcher_icon_out_and_drop()): + print 'FAIL: DRAG LAUNCHER ICON OUT AND DROP CRASHED UNITY' + exit (1) + sleep(1.5) + if (not tests.drag_launcher_icon_out_and_move()): + print 'FAIL: DRAG LAUNCHER ICON OUT AND MOVE CRASHED UNITY' + exit (1) - print 'PASS' + print 'PASS' diff --git a/tools/migrate_favorites.py b/tools/migrate_favorites.py index b7fa791ee..7fae599fa 100755 --- a/tools/migrate_favorites.py +++ b/tools/migrate_favorites.py @@ -171,7 +171,7 @@ if migration_level < '3.2.0': migrating_chapter_log("unity mutter", apps_list, unity_mutter_favorites_list, log_file) for candidate in unity_mutter_favorites_list: candidate_path = '/desktop/unity/launcher/favorites/%s' % candidate - if (client.get_string('%s/type' % candidate_path) == 'application'): + if (candidate and client.get_string('%s/type' % candidate_path) == 'application'): launcher_location = client.get_string('%s/desktop_file' % candidate_path) position = client.get_string('%s/desktop_file' % candidate_path) if launcher_location: @@ -186,7 +186,7 @@ if migration_level < '3.2.0': migrating_chapter_log("netbook-launcher favorites", apps_list, lucid_favorites_list, log_file) for candidate in lucid_favorites_list: candidate_path = '/apps/netbook-launcher/favorites/%s' % candidate - if (client.get_string('%s/type' % candidate_path) == 'application'): + if (candidate and client.get_string('%s/type' % candidate_path) == 'application'): launcher_location = client.get_string('%s/desktop_file' % candidate_path) if launcher_location: apps_list = register_new_app(launcher_location, apps_list, log_file) @@ -197,7 +197,7 @@ if migration_level < '3.2.0': migrating_chapter_log("gnome-panel items", apps_list, candidate_objects, log_file) for candidate in candidate_objects: candidate_path = '/apps/panel/objects/%s' % candidate - if (client.get_string('%s/object_type' % candidate_path) == 'launcher-object' + if (candidate and client.get_string('%s/object_type' % candidate_path) == 'launcher-object' and client.get_string('%s/toplevel_id' % candidate_path) in panel_list): launcher_location = client.get_string('%s/launcher_location' % candidate_path) if launcher_location: diff --git a/unityshell.xml.in b/unityshell.xml.in index c2793b8b4..7e2ceb56b 100644 --- a/unityshell.xml.in +++ b/unityshell.xml.in @@ -68,11 +68,15 @@ <default><Super></default> </option> <option name="keyboard_focus" type="key"> - <_short>Key to put keyboard-focus on launcher</_short> - <_long>Set the keyboard-focus on the launcher so it can be navigated with the cursor-keys</_long> - <default><Alt>F1</default> + <_short>Key to put keyboard-focus on launcher</_short> + <_long>Set the keyboard-focus on the launcher so it can be navigated with the cursor-keys</_long> + <default><Alt>F1</default> </option> - </group> + <option name="panel_first_menu" type="key"> + <_short>Key to open the first panel menu</_short> + <_long>Open the first menu on the panel, allowing keyboard navigation thereafter.</_long> + <default>F10</default> + </option> </group> <group> <_short>Experimental</_short> <option name="backlight_mode" type="int"> @@ -132,6 +136,33 @@ <_name>Wiggle</_name> </desc> </option> + <option type="float" name="panel_opacity"> + <_short>Panel Opacity</_short> + <_long>The opacity of the Panel background.</_long> + <default>1.0</default> + <min>0.0</min> + <max>1.0</max> + <precision>0.01</precision> + </option> + <option name="autohide_animation" type="int"> + <_short>Hide Animation</_short> + <_long>Animation played when the launcher is showing or hiding</_long> + <min>0</min> + <max>2</max> + <default>0</default> + <desc> + <value>0</value> + <_name>Fade on bfb and Slide</_name> + </desc> + <desc> + <value>1</value> + <_name>Side only</_name> + </desc> + <desc> + <value>2</value> + <_name>Fade only</_name> + </desc> + </option> </group> </options> </plugin> |
