Merge lp:~renatofilho/unity/unity-lp876017 into lp:unity

Proposed by Renato Araujo Oliveira Filho
Status: Merged
Approved by: Renato Araujo Oliveira Filho
Approved revision: no longer in the source branch.
Merged at revision: 2650
Proposed branch: lp:~renatofilho/unity/unity-lp876017
Merge into: lp:unity
Diff against target: 729 lines (+507/-31)
6 files modified
CMakeLists.txt (+1/-2)
plugins/unityshell/CMakeLists.txt (+1/-1)
plugins/unityshell/src/unityshell.cpp (+428/-0)
plugins/unityshell/src/unityshell.h (+39/-1)
unity-shared/PanelStyle.cpp (+37/-27)
unity-shared/PanelStyle.h (+1/-0)
To merge this branch: bzr merge lp:~renatofilho/unity/unity-lp876017
Reviewer Review Type Date Requested Status
Sam Spilsbury (community) Approve
Review via email: mp+120450@code.launchpad.net

Commit message

UnityWindow now implements ScaleWindowInterface.
Implemented support to close window during the scale plugin.
Fake windows decoration rendering using panel code as base.

Description of the change

UnityWindow now implements ScaleWindowInterface.
Implemented support to close window during the scale plugin.
Fake windows decoration rendering using panel code as base.

To post a comment you must log in.
Revision history for this message
Sam Spilsbury (smspillaz) wrote :
Download full text (3.7 KiB)

Right approach, some pointers:

76 +// Based on Scale plugin code
77 +CompWindow* UnityScreen::checkForWindowAt (int x, int y)
78 +{
79 + int x1, y1, x2, y2;
80 + CompWindowList::reverse_iterator rit = screen->windows ().rbegin ();
81 +
82 + for (; rit != screen->windows ().rend (); ++rit)
83 + {
84 + CompWindow *w = *rit;
85 + SCALE_WINDOW (w);
86 +
87 + ScalePosition pos = sw->getCurrentPosition ();
88 + if (sw->hasSlot ())
89 + {
90 + x1 = w->x () - w->input ().left * pos.scale;
91 + y1 = w->y () - w->input ().top * pos.scale;
92 + x2 = w->x () + (w->width () + w->input ().right) * pos.scale;
93 + y2 = w->y () + (w->height () + w->input ().bottom) * pos.scale;
94 + x1 += pos.x ();
95 + y1 += pos.y ();
96 + x2 += pos.x ();
97 + y2 += pos.y ();
98 + if (x1 <= x && y1 <= y && x2 > x && y2 > y)
99 + return w;
100 + }
101 + }
102 + return NULL;
103 +}

Is this necessary?

I think you can just overload scaleSelectWindow to determine what the currently hovered window is. From there you will need to damage and re-render both the new and old window. Have a look at the scaleaddon plugin.

151 + gWindow->geometry ().reset ();
152 + if (width && height)
153 + gWindow->glAddGeometry (ml, iconReg, iconReg);
154 +
155 + if (gWindow->geometry ().vCount)
156 + {
157 + GLFragment::Attrib fragment (attrib);
158 + GLMatrix wTransform (transform);
159 +
160 + wTransform.translate (x, y, 0.0f);
161 +
162 + glPushMatrix ();
163 + glLoadMatrixf (wTransform.getMatrix ());
164 + gWindow->glDrawTexture (icon, fragment, mask);
165 + glPopMatrix ();
166 + }

You will need to put this inside of #if USE_MODERN_COMPIZ_GL ifdefs. Sorry :( Here's how to do it:

#ifdef USE_MODERN_COMPIZ_GL
gWindow->vertexBuffer ()->begin ();
#else
151 + gWindow->geometry ().reset ();
#endif
152 + if (width && height)
153 + gWindow->glAddGeometry (ml, iconReg, iconReg);
154 +
#ifdef USE_MODERN_COMPIZ_GL
gWindow->vertexBuffer ().end ();
if (gWindow->vertexBuffer ().countVertices ())
#else
155 + if (gWindow->geometry ().vCount)
#endif
156 + {
#ifdef USE_MODERN_COMPIZ_GL
157 + GLFragment::Attrib fragment (attrib);
#endif
158 + GLMatrix wTransform (transform);
159 +
160 + wTransform.translate (x, y, 0.0f);
161 +
#ifdef USE_MODERN_COMPIZ_GL
gWindow->glDrawTexture (icon, wTransform, attrib, mask);
#else
162 + glPushMatrix ();
163 + glLoadMatrixf (wTransform.getMatrix ());
164 + gWindow->glDrawTexture (icon, fragment, mask);
165 + glPopMatrix ();
#endif
166 + }

172 + // BG
173 + glColor3f (0.0f, 0.0f, 0.0f);
174 + glRectf (x, y2, x2, y);

Preferably use client side buffers for this, eg

#ifndef USE_MODERN_COMPIZ_GL
172 + // BG
173 + glColor3f (0.0f, 0.0f, 0.0f);
174 + glRectf (x, y2, x2, y);
#else
GLVertexBuffer *vertexBuffer = GLVertexBuffer::streamingBuffer ();
vertexBuffer->begin (GL_TRIANGLE_STRIP)
const GLfloat vertices[] =
{
    x, y2, 0.0f,
    x, y, 0.0f,
    x2, y, 0.0f,
    x2, y2, 0.0f
};

vertexBuffer->addVertices (4, vertices);
vertexBuffer->color4f (0.0f, 0.0f, 0.0f, 1.0f);
vertexBuffer->end ();
vertexBuffer->render (transform, attrib);

209 + x + CLOSE_ICON_SPACE, iconY,
210 + maxWidth , maxHeight);

Make this a constant

190 + if (!sWindow->hasSlot() || // animation finished
191 + ...

Read more...

review: Needs Fixing
Revision history for this message
Renato Araujo Oliveira Filho (renatofilho) wrote :

> I think you can just overload scaleSelectWindow to determine what the
> currently hovered window is. From there you will need to damage and re-render
> both the new and old window. Have a look at the scaleaddon plugin.
> #ifdef USE_MODERN_COMPIZ_GL
> gWindow->vertexBuffer ()->begin ();
> #else
> 151 + gWindow->geometry ().reset ();
> #endif
> 152 + if (width && height)
> 153 + gWindow->glAddGeometry (ml, iconReg, iconReg);
> 154 +
> #ifdef USE_MODERN_COMPIZ_GL
> gWindow->vertexBuffer ().end ();
> if (gWindow->vertexBuffer ().countVertices ())
> #else
> 155 + if (gWindow->geometry ().vCount)
> #endif
> 156 + {
> #ifdef USE_MODERN_COMPIZ_GL
> 157 + GLFragment::Attrib fragment (attrib);
> #endif
> 158 + GLMatrix wTransform (transform);
> 159 +
> 160 + wTransform.translate (x, y, 0.0f);
> 161 +
> #ifdef USE_MODERN_COMPIZ_GL
> gWindow->glDrawTexture (icon, wTransform, attrib, mask);
> #else
> 162 + glPushMatrix ();
> 163 + glLoadMatrixf (wTransform.getMatrix ());
> 164 + gWindow->glDrawTexture (icon, fragment, mask);
> 165 + glPopMatrix ();
> #endif
> 166 + }
Fixed on rev: 2577
I have implemented the "scaleSelectWindow" based on scaleaddon plugin, but I did not understand why I need this code. (The implementation is working well without this)

>
> 172 + // BG
> 173 + glColor3f (0.0f, 0.0f, 0.0f);
> 174 + glRectf (x, y2, x2, y);
>
> Preferably use client side buffers for this
Fixed on rev: 2574
Thanks for the example code.

> Make this a constant
Fixed on rev: 2575

>
> Also avoid the 65535, use OPAQUE
Fixed on rev: 2576

>
> 121 + CompString name (PKGDATADIR"/close_dash.png");
>
> Is that the correct asset?
Based on designer docs, yes this is the correct icon.

>
> That needs to be under test.
Any suggestion or example how to test it?

Revision history for this message
Renato Araujo Oliveira Filho (renatofilho) wrote :

> > That needs to be under test.
My suggestion to make the code testable is split unityshell.(h/cpp) file into different files (UnityWindow/UnityWindowPrivate, UntiyScree/UnityScreenPrivate and UnityShell), with this we can instantiate only the private class inside of the tests and call/test the "private" functions.

What do you think?

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

> > I think you can just overload scaleSelectWindow to determine what the
> > currently hovered window is. From there you will need to damage and re-
> render
> > both the new and old window. Have a look at the scaleaddon plugin.
> > #ifdef USE_MODERN_COMPIZ_GL
> > gWindow->vertexBuffer ()->begin ();
> > #else
> > 151 + gWindow->geometry ().reset ();
> > #endif
> > 152 + if (width && height)
> > 153 + gWindow->glAddGeometry (ml, iconReg, iconReg);
> > 154 +
> > #ifdef USE_MODERN_COMPIZ_GL
> > gWindow->vertexBuffer ().end ();
> > if (gWindow->vertexBuffer ().countVertices ())
> > #else
> > 155 + if (gWindow->geometry ().vCount)
> > #endif
> > 156 + {
> > #ifdef USE_MODERN_COMPIZ_GL
> > 157 + GLFragment::Attrib fragment (attrib);
> > #endif
> > 158 + GLMatrix wTransform (transform);
> > 159 +
> > 160 + wTransform.translate (x, y, 0.0f);
> > 161 +
> > #ifdef USE_MODERN_COMPIZ_GL
> > gWindow->glDrawTexture (icon, wTransform, attrib, mask);
> > #else
> > 162 + glPushMatrix ();
> > 163 + glLoadMatrixf (wTransform.getMatrix ());
> > 164 + gWindow->glDrawTexture (icon, fragment, mask);
> > 165 + glPopMatrix ();
> > #endif
> > 166 + }
> Fixed on rev: 2577
> I have implemented the "scaleSelectWindow" based on scaleaddon plugin, but I
> did not understand why I need this code. (The implementation is working well
> without this)

Hmm, what do you mean by this? If you're saying that you don't need either I guess you can remove them both? Its just that overriding scaleSelectWindow is the preferred way to finding out the currently highlighted window as opposed to reimplementing checkForWindowAt.

>
> >
> > 172 + // BG
> > 173 + glColor3f (0.0f, 0.0f, 0.0f);
> > 174 + glRectf (x, y2, x2, y);
> >
> > Preferably use client side buffers for this
> Fixed on rev: 2574
> Thanks for the example code.
>
> > Make this a constant
> Fixed on rev: 2575
>
> >
> > Also avoid the 65535, use OPAQUE
> Fixed on rev: 2576

Thanks.

>
> >
> > 121 + CompString name (PKGDATADIR"/close_dash.png");
> >
> > Is that the correct asset?
> Based on designer docs, yes this is the correct icon.

+1

>
> >
> > That needs to be under test.
> Any suggestion or example how to test it?

My suggestion to make the code testable is split unityshell.(h/cpp) file into different files (UnityWindow/UnityWindowPrivate, UntiyScree/UnityScreenPrivate and UnityShell), with this we can instantiate only the private class inside of the tests and call/test the "private" functions.

What do you think?

^ This suggestion is the right way to do it :)

Revision history for this message
Renato Araujo Oliveira Filho (renatofilho) wrote :

> Hmm, what do you mean by this? If you're saying that you don't need either I
> guess you can remove them both? Its just that overriding scaleSelectWindow is
> the preferred way to finding out the currently highlighted window as opposed
> to reimplementing checkForWindowAt.

I have implemented "scaleSelectWindow" but I did not use all the code you suggested, what I did was:

+void UnityWindow::scaleSelectWindow ()
210 +{
211 + UnityScreen* us = UnityScreen::get(screen);
212 +
213 + if (us->highlighted_window_ != window->id ())
214 + {
215 + CompositeWindow *cWindow = CompositeWindow::get (window);
216 + if (cWindow)
217 + cWindow->addDamage ();
218 +
219 + cWindow = 0;
220 + CompWindow *old_window = screen->findWindow (us->highlighted_window_);
221 + if (old_window)
222 + cWindow = CompositeWindow::get (old_window);
223 +
224 + if (cWindow)
225 + cWindow->addDamage ();
226 +
227 + us->highlighted_window_ = window->id ();
228 + }
229 +
230 + ScaleWindow *sWindow = ScaleWindow::get (window);
231 + if (sWindow)
232 + sWindow->scaleSelectWindow ();

Revision history for this message
Renato Araujo Oliveira Filho (renatofilho) wrote :

> > >
> > > That needs to be under test.
> > Any suggestion or example how to test it?
>
> My suggestion to make the code testable is split unityshell.(h/cpp) file into
> different files (UnityWindow/UnityWindowPrivate, UntiyScree/UnityScreenPrivate
> and UnityShell), with this we can instantiate only the private class inside of
> the tests and call/test the "private" functions.
>
> What do you think?
>
> ^ This suggestion is the right way to do it :)

This will be a big change in the code, because of that me and Olivier think this is not the best moment to do it, since this is our last week working on Unity bug fixes, and the code is already in feature freeze.

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

This looks good. I don't know how much of this is testable, but I agree at this point its probably better in than out. I'll put my +1 here and hopefully someone can give a second opinion in the next few hours.

review: Approve
Revision history for this message
Sam Spilsbury (smspillaz) :
review: Approve
Revision history for this message
Unity Merger (unity-merger) wrote :

No commit message specified.

Revision history for this message
Unity Merger (unity-merger) wrote :

The Jenkins job https://jenkins.qa.ubuntu.com/job/automerge-unity/1164/console reported an error when processing this lp:~renatofilho/unity/unity-lp876017 branch.
Not merging it.

Revision history for this message
Sam Spilsbury (smspillaz) wrote :

Hey renato.

You need to add xrender to the pkgconfig deps in the top level cmakelists file.

Sent from Samsung Mobile

 Unity Merger <email address hidden> wrote:

The Jenkins job https://jenkins.qa.ubuntu.com/job/automerge-unity/1164/console reported an error when processing this lp:~renatofilho/unity/unity-lp876017 branch.
Not merging it.
--
https://code.launchpad.net/~renatofilho/unity/unity-lp876017/+merge/120450
You are reviewing the proposed merge of lp:~renatofilho/unity/unity-lp876017 into lp:unity.

Revision history for this message
Unity Merger (unity-merger) wrote :

There are additional revisions which have not been approved in review. Please seek review and approval of these new revisions.

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :

64 + WindowCairoContext ()

When you have some time, could you please update this code to match the unity coding stiles (i.e. no spaces between methods and brackets)

Instead of GetTextProperty and GetTextProperty why not just using gdk_x11_get_xatom_by_name?
Also, these functions should actually be in WindowManager class (implemented by PluginAdapterCompiz).

441 + if (window_header_style_)
442 + g_object_unref (window_header_style_);

You should have used glib::Object for this, and try to get rid of some manual deletion using smart pointers.

Revision history for this message
Renato Araujo Oliveira Filho (renatofilho) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'CMakeLists.txt'
--- CMakeLists.txt 2012-08-30 12:52:53 +0000
+++ CMakeLists.txt 2012-08-31 13:28:34 +0000
@@ -130,8 +130,7 @@
130#130#
131# Compiz Plugins131# Compiz Plugins
132#132#
133133set (UNITY_PLUGIN_DEPS "compiz;nux-3.0>=3.0.0;libbamf3;dee-1.0;gio-2.0;gio-unix-2.0;gmodule-2.0;dbusmenu-glib-0.4;x11;libstartup-notification-1.0;gthread-2.0;indicator3-0.4>=0.4.90;atk;unity-misc>=0.4.0;dbus-glib-1;gtk+-3.0>=3.1;sigc++-2.0;json-glib-1.0;libnotify;xfixes;unity-protocol-private>=5.95.1;libgeis;xrender>=0.9")
134set (UNITY_PLUGIN_DEPS "compiz;nux-3.0>=3.0.0;libbamf3;dee-1.0;gio-2.0;gio-unix-2.0;gmodule-2.0;dbusmenu-glib-0.4;x11;libstartup-notification-1.0;gthread-2.0;indicator3-0.4>=0.4.90;atk;unity-misc>=0.4.0;dbus-glib-1;gtk+-3.0>=3.1;sigc++-2.0;json-glib-1.0;libnotify;xfixes;unity-protocol-private>=5.95.1;libgeis")
135set (UNITY_PROTOCOL_PRIVATE_DEPS "unity-protocol-private>=5.95.1")134set (UNITY_PROTOCOL_PRIVATE_DEPS "unity-protocol-private>=5.95.1")
136135
137find_package (PkgConfig)136find_package (PkgConfig)
138137
=== modified file 'plugins/unityshell/CMakeLists.txt'
--- plugins/unityshell/CMakeLists.txt 2012-08-03 12:51:02 +0000
+++ plugins/unityshell/CMakeLists.txt 2012-08-31 13:28:34 +0000
@@ -6,7 +6,7 @@
66
7compiz_plugin (unityshell7compiz_plugin (unityshell
8 PKGDEPS ${UNITY_PLUGIN_DEPS}8 PKGDEPS ${UNITY_PLUGIN_DEPS}
9 PLUGINDEPS composite opengl compiztoolbox9 PLUGINDEPS composite opengl compiztoolbox scale
10 CFLAGSADD "-DINSTALLPREFIX='\"${CMAKE_INSTALL_PREFIX}\"' -DPKGDATADIR='\"${PKGDATADIR}\"' -I${CMAKE_BINARY_DIR} -I${CMAKE_SOURCE_DIR} ${BOOT_LOGGER_FLAG} -DGETTEXT_PACKAGE='\"unity\"' ${MAINTAINER_CFLAGS} -I${CMAKE_SOURCE_DIR}/dash/ -I${CMAKE_SOURCE_DIR}/launcher/ -I${CMAKE_SOURCE_DIR}/hud/ -I${CMAKE_SOURCE_DIR}/panel/ -I${CMAKE_SOURCE_DIR}/shortcuts/ -I${CMAKE_SOURCE_DIR}/unity-shared/"10 CFLAGSADD "-DINSTALLPREFIX='\"${CMAKE_INSTALL_PREFIX}\"' -DPKGDATADIR='\"${PKGDATADIR}\"' -I${CMAKE_BINARY_DIR} -I${CMAKE_SOURCE_DIR} ${BOOT_LOGGER_FLAG} -DGETTEXT_PACKAGE='\"unity\"' ${MAINTAINER_CFLAGS} -I${CMAKE_SOURCE_DIR}/dash/ -I${CMAKE_SOURCE_DIR}/launcher/ -I${CMAKE_SOURCE_DIR}/hud/ -I${CMAKE_SOURCE_DIR}/panel/ -I${CMAKE_SOURCE_DIR}/shortcuts/ -I${CMAKE_SOURCE_DIR}/unity-shared/"
11 LIBDIRS "${CMAKE_BINARY_DIR}/UnityCore"11 LIBDIRS "${CMAKE_BINARY_DIR}/UnityCore"
12 )12 )
1313
=== modified file 'plugins/unityshell/src/unityshell.cpp'
--- plugins/unityshell/src/unityshell.cpp 2012-08-31 09:15:33 +0000
+++ plugins/unityshell/src/unityshell.cpp 2012-08-31 13:28:34 +0000
@@ -43,6 +43,9 @@
43#include <gdk/gdk.h>43#include <gdk/gdk.h>
44#include <gdk/gdkx.h>44#include <gdk/gdkx.h>
45#include <libnotify/notify.h>45#include <libnotify/notify.h>
46#include <cairo-xlib-xrender.h>
47
48#include <text/text.h>
4649
47#include <sstream>50#include <sstream>
48#include <memory>51#include <memory>
@@ -80,6 +83,10 @@
8083
81UnityScreen* uScreen = 0;84UnityScreen* uScreen = 0;
8285
86static unsigned int CLOSE_ICON_SIZE = 19;
87static unsigned int CLOSE_ICON_SPACE = 5;
88static unsigned int SCALE_WINDOW_TITLE_SIZE = 28;
89
83void reset_glib_logging();90void reset_glib_logging();
84void configure_logging();91void configure_logging();
85void capture_g_log_calls(const gchar* log_domain,92void capture_g_log_calls(const gchar* log_domain,
@@ -100,6 +107,34 @@
100} // namespace local107} // namespace local
101} // anon namespace108} // anon namespace
102109
110class WindowCairoContext
111{
112 public:
113 Pixmap pixmap_;
114 cairo_surface_t* surface_;
115 GLTexture::List texture_;
116 cairo_t *cr_;
117
118 WindowCairoContext ()
119 : pixmap_ (0), surface_ (0), cr_ (0)
120 {
121 }
122
123 ~WindowCairoContext ()
124 {
125 if (cr_)
126 cairo_destroy (cr_);
127
128 if (surface_)
129 cairo_surface_destroy (surface_);
130
131 texture_.clear ();
132
133 if (pixmap_)
134 XFreePixmap (screen->dpy (), pixmap_);
135 }
136};
137
103UnityScreen::UnityScreen(CompScreen* screen)138UnityScreen::UnityScreen(CompScreen* screen)
104 : BaseSwitchScreen (screen)139 : BaseSwitchScreen (screen)
105 , PluginClassHandler <UnityScreen, CompScreen> (screen)140 , PluginClassHandler <UnityScreen, CompScreen> (screen)
@@ -128,6 +163,7 @@
128 , panel_texture_has_changed_(true)163 , panel_texture_has_changed_(true)
129 , paint_panel_(false)164 , paint_panel_(false)
130 , scale_just_activated_(false)165 , scale_just_activated_(false)
166 , highlighted_window_(0)
131 , minimize_speed_controller(new WindowMinimizeSpeedController())167 , minimize_speed_controller(new WindowMinimizeSpeedController())
132{168{
133 Timer timer;169 Timer timer;
@@ -1221,6 +1257,11 @@
1221 }1257 }
1222}1258}
12231259
1260CompRect UnityWindow::closeButtonArea ()
1261{
1262 return close_button_area_;
1263}
1264
1224bool UnityScreen::shellCouldBeHidden(CompOutput const& output)1265bool UnityScreen::shellCouldBeHidden(CompOutput const& output)
1225{1266{
1226 std::vector<Window> const& nuxwins(nux::XInputWindow::NativeHandleList());1267 std::vector<Window> const& nuxwins(nux::XInputWindow::NativeHandleList());
@@ -1588,6 +1629,24 @@
1588 launcher_controller_->KeyNavTerminate(false);1629 launcher_controller_->KeyNavTerminate(false);
1589 EnableCancelAction(CancelActionTarget::LAUNCHER_SWITCHER, false);1630 EnableCancelAction(CancelActionTarget::LAUNCHER_SWITCHER, false);
1590 }1631 }
1632 if (PluginAdapter::Default()->IsScaleActive() &&
1633 event->xbutton.button == Button1 &&
1634 highlighted_window_ != 0)
1635 {
1636 CompWindow *w = screen->findWindow (highlighted_window_);
1637 if (w)
1638 {
1639 UnityWindow *uw = UnityWindow::get (w);
1640 CompPoint pointer (pointerX, pointerY);
1641 if (uw->closeButtonArea ().contains (pointer))
1642 {
1643 w->close (0);
1644 skip_other_plugins = true;
1645 }
1646 }
1647
1648 }
1649
1591 break;1650 break;
1592 case ButtonRelease:1651 case ButtonRelease:
1593 if (switcher_controller_ && switcher_controller_->Visible())1652 if (switcher_controller_ && switcher_controller_->Visible())
@@ -3409,9 +3468,11 @@
3409 , gWindow(GLWindow::get(window))3468 , gWindow(GLWindow::get(window))
3410 , mMinimizeHandler()3469 , mMinimizeHandler()
3411 , mShowdesktopHandler(nullptr)3470 , mShowdesktopHandler(nullptr)
3471 , window_header_style_(0)
3412{3472{
3413 WindowInterface::setHandler(window);3473 WindowInterface::setHandler(window);
3414 GLWindowInterface::setHandler(gWindow);3474 GLWindowInterface::setHandler(gWindow);
3475 ScaleWindowInterface::setHandler (ScaleWindow::get (window));
34153476
3416 if (UnityScreen::get (screen)->optionGetShowMinimizedWindows () &&3477 if (UnityScreen::get (screen)->optionGetShowMinimizedWindows () &&
3417 window->mapNum ())3478 window->mapNum ())
@@ -3456,6 +3517,292 @@
3456 }3517 }
3457}3518}
34583519
3520void UnityWindow::DrawTexture (GLTexture* icon,
3521 const GLWindowPaintAttrib& attrib,
3522 const GLMatrix& transform,
3523 unsigned int mask,
3524 float x, float y,
3525 int &maxWidth, int &maxHeight)
3526{
3527 if (icon)
3528 {
3529 int width, height;
3530 width = icon->width ();
3531 height = icon->height ();
3532
3533 if (height > maxHeight)
3534 maxHeight = height;
3535
3536 if (width > maxWidth)
3537 maxWidth = width;
3538
3539 CompRegion iconReg (0, 0, width, height);
3540 GLTexture::MatrixList ml (1);
3541
3542 ml[0] = icon->matrix ();
3543 gWindow->vertexBuffer ()->begin ();
3544 if (width && height)
3545 gWindow->glAddGeometry (ml, iconReg, iconReg);
3546
3547 if (gWindow->vertexBuffer ()->end ())
3548 {
3549 GLMatrix wTransform (transform);
3550
3551 wTransform.translate (x, y, 0.0f);
3552
3553 gWindow->glDrawTexture (icon, wTransform, attrib, mask);
3554 }
3555 }
3556}
3557
3558WindowCairoContext* UnityWindow::CreateCairoContext (float width, float height)
3559{
3560 XRenderPictFormat *format;
3561 Screen *xScreen;
3562 WindowCairoContext *context = new WindowCairoContext();
3563
3564 xScreen = ScreenOfDisplay (screen->dpy (), screen->screenNum ());
3565
3566 format = XRenderFindStandardFormat (screen->dpy (), PictStandardARGB32);
3567 context->pixmap_ = XCreatePixmap (screen->dpy (),
3568 screen->root (),
3569 width, height, 32);
3570
3571 context->texture_ = GLTexture::bindPixmapToTexture (context->pixmap_,
3572 width, height,
3573 32);
3574 if (context->texture_.empty ())
3575 {
3576 delete context;
3577 return 0;
3578 }
3579
3580 context->surface_ = cairo_xlib_surface_create_with_xrender_format (screen->dpy (),
3581 context->pixmap_,
3582 xScreen,
3583 format,
3584 width,
3585 height);
3586 context->cr_ = cairo_create (context->surface_);
3587
3588 // clear
3589 cairo_save (context->cr_);
3590 cairo_set_operator (context->cr_, CAIRO_OPERATOR_CLEAR);
3591 cairo_paint (context->cr_);
3592 cairo_restore (context->cr_);
3593
3594 return context;
3595}
3596
3597void UnityWindow::RenderText (WindowCairoContext *context,
3598 float x, float y,
3599 float maxWidth, float maxHeight)
3600{
3601 PangoFontDescription* font = pango_font_description_new ();
3602 pango_font_description_set_family (font, "sans");
3603 pango_font_description_set_absolute_size (font, 12 * PANGO_SCALE);
3604 pango_font_description_set_style (font, PANGO_STYLE_NORMAL);
3605 pango_font_description_set_weight (font, PANGO_WEIGHT_BOLD);
3606
3607 PangoLayout* layout = pango_cairo_create_layout (context->cr_);
3608 pango_layout_set_font_description (layout, font);
3609 pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
3610 pango_layout_set_height (layout, maxHeight);
3611
3612 pango_layout_set_auto_dir (layout, false);
3613 pango_layout_set_text (layout,
3614 GetWindowName (window->id ()).c_str (),
3615 -1);
3616
3617 /* update the size of the pango layout */
3618 pango_layout_set_width (layout, maxWidth * PANGO_SCALE);
3619 pango_cairo_update_layout (context->cr_, layout);
3620
3621 cairo_set_operator (context->cr_, CAIRO_OPERATOR_OVER);
3622
3623 cairo_set_source_rgba (context->cr_,
3624 1.0,
3625 1.0,
3626 1.0,
3627 1.0);
3628
3629 // alignment
3630 int lWidth, lHeight;
3631 pango_layout_get_pixel_size (layout, &lWidth, &lHeight);
3632
3633 y = ((maxHeight - lHeight) / 2.0) + y;
3634 cairo_translate (context->cr_, x, y);
3635 pango_cairo_show_layout (context->cr_, layout);
3636}
3637
3638void UnityWindow::DrawWindowTitle (const GLWindowPaintAttrib& attrib,
3639 const GLMatrix& transform,
3640 unsigned int mask,
3641 float x, float y, float x2, float y2)
3642{
3643 const float width = x2 - x;
3644
3645 // Paint a fake window decoration
3646 WindowCairoContext *context = CreateCairoContext (width, SCALE_WINDOW_TITLE_SIZE);
3647
3648 cairo_save (context->cr_);
3649 cairo_push_group (context->cr_);
3650
3651 // Round window decoration top border
3652 const double height = SCALE_WINDOW_TITLE_SIZE;
3653 const double aspect = 1.0;
3654 const double corner_radius = height / 10.0;
3655 const double radius = corner_radius / aspect;
3656 const double degrees = M_PI / 180.0;
3657
3658 cairo_new_sub_path (context->cr_);
3659
3660 cairo_arc (context->cr_, radius, radius, radius, 180 * degrees, 270 * degrees);
3661 cairo_arc (context->cr_, width - radius, radius, radius, -90 * degrees, 0 * degrees);
3662 cairo_line_to (context->cr_, width, height);
3663 cairo_line_to (context->cr_, 0, height);
3664
3665 cairo_close_path (context->cr_);
3666 cairo_clip (context->cr_);
3667
3668 // Draw window decoration abased on gtk style
3669 gtk_render_background (window_header_style_, context->cr_, 0, 0, width, SCALE_WINDOW_TITLE_SIZE);
3670 gtk_render_frame (window_header_style_, context->cr_, 0, 0, width, SCALE_WINDOW_TITLE_SIZE);
3671
3672 cairo_pop_group_to_source (context->cr_);
3673
3674 cairo_paint_with_alpha (context->cr_, 1.0);
3675 cairo_restore (context->cr_);
3676
3677 // Draw windows title
3678 RenderText (context,
3679 CLOSE_ICON_SPACE * 2 + CLOSE_ICON_SIZE,
3680 0.0,
3681 width, SCALE_WINDOW_TITLE_SIZE);
3682
3683 mask |= PAINT_WINDOW_BLEND_MASK;
3684 int maxWidth, maxHeight;
3685 foreach(GLTexture *icon, context->texture_)
3686 {
3687 DrawTexture (icon, attrib, transform, mask,
3688 x, y,
3689 maxWidth , maxHeight);
3690 }
3691
3692 delete context;
3693}
3694
3695void UnityWindow::scalePaintDecoration (const GLWindowPaintAttrib& attrib,
3696 const GLMatrix& transform,
3697 const CompRegion& region,
3698 unsigned int mask)
3699{
3700 ScaleWindow *sWindow = ScaleWindow::get (window);
3701 if (!sWindow)
3702 return;
3703
3704 sWindow->scalePaintDecoration (attrib, transform, region, mask);
3705
3706 if (!sWindow->hasSlot()) // animation not finished
3707 return;
3708
3709 if (!window_header_style_)
3710 {
3711 GtkWidgetPath* widget_path = gtk_widget_path_new ();
3712 gint pos = gtk_widget_path_append_type (widget_path, GTK_TYPE_WINDOW);
3713 gtk_widget_path_iter_set_name (widget_path, pos, "UnityPanelWidget");
3714
3715 window_header_style_ = gtk_style_context_new ();
3716 gtk_style_context_set_path (window_header_style_, widget_path);
3717 gtk_style_context_add_class (window_header_style_, "gnome-panel-menu-bar");
3718 gtk_style_context_add_class (window_header_style_, "unity-panel");
3719
3720 // get close button
3721 panel::Style& style = panel::Style::Instance();
3722
3723 std::vector<std::string> files = style.GetWindowButtonFileNames (panel::WindowButtonType::CLOSE,
3724 panel::WindowState::NORMAL);
3725
3726 CompString pName ("unityshell");
3727 foreach (std::string file, files)
3728 {
3729 CompString fileName (file.c_str ());
3730 CompSize size (CLOSE_ICON_SIZE, CLOSE_ICON_SIZE);
3731 close_icon_ = GLTexture::readImageToTexture (fileName,
3732 pName,
3733 size);
3734 if (close_icon_.size () != 0)
3735 break;
3736 }
3737
3738 if (close_icon_.size () == 0)
3739 {
3740 CompString fileName (PKGDATADIR"/close_dash.png");
3741 CompSize size (CLOSE_ICON_SIZE, CLOSE_ICON_SIZE);
3742 close_icon_ = GLTexture::readImageToTexture (fileName,
3743 pName,
3744 size);
3745 }
3746 }
3747
3748 // Make the windows header opaque to override the original
3749 GLWindowPaintAttrib sAttrib (attrib);
3750 sAttrib.opacity = OPAQUE;
3751
3752 ScalePosition pos = sWindow->getCurrentPosition ();
3753 int maxHeight, maxWidth;
3754 // Use "2" as margin to make sure to cover all originial decoration
3755 const float width = (window->width () + 4) * pos.scale;
3756 const float x = pos.x () + window->x () - (2 * pos.scale);
3757 const float y = pos.y () + window->y () - SCALE_WINDOW_TITLE_SIZE;
3758 const float iconX = x + CLOSE_ICON_SPACE;
3759 const float iconY = y + ((SCALE_WINDOW_TITLE_SIZE - CLOSE_ICON_SIZE) / 2.0);
3760
3761 maxHeight = maxWidth = 0;
3762
3763 DrawWindowTitle (sAttrib,
3764 transform,
3765 mask,
3766 x, y,
3767 x + width, y + SCALE_WINDOW_TITLE_SIZE);
3768
3769 mask |= PAINT_WINDOW_BLEND_MASK;
3770 foreach(GLTexture *icon, close_icon_)
3771 {
3772 DrawTexture (icon, sAttrib, transform, mask,
3773 iconX, iconY,
3774 maxWidth , maxHeight);
3775 }
3776
3777 close_button_area_ = CompRect (iconX, iconY, maxWidth, maxHeight);
3778}
3779
3780void UnityWindow::scaleSelectWindow ()
3781{
3782 UnityScreen* us = UnityScreen::get(screen);
3783
3784 if (us->highlighted_window_ != window->id ())
3785 {
3786 CompositeWindow *cWindow = CompositeWindow::get (window);
3787 if (cWindow)
3788 cWindow->addDamage ();
3789
3790 cWindow = 0;
3791 CompWindow *old_window = screen->findWindow (us->highlighted_window_);
3792 if (old_window)
3793 cWindow = CompositeWindow::get (old_window);
3794
3795 if (cWindow)
3796 cWindow->addDamage ();
3797
3798 us->highlighted_window_ = window->id ();
3799 }
3800
3801 ScaleWindow *sWindow = ScaleWindow::get (window);
3802 if (sWindow)
3803 sWindow->scaleSelectWindow ();
3804}
3805
3459UnityWindow::~UnityWindow()3806UnityWindow::~UnityWindow()
3460{3807{
3461 UnityScreen* us = UnityScreen::get(screen);3808 UnityScreen* us = UnityScreen::get(screen);
@@ -3474,6 +3821,9 @@
3474 window->minimize ();3821 window->minimize ();
3475 }3822 }
34763823
3824 if (window_header_style_)
3825 g_object_unref (window_header_style_);
3826
3477 ShowdesktopHandler::animating_windows.remove (static_cast <ShowdesktopHandlerWindowInterface *> (this));3827 ShowdesktopHandler::animating_windows.remove (static_cast <ShowdesktopHandlerWindowInterface *> (this));
34783828
3479 if (mShowdesktopHandler)3829 if (mShowdesktopHandler)
@@ -3513,6 +3863,84 @@
3513 return true;3863 return true;
3514}3864}
35153865
3866CompString UnityWindow::GetUtf8Property (Window id,
3867 Atom atom)
3868{
3869 Atom type;
3870 int result, format;
3871 unsigned long nItems, bytesAfter;
3872 char *val;
3873 CompString retval;
3874 Atom utf8StringAtom;
3875
3876 utf8StringAtom = XInternAtom (screen->dpy (), "UTF8_STRING", 0);
3877 result = XGetWindowProperty (screen->dpy (), id, atom, 0L, 65536, False,
3878 utf8StringAtom, &type, &format, &nItems,
3879 &bytesAfter, (unsigned char **) &val);
3880
3881 if (result != Success)
3882 return retval;
3883
3884 if (type == utf8StringAtom && format == 8 && val && nItems > 0)
3885 {
3886 char valueString[nItems + 1];
3887 strncpy (valueString, val, nItems);
3888 valueString[nItems] = 0;
3889 retval = valueString;
3890 }
3891 if (val)
3892 XFree (val);
3893
3894 return retval;
3895}
3896
3897CompString UnityWindow::GetTextProperty (Window id,
3898 Atom atom)
3899{
3900 XTextProperty text;
3901 CompString retval;
3902
3903 text.nitems = 0;
3904 if (XGetTextProperty (screen->dpy (), id, &text, atom))
3905 {
3906 if (text.value)
3907 {
3908 char valueString[text.nitems + 1];
3909
3910 strncpy (valueString, (char *) text.value, text.nitems);
3911 valueString[text.nitems] = 0;
3912
3913 retval = valueString;
3914
3915 XFree (text.value);
3916 }
3917 }
3918
3919 return retval;
3920}
3921
3922
3923CompString UnityWindow::GetWindowName (Window id)
3924{
3925 CompString name;
3926 Atom visibleNameAtom;
3927
3928 visibleNameAtom = XInternAtom (screen->dpy (), "_NET_WM_VISIBLE_NAME", 0);
3929 name = GetUtf8Property (id, visibleNameAtom);
3930 if (name.empty ())
3931 {
3932 Atom wmNameAtom = XInternAtom (screen->dpy (), "_NET_WM_NAME", 0);
3933 name = GetUtf8Property (id, wmNameAtom);
3934 }
3935
3936
3937 if (name.empty ())
3938 name = GetTextProperty (id, XA_WM_NAME);
3939
3940 return name;
3941}
3942
3943
35163944
3517namespace3945namespace
3518{3946{
35193947
=== modified file 'plugins/unityshell/src/unityshell.h'
--- plugins/unityshell/src/unityshell.h 2012-08-27 13:51:29 +0000
+++ plugins/unityshell/src/unityshell.h 2012-08-31 13:28:34 +0000
@@ -29,6 +29,7 @@
29#include <sigc++/sigc++.h>29#include <sigc++/sigc++.h>
30#include <boost/shared_ptr.hpp>30#include <boost/shared_ptr.hpp>
3131
32#include <scale/scale.h>
32#include <core/core.h>33#include <core/core.h>
33#include <core/pluginclasshandler.h>34#include <core/pluginclasshandler.h>
34#include <composite/composite.h>35#include <composite/composite.h>
@@ -70,6 +71,8 @@
70namespace unity71namespace unity
71{72{
7273
74class WindowCairoContext;
75
73/* base screen class */76/* base screen class */
74class UnityScreen :77class UnityScreen :
75 public unity::debug::Introspectable,78 public unity::debug::Introspectable,
@@ -344,8 +347,9 @@
344 glib::SourceManager sources_;347 glib::SourceManager sources_;
345 unity::ThumbnailGenerator thumb_generator;348 unity::ThumbnailGenerator thumb_generator;
346349
350 Window highlighted_window_;
351
347 WindowMinimizeSpeedController* minimize_speed_controller;352 WindowMinimizeSpeedController* minimize_speed_controller;
348
349 friend class UnityWindow;353 friend class UnityWindow;
350};354};
351355
@@ -354,6 +358,7 @@
354 public GLWindowInterface,358 public GLWindowInterface,
355 public ShowdesktopHandlerWindowInterface,359 public ShowdesktopHandlerWindowInterface,
356 public compiz::WindowInputRemoverLockAcquireInterface,360 public compiz::WindowInputRemoverLockAcquireInterface,
361 public WrapableHandler<ScaleWindowInterface, 4>,
357 public BaseSwitchWindow,362 public BaseSwitchWindow,
358 public PluginClassHandler <UnityWindow, CompWindow>363 public PluginClassHandler <UnityWindow, CompWindow>
359{364{
@@ -414,6 +419,8 @@
414419
415 void handleEvent (XEvent *event);420 void handleEvent (XEvent *event);
416421
422 CompRect closeButtonArea ();
423
417 typedef compiz::CompizMinimizedWindowHandler<UnityScreen, UnityWindow>424 typedef compiz::CompizMinimizedWindowHandler<UnityScreen, UnityWindow>
418 UnityMinimizedHandler;425 UnityMinimizedHandler;
419 std::unique_ptr <UnityMinimizedHandler> mMinimizeHandler;426 std::unique_ptr <UnityMinimizedHandler> mMinimizeHandler;
@@ -422,6 +429,13 @@
422429
423 //! Emited when CompWindowNotifyBeforeDestroy is received430 //! Emited when CompWindowNotifyBeforeDestroy is received
424 sigc::signal<void> being_destroyed;431 sigc::signal<void> being_destroyed;
432
433 void scaleSelectWindow ();
434 void scalePaintDecoration (const GLWindowPaintAttrib &,
435 const GLMatrix &,
436 const CompRegion &,
437 unsigned int);
438
425private:439private:
426 void DoEnableFocus ();440 void DoEnableFocus ();
427 void DoDisableFocus ();441 void DoDisableFocus ();
@@ -453,8 +467,32 @@
453467
454 compiz::WindowInputRemoverLock::Ptr GetInputRemover ();468 compiz::WindowInputRemoverLock::Ptr GetInputRemover ();
455469
470 void DrawWindowTitle (const GLWindowPaintAttrib& attrib,
471 const GLMatrix& transform,
472 unsigned int mask,
473 float x, float y, float x2, float y2);
474 void DrawTexture (GLTexture *icon,
475 const GLWindowPaintAttrib& attrib,
476 const GLMatrix& transform,
477 unsigned int mask,
478 float x, float y,
479 int &maxWidth, int &maxHeight);
480 void RenderText (WindowCairoContext *context,
481 float x, float y,
482 float maxWidth, float maxHeight);
483 WindowCairoContext* CreateCairoContext (float width, float height);
484
485 // based on compiz text plugin
486 CompString GetWindowName (Window id);
487 CompString GetUtf8Property (Window id, Atom atom);
488 CompString GetTextProperty (Window id, Atom atom);
489
456 compiz::WindowInputRemoverLock::Weak input_remover_;490 compiz::WindowInputRemoverLock::Weak input_remover_;
457 glib::Source::UniquePtr focus_desktop_timeout_;491 glib::Source::UniquePtr focus_desktop_timeout_;
492
493 GLTexture::List close_icon_;
494 CompRect close_button_area_;
495 GtkStyleContext* window_header_style_;
458};496};
459497
460498
461499
=== modified file 'unity-shared/PanelStyle.cpp'
--- unity-shared/PanelStyle.cpp 2012-08-01 20:46:31 +0000
+++ unity-shared/PanelStyle.cpp 2012-08-31 13:28:34 +0000
@@ -182,9 +182,17 @@
182 return context.GetBitmap();182 return context.GetBitmap();
183}183}
184184
185nux::BaseTexture* Style::GetWindowButton(WindowButtonType type, WindowState state)185/*!
186 Return a vector with the possible file names sorted by priority
187
188 @param type The type of the button.
189 @param state The button state.
190
191 @return A vector of strings with the possible file names sorted by priority.
192*/
193std::vector<std::string> Style::GetWindowButtonFileNames(WindowButtonType type, WindowState state)
186{194{
187 nux::BaseTexture* texture = NULL;195 std::vector<std::string> files;
188 std::string names[] = { "close", "minimize", "unmaximize", "maximize" };196 std::string names[] = { "close", "minimize", "unmaximize", "maximize" };
189 std::string states[] = { "", "_focused_prelight", "_focused_pressed", "_unfocused",197 std::string states[] = { "", "_focused_prelight", "_focused_pressed", "_unfocused",
190 "_unfocused", "_unfocused_prelight", "_unfocused_pressed"};198 "_unfocused", "_unfocused_prelight", "_unfocused_pressed"};
@@ -200,38 +208,40 @@
200 glib::String filename(g_build_filename(home_dir, ".themes", _theme_name.c_str(), subpath.str().c_str(), NULL));208 glib::String filename(g_build_filename(home_dir, ".themes", _theme_name.c_str(), subpath.str().c_str(), NULL));
201209
202 if (g_file_test(filename.Value(), G_FILE_TEST_EXISTS))210 if (g_file_test(filename.Value(), G_FILE_TEST_EXISTS))
203 {211 files.push_back (filename.Value());
204 glib::Error error;
205
206 // Found a file, try loading the pixbuf
207 glib::Object<GdkPixbuf> pixbuf(gdk_pixbuf_new_from_file(filename.Value(), &error));
208 if (error)
209 LOG_WARNING(logger) << "Unable to load window button " << filename.Value() << ": " << error.Message();
210 else
211 texture = nux::CreateTexture2DFromPixbuf(pixbuf, true);
212 }
213 }212 }
214213
215 // texture is NULL if the pixbuf is not loaded214 const char* var = g_getenv("GTK_DATA_PREFIX");
216 if (!texture)215 if (!var)
216 var = "/usr";
217
218 glib::String filename(g_build_filename(var, "share", "themes", _theme_name.c_str(), subpath.str().c_str(), NULL));
219 if (g_file_test(filename.Value(), G_FILE_TEST_EXISTS))
220 files.push_back (filename.Value());
221
222 return files;
223}
224
225nux::BaseTexture* Style::GetWindowButton(WindowButtonType type, WindowState state)
226{
227 nux::BaseTexture* texture = NULL;
228
229 std::vector<std::string> files = GetWindowButtonFileNames (type, state);
230 for (unsigned int i=0; i < files.size(); i++)
217 {231 {
218 const char* var = g_getenv("GTK_DATA_PREFIX");
219 if (!var)
220 var = "/usr";
221
222 glib::String filename(g_build_filename(var, "share", "themes", _theme_name.c_str(), subpath.str().c_str(), NULL));
223
224 if (g_file_test(filename.Value(), G_FILE_TEST_EXISTS))
225 {
226 glib::Error error;232 glib::Error error;
227233 // Try loading the pixbuf
228 // Found a file, try loading the pixbuf234 glib::Object<GdkPixbuf> pixbuf(gdk_pixbuf_new_from_file(files[i].c_str (), &error));
229 glib::Object<GdkPixbuf> pixbuf(gdk_pixbuf_new_from_file(filename.Value(), &error));
230 if (error)235 if (error)
231 LOG_WARNING(logger) << "Unable to load window button " << filename.Value() << ": " << error.Message();236 {
237 LOG_WARNING(logger) << "Unable to load window button " << files[i] << ": " << error.Message();
238 }
232 else239 else
240 {
233 texture = nux::CreateTexture2DFromPixbuf(pixbuf, true);241 texture = nux::CreateTexture2DFromPixbuf(pixbuf, true);
234 }242 if (texture)
243 break;
244 }
235 }245 }
236246
237 if (!texture)247 if (!texture)
238248
=== modified file 'unity-shared/PanelStyle.h'
--- unity-shared/PanelStyle.h 2012-08-01 20:46:31 +0000
+++ unity-shared/PanelStyle.h 2012-08-31 13:28:34 +0000
@@ -71,6 +71,7 @@
71 GtkStyleContext* GetStyleContext();71 GtkStyleContext* GetStyleContext();
72 nux::NBitmapData* GetBackground(int width, int height, float opacity);72 nux::NBitmapData* GetBackground(int width, int height, float opacity);
73 nux::BaseTexture* GetWindowButton(WindowButtonType type, WindowState state);73 nux::BaseTexture* GetWindowButton(WindowButtonType type, WindowState state);
74 std::vector<std::string> GetWindowButtonFileNames(WindowButtonType type, WindowState state);
74 nux::BaseTexture* GetFallbackWindowButton(WindowButtonType type, WindowState state);75 nux::BaseTexture* GetFallbackWindowButton(WindowButtonType type, WindowState state);
75 glib::Object<GdkPixbuf> GetHomeButton();76 glib::Object<GdkPixbuf> GetHomeButton();
76 std::string GetFontDescription(PanelItem item);77 std::string GetFontDescription(PanelItem item);