diff options
| author | Neil Jagdish Patel <neil.patel@canonical.com> | 2011-02-17 11:04:21 +0000 |
|---|---|---|
| committer | Neil Jagdish Patel <neil.patel@canonical.com> | 2011-02-17 11:04:21 +0000 |
| commit | 24c40d99b0d4fd0fa2bf217720e9130f14b0f658 (patch) | |
| tree | f50c73b5f3b08c3c43c568fa79a9c5961dea6925 | |
| parent | 463155142a7407dec8b53bad89a9dc07d76fb1cb (diff) | |
| parent | c9beb6e389cf368f5c75a6e4e65d4593e726a780 (diff) | |
[merge] Panel fixes
(bzr r867)
| -rw-r--r-- | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | com.canonical.Unity.gschema.xml | 7 | ||||
| -rw-r--r-- | services/panel-service.c | 13 | ||||
| -rw-r--r-- | src/PanelHomeButton.cpp | 18 | ||||
| -rw-r--r-- | src/PanelHomeButton.h | 1 | ||||
| -rw-r--r-- | src/PanelIndicatorObjectEntryView.cpp | 84 | ||||
| -rw-r--r-- | src/PanelIndicatorObjectView.cpp | 10 | ||||
| -rw-r--r-- | src/PanelMenuView.cpp | 85 | ||||
| -rw-r--r-- | src/PanelMenuView.h | 1 | ||||
| -rw-r--r-- | src/PanelStyle.cpp | 274 | ||||
| -rw-r--r-- | src/PanelStyle.h | 79 | ||||
| -rw-r--r-- | src/PanelTray.cpp | 231 | ||||
| -rw-r--r-- | src/PanelTray.h | 73 | ||||
| -rw-r--r-- | src/PanelView.cpp | 167 | ||||
| -rw-r--r-- | src/PanelView.h | 23 | ||||
| -rw-r--r-- | src/WindowButtons.cpp | 90 | ||||
| -rw-r--r-- | src/unityshell.cpp | 41 | ||||
| -rw-r--r-- | src/unityshell.h | 8 | ||||
| -rw-r--r-- | tests/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | tests/TestPanel.cpp | 4 | ||||
| -rw-r--r-- | unityshell.xml.in | 20 |
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><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,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> |
