summaryrefslogtreecommitdiff
diff options
authorNeil Jagdish Patel <neil.patel@canonical.com>2011-02-17 11:04:21 +0000
committerNeil Jagdish Patel <neil.patel@canonical.com>2011-02-17 11:04:21 +0000
commit24c40d99b0d4fd0fa2bf217720e9130f14b0f658 (patch)
treef50c73b5f3b08c3c43c568fa79a9c5961dea6925
parent463155142a7407dec8b53bad89a9dc07d76fb1cb (diff)
parentc9beb6e389cf368f5c75a6e4e65d4593e726a780 (diff)
[merge] Panel fixes
(bzr r867)
-rw-r--r--CMakeLists.txt2
-rw-r--r--com.canonical.Unity.gschema.xml7
-rw-r--r--services/panel-service.c13
-rw-r--r--src/PanelHomeButton.cpp18
-rw-r--r--src/PanelHomeButton.h1
-rw-r--r--src/PanelIndicatorObjectEntryView.cpp84
-rw-r--r--src/PanelIndicatorObjectView.cpp10
-rw-r--r--src/PanelMenuView.cpp85
-rw-r--r--src/PanelMenuView.h1
-rw-r--r--src/PanelStyle.cpp274
-rw-r--r--src/PanelStyle.h79
-rw-r--r--src/PanelTray.cpp231
-rw-r--r--src/PanelTray.h73
-rw-r--r--src/PanelView.cpp167
-rw-r--r--src/PanelView.h23
-rw-r--r--src/WindowButtons.cpp90
-rw-r--r--src/unityshell.cpp41
-rw-r--r--src/unityshell.h8
-rw-r--r--tests/CMakeLists.txt4
-rw-r--r--tests/TestPanel.cpp4
-rw-r--r--unityshell.xml.in20
21 files changed, 1038 insertions, 197 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7ba79be9d..ecc0b8cd2 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -88,7 +88,7 @@ endif (BOOT_LOGGER)
#
# 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)
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/services/panel-service.c b/services/panel-service.c
index 00f88765f..99ec9a2e0 100644
--- a/services/panel-service.c
+++ b/services/panel-service.c
@@ -963,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))
{
@@ -975,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;
@@ -1016,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/src/PanelHomeButton.cpp b/src/PanelHomeButton.cpp
index 84a2a7958..17ecb0236 100644
--- a/src/PanelHomeButton.cpp
+++ b/src/PanelHomeButton.cpp
@@ -32,6 +32,8 @@
#include <pango/pangocairo.h>
#include <gtk/gtk.h>
+#include "PanelStyle.h"
+
#define PANEL_HEIGHT 24
#define BUTTON_WIDTH 66
@@ -41,7 +43,6 @@ 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));
@@ -51,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
@@ -64,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);
@@ -102,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.
);
@@ -205,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 90b6712a4..ed0044f91 100644
--- a/src/PanelHomeButton.h
+++ b/src/PanelHomeButton.h
@@ -51,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 ed4ac7305..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)
{
@@ -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 (x+text_width >= width-1)
- {
- linpat = cairo_pattern_create_linear (x, y-1, width-1, 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 (x+text_width >= width-1)
{
linpat = cairo_pattern_create_linear (x, y, width-1, 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);
+ 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);
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 79b629473..feac1d762 100644
--- a/src/PanelView.cpp
+++ b/src/PanelView.cpp
@@ -32,6 +32,7 @@
#include <glib.h>
#include "PanelView.h"
+#include "PanelStyle.h"
#include "IndicatorObjectFactoryRemote.h"
#include "PanelIndicatorObjectView.h"
@@ -39,8 +40,13 @@
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);
@@ -55,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));
@@ -64,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";
@@ -152,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);
@@ -185,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 ();
}
@@ -307,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 c58eee27e..3876c1140 100644
--- a/src/PanelView.h
+++ b/src/PanelView.h
@@ -24,10 +24,14 @@
#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
{
@@ -50,6 +54,13 @@ public:
PanelHomeButton * HomeButton ();
+ void StartFirstMenuShow ();
+ void EndFirstMenuShow ();
+
+ Window GetTrayWindow ();
+
+ void SetOpacity (float opacity);
+
protected:
// Introspectable methods
const gchar * GetName ();
@@ -58,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/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/unityshell.cpp b/src/unityshell.cpp
index c7a504181..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,6 +495,8 @@ 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;
@@ -558,15 +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));
+ 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));
+ 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,
diff --git a/src/unityshell.h b/src/unityshell.h
index 25a98ff93..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);
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 5e4e4fa0a..2b3725ea0 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -75,6 +75,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 +85,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
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/unityshell.xml.in b/unityshell.xml.in
index 63700919f..7e2ceb56b 100644
--- a/unityshell.xml.in
+++ b/unityshell.xml.in
@@ -68,11 +68,15 @@
<default>&lt;Super&gt;</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>&lt;Alt&gt;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>&lt;Alt&gt;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,14 @@
<_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>