Merge lp://qastaging/~3v1n0/unity/unity-decorations into lp://qastaging/unity

Proposed by Marco Trevisan (Treviño)
Status: Merged
Approved by: Christopher Townsend
Approved revision: no longer in the source branch.
Merged at revision: 3632
Proposed branch: lp://qastaging/~3v1n0/unity/unity-decorations
Merge into: lp://qastaging/unity
Diff against target: 10234 lines (+6824/-1487)
64 files modified
CMakeLists.txt (+5/-0)
config.h.cmake (+1/-0)
decorations/CMakeLists.txt (+38/-0)
decorations/DecoratedWindow.cpp (+654/-0)
decorations/DecoratedWindow.h (+73/-0)
decorations/DecorationsDataPool.cpp (+153/-0)
decorations/DecorationsDataPool.h (+59/-0)
decorations/DecorationsEdge.cpp (+137/-0)
decorations/DecorationsEdge.h (+64/-0)
decorations/DecorationsEdgeBorders.cpp (+99/-0)
decorations/DecorationsEdgeBorders.h (+43/-0)
decorations/DecorationsGrabEdge.cpp (+102/-0)
decorations/DecorationsGrabEdge.h (+53/-0)
decorations/DecorationsInputMixer.cpp (+176/-0)
decorations/DecorationsInputMixer.h (+66/-0)
decorations/DecorationsManager.cpp (+386/-0)
decorations/DecorationsManager.h (+74/-0)
decorations/DecorationsPriv.h (+165/-0)
decorations/DecorationsTitle.cpp (+116/-0)
decorations/DecorationsTitle.h (+61/-0)
decorations/DecorationsWidgets.cpp (+493/-0)
decorations/DecorationsWidgets.h (+190/-0)
decorations/DecorationsWindowButton.cpp (+216/-0)
decorations/DecorationsWindowButton.h (+58/-0)
decorations/pch/decorations_pch.hh (+39/-0)
panel/PanelMenuView.cpp (+116/-254)
panel/PanelMenuView.h (+9/-14)
plugins/unityshell/CMakeLists.txt (+27/-2)
plugins/unityshell/src/unityshell.cpp (+291/-412)
plugins/unityshell/src/unityshell.h (+29/-17)
plugins/unityshell/src/unityshell_glow.cpp (+4/-9)
plugins/unityshell/unityshell.xml.in (+69/-1)
tests/CMakeLists.txt (+14/-9)
tests/decoration_mock_item.h (+88/-0)
tests/test_decorations_input_mixer.cpp (+493/-0)
tests/test_decorations_widgets.cpp (+512/-0)
tests/test_texture_cache.cpp (+16/-1)
tests/test_unity_window_style.cpp (+3/-3)
unity-shared/CMakeLists.txt (+14/-1)
unity-shared/CompizUtils.cpp (+181/-0)
unity-shared/CompizUtils.h (+116/-0)
unity-shared/DebugDBusInterface.cpp (+6/-1)
unity-shared/DecorationStyle.cpp (+640/-0)
unity-shared/DecorationStyle.h (+141/-0)
unity-shared/Introspectable.cpp (+4/-1)
unity-shared/IntrospectionData.cpp (+21/-0)
unity-shared/IntrospectionData.h (+8/-0)
unity-shared/PanelStyle.cpp (+58/-259)
unity-shared/PanelStyle.h (+16/-38)
unity-shared/PluginAdapter.cpp (+28/-311)
unity-shared/PluginAdapter.h (+0/-22)
unity-shared/StandaloneDecorationStyle.cpp (+146/-0)
unity-shared/StandaloneWindowManager.cpp (+15/-20)
unity-shared/StandaloneWindowManager.h (+2/-3)
unity-shared/TextureCache.cpp (+6/-3)
unity-shared/TextureCache.h (+3/-2)
unity-shared/UnityWindowStyle.cpp (+1/-1)
unity-shared/UnityWindowStyle.h (+1/-1)
unity-shared/WindowButtonPriv.h (+1/-0)
unity-shared/WindowButtons.cpp (+69/-79)
unity-shared/WindowButtons.h (+1/-0)
unity-shared/WindowManager.h (+4/-5)
unity-shared/XWindowManager.cpp (+146/-11)
unity-shared/XWindowManager.h (+4/-7)
To merge this branch: bzr merge lp://qastaging/~3v1n0/unity/unity-decorations
Reviewer Review Type Date Requested Status
Christopher Townsend (community) Approve
Brandon Schaefer (community) Approve
PS Jenkins bot (community) continuous-integration Approve
Review via email: mp+202582@code.qastaging.launchpad.net

Commit message

decorations: added new unity-decorations fully gtk-css-themed inside unity

Description of the change

Added new decorations to unity, inside unity itself instead of depending on the
compiz "decor" plugin and on a decorator (gtk-window-decorator).
My mission: «Everything changes, but nothing changes»; so completely new backend,
same results.

- Support for full Gtk3 Theming (https://wiki.ubuntu.com/Unity/Theming)
- Improved resizing speed when using "Normal Resize" in compiz
- Removed duplicated textures, IPC between compiz and the decorator
- Anti aliased corners!!

Screenshot:
 - Ambiance: http://ubuntuone.com/0QIWISIXmf1zRJfDiIqLHz
 - Radiance: http://ubuntuone.com/1CfUWwRj0xICU3otSfjTyY

Things to do:
- Add right-click window menu support
- Add "force quit" dialog

Not supported:
- Window buttons positions (we want a consistent user experience in unity, that
  covers both the windows and the top panel and here the window buttons are, by
  design on the top left corner of a window. Always).
- Custom actions on bar clicks (maybe to be supported later)
- Different decorators, just use themes.

This branch needs has a "soft dependency" on lp:~3v1n0/ubuntu-themes/unity-decorations
(for proper theming) and on lp:~3v1n0/compiz/disable-decor-with-unity to disable
decor plugin on settings.

=================

Technical details (use a better diff visualizer for review, like bzr qdiff):

- Added DecorationsManager: that handles all the windows, creates them and
  redirect to the proper target the relative events.
- DecoratedWindow: wraps a CompWindow, set the extents, generates the background
  textures, the top layout and draws them on screen.

Both DecorationsManager is allocated and controlled by UnityScreen (that redirects
the events to it), while each UnityWindow controls a DecoratedWindow, and redirects
to it the relevant compiz calls.

As for the decoration widgets, since I needed a simple way to handle textures and
to create a simple layout for displaying them, depending on the window size and
positioning, I've decided to write a small "widgets library" used to paint elements
and handle input events. What I called decoration::Item is basically a simple
widget with a geometry and that can be added into a container and managed by it.
Also, I've built an "InputMixer" (event compositor) that has the role to redirect
events to the proper widget that it manages.

So, with these tools, I've built all the widgets that are in a decoration:
 - A DecorationsEdgeBorders, that is a container of DecorationsGrabEdge, that are
   input-only widgets that care about mouse events, draw the right mouse pointers
   and allow to resize and move a window (now the GrabEdge has the same logic of
   the PanelGrabArea).
 - A Layout containing the window buttons and the window title.

To properly theme the decorations I've built a decoration::Style class that
defines custom gtk-css parameters for an "UnityDecoration" widget that is used
for theming the whole decorations; read the values, caches the relevant settings
and emits signals when theme or font parameters changes. panel::Style has been
rewritten to use decoration::Style as its main source.

Other aspects:
- Removed all the unneeded code for decorating, undecorating and monitoring
  decorations from PluginAdapter.
- Moved some XLib-only calls from PluginAdapter to XWindowManager and optimized
  GetWindowName using the new GetStringProperty.
- Removing the unneeded code from PanelMenuView that was handling the decorations
  and use decoration::Style on it; also remove a lot of unneeded redraws.
- Use decoration::Style for painting fake-decorations in UnityWindow.
- Added CompizUtils to unity-shared-compiz, that contains some structs, classes
  and functions that are useful for other components that are handling things
  with compiz (allows removing duplicated code from UnityWindow as well).
- Added decoration::DataPool utility class to load and cache shared resources
- Shadows are based on simple pixmaps that are generated through cairo just
  once per session (or when the shadow settings change) and shared by all
  the windows.
- Fixed linking of standalone components (and tests) against libunity-protocol-private
  (now the library dir is added to dpath, no need to use LD_LIBRARY_PATH any more).
- Added compiz settings to override theme shadow parameters.
- Improved fallback window buttons (now they're filled with foreground color).
- All the decoration objects support debug introspection for autopilot tests.
- Added unit tests for decoration::Item and InputMixer, more tests to come later.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

On a side note this only causes 4 conflicts in my panel high dpi code!

Text conflict in unity-shared/PanelStyle.cpp
Text conflict in unity-shared/PanelStyle.h
Text conflict in unity-shared/WindowButtonPriv.h
Text conflict in unity-shared/WindowButtons.cpp
4 conflicts encountered.

So it shouldn't be to bad to merge those over this. Ill get on that tomorrow after I finish going through this!

Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :
Download full text (6.5 KiB)

Ignore what I already sent you! Im at about 7-8k (The test looked good!) What I have so far:

You shouldn't need the ';' but i could be wrong

+ set(UNITY_STANDALONE_LADD ${UNITY_STANDALONE_LADD};${UNITY_PROTOCOL_PRIVATE_LIB})

----

To make things a but more readable, we should split this function into 2 smaller functions that accept the frame_geo as an arguments:

+void Window::Impl::UpdateFrame()

1, + if (!frame_), should then just call CreateNewFrame(frame_geo);

2, + if (frame_geo_ != frame_geo), UpdateFrameGeo(frame_geo) ... or something like that, so the function will just look like:

+void Window::Impl::UpdateFrame()
+{
+ auto const& input = win_->input();
+ auto const& server = win_->serverGeometry();
+ nux::Geometry frame_geo(0, 0, server.widthIncBorders() + input.left + input.right,
+ server.heightIncBorders() + input.top + input.bottom);
+
+ if (win_->shaded())
+ frame_geo.height = input.top + input.bottom;
+
+ if (!frame_)
+ CreateNewFrame(frame_geo);
+
+ if (frame_geo_ != frame_geo)
+ UpdateFrameGeo(frame_geo);
+}

Just makes things a bit more readable, imo.

----

An if statement is a bit more readable here.

+ return active() || parent_->scaled() ? mi->active_shadow_pixmap_->texture() : mi->inactive_shadow_pixmap_->texture();

+ return active() || parent_->scaled() ? manager_->active_shadow_radius() : manager_->inactive_shadow_radius();

----

Should be a const pointer, or rather could be a const pointer to const data:

auto const* const texture.

+ auto* texture = ShadowTexture();

+ auto* win = impl_->win_;

----

Are these just for testing? As I see a lot of friend classes...which kind of defeats the purpose of encapsulation. It'll make it hard to track down bugs when all these other classes have access to the private members.... I would much rather provide an access function to these for Read only if thats whats needed. (Vs having read/write of private members.)

+ friend class Manager;

+ friend class Window;

+ friend class Window;
+ friend struct Manager::Impl;

+ friend class Manager;
+ friend struct Window::Impl;

+ friend class InputMixer;

+ friend class Item;

+ friend class decoration::Manager;

+ friend class decoration::Window;
+ friend class decoration::Manager;

----

Why make a global read/write variable for this? This should be part of the class.

+Display* dpy = nullptr;

----

You can simply this:

+EdgeBorders::EdgeBorders(CompWindow* win)
+{
+ items_.resize(size_t(Edge::Type::Size));
+
+ auto item = std::make_shared<Edge>(win, Edge::Type::TOP);
+ items_[unsigned(Edge::Type::TOP)] = item;
+
+ item = std::make_shared<Edge>(win, Edge::Type::TOP_LEFT);
+ items_[unsigned(Edge::Type::TOP_LEFT)] = item;
+
+ item = std::make_shared<Edge>(win, Edge::Type::TOP_RIGHT);
+ items_[unsigned(Edge::Type::TOP_RIGHT)] = item;
+
+ item = std::make_shared<Edge>(win, Edge::Type::LEFT);
+ items_[unsigned(Edge::Type::LEFT)] = item;
+
+ item = std::make_shared<Edge>(win, Edge::Type::RIGHT);
+ items_[unsigned(Edge::Type::RIGHT)] = item;
+
+ item = std::make_shared<Edge>(win, Edge::Type::BOTTOM);
+ items_[unsigned(Edge::Type::BOTTOM)] = item;
+
+ item = std::...

Read more...

Revision history for this message
Marco Trevisan (Treviño) (3v1n0) wrote :
Download full text (8.3 KiB)

> You shouldn't need the ';' but i could be wrong
>
> + set(UNITY_STANDALONE_LADD ${UNITY_STANDALONE_LADD};${UNITY_PROTOCOL_PRIVATE_LIB})

Oh, I thought I had a linking error without it, but it seems to go...
So, I've removed it. This is with gold btw.

> To make things a but more readable, we should split this function into 2 smaller
> functions that accept the frame_geo as an arguements:
>
> +void Window::Impl::UpdateFrame()
>
> 1, + if (!frame_), should then just call CreateNewFrame(frame_geo);

> 2, + if (frame_geo_ != frame_geo), UpdateFrameGeo(frame_geo) ... or something like that, so the function will just look like:
>
> +void Window::Impl::UpdateFrame()
> +{
> + auto const& input = win_->input();
> + auto const& server = win_->serverGeometry();
> + nux::Geometry frame_geo(0, 0, server.widthIncBorders() + input.left + input.right,
> + server.heightIncBorders() + input.top + input.bottom);
> +
> + if (win_->shaded())
> + frame_geo.height = input.top + input.bottom;
> +
> + if (!frame_)
> + CreateNewFrame(frame_geo);
> +
> + if (frame_geo_ != frame_geo)
> + UpdateFrameGeo(frame_geo);
> +}
>

Ok, sounds good!
I didn't that to keep the frame_geo in the same function without passing it, and
not to reclare input, in UpdateFrameGeo, but it's not really a problem.
I think you're right.

> An if statement is a bit more readable here.

> + return active() || parent_->scaled() ? mi->active_shadow_pixmap_->texture() : mi->inactive_shadow_pixmap_->texture();

> + return active() || parent_->scaled() ? manager_->active_shadow_radius() : manager_->inactive_shadow_radius();

Agreedo, it was smaller at the beginning, then it got bigger :P.

> Should be a const pointer, or rather could be a const pointer to const data:
>
> auto const* const texture.
>
> + auto* texture = ShadowTexture();
>
> + auto* win = impl_->win_;
>
> ----

It doesn't change much, but ok.

> Are these just for testing? As I see a lot of friend classes...which kind of
> defeats the purpose of encaspulation. It'll make it hard to track down bugs when
> all these other classes have access to the private members.... I would much rather
> provide an access funtion to these for Read only if thats whats needed. (Vs having
> read/write of private members.)
>
> + friend class Manager;

Unfortunately I need these to make possible to a Window to access to Impl
functions that are private, but not for manager... I mean, decoration::Manager
is strictly connected to the windows and it has to access to some methods that I
don't want to make visible to everyone... So, unfortunately here we can't use
protected in the way is in java or other languages (access to the members of the
"package"), so I need to use this way... That I don't like, but it's the only
method we have to access to private methods in very limited cases.
For sure the friendship with UnityScreen/UnityWindow can be removed (it was there
for testing), and I could also remove the friendship with the Impl structs, by
just adding some more "public" methods to them, so that there's no private write
access to the members... That's what already happens in fact, but if we want to
protect more I...

Read more...

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Brandon Schaefer (brandontschaefer) wrote :

I've been using this branch for about a week now, and its working well!

Would like at lease one more person to go through the code, as this is a larger branch!

review: Approve
Revision history for this message
Christopher Townsend (townsend) wrote :

This works well for me too and I have nothing to add on the code itself. Well done!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
The diff is not available at this time. You can reload the page or download it.