summaryrefslogtreecommitdiff
path: root/plugins
diff options
Diffstat (limited to 'plugins')
-rw-r--r--plugins/unityshell/CMakeLists.txt2
-rw-r--r--plugins/unityshell/src/WindowMinimizeSpeedController.cpp108
-rw-r--r--plugins/unityshell/src/WindowMinimizeSpeedController.h57
-rw-r--r--plugins/unityshell/src/unityshell.cpp477
-rw-r--r--plugins/unityshell/src/unityshell.h48
-rw-r--r--plugins/unityshell/unityshell.xml.in20
6 files changed, 684 insertions, 28 deletions
diff --git a/plugins/unityshell/CMakeLists.txt b/plugins/unityshell/CMakeLists.txt
index eaf2047a3..c6ad6f75d 100644
--- a/plugins/unityshell/CMakeLists.txt
+++ b/plugins/unityshell/CMakeLists.txt
@@ -6,7 +6,7 @@ set (COMPIZ_PLUGIN_INSTALL_TYPE "package")
compiz_plugin (unityshell
PKGDEPS ${UNITY_PLUGIN_DEPS}
- PLUGINDEPS composite opengl compiztoolbox
+ PLUGINDEPS composite opengl compiztoolbox scale
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/"
LIBDIRS "${CMAKE_BINARY_DIR}/UnityCore"
)
diff --git a/plugins/unityshell/src/WindowMinimizeSpeedController.cpp b/plugins/unityshell/src/WindowMinimizeSpeedController.cpp
new file mode 100644
index 000000000..66f28d8fc
--- /dev/null
+++ b/plugins/unityshell/src/WindowMinimizeSpeedController.cpp
@@ -0,0 +1,108 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/* Compiz unity plugin
+ * unity.h
+ *
+ * Copyright (c) 2010-11 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Your own copyright notice would go above. You are free to choose whatever
+ * licence you want, just take note that some compiz code is GPL and you will
+ * not be able to re-use it if you want to use a different licence.
+ */
+
+#include <gio/gio.h>
+#include <NuxCore/Logger.h>
+
+#include "WindowMinimizeSpeedController.h"
+
+namespace
+{
+
+nux::logging::Logger logger ("unity.WindowMinimizeSpeedController");
+
+namespace local
+{
+const std::string UNITY_SCHEMA = "com.canonical.Unity";
+}
+}
+
+WindowMinimizeSpeedController::WindowMinimizeSpeedController()
+ : _settings(g_settings_new(local::UNITY_SCHEMA.c_str()))
+ , _minimize_count(g_settings_get_int(_settings, "minimize-count"))
+ , _minimize_speed_threshold(g_settings_get_int(_settings, "minimize-speed-threshold"))
+ , _minimize_slow_duration(g_settings_get_int(_settings, "minimize-slow-duration"))
+ , _minimize_fast_duration(g_settings_get_int(_settings, "minimize-fast-duration"))
+{
+ _minimize_count_changed.Connect(_settings, "changed::minimize-count",
+ [&] (GSettings*, gchar* name) {
+ _minimize_count = g_settings_get_int(_settings, name);
+ SetDuration();
+ });
+ _minimize_speed_threshold_changed.Connect(_settings, "changed::minimize-speed-threshold",
+ [&] (GSettings*, gchar* name) {
+ _minimize_speed_threshold = g_settings_get_int(_settings, name);
+ SetDuration();
+ });
+ _minimize_fast_duration_changed.Connect(_settings, "changed::minimize-fast-duration",
+ [&] (GSettings*, gchar* name) {
+ _minimize_fast_duration = g_settings_get_int(_settings, name);
+ SetDuration();
+ });
+ _minimize_slow_duration_changed.Connect(_settings, "changed::minimize-slow-duration",
+ [&] (GSettings*, gchar* name) {
+ _minimize_slow_duration = g_settings_get_int(_settings, name);
+ SetDuration();
+ });
+}
+
+void WindowMinimizeSpeedController::UpdateCount()
+{
+ if (_minimize_count < _minimize_speed_threshold) {
+ _minimize_count += 1;
+ g_settings_set_int(_settings, "minimize-count", _minimize_count);
+ }
+}
+
+int WindowMinimizeSpeedController::getDuration()
+{
+ return mDuration;
+}
+
+void WindowMinimizeSpeedController::SetDuration()
+{
+ /* Perform some sanity checks on the configuration values */
+ if (_minimize_fast_duration > _minimize_slow_duration)
+ {
+ LOG_WARN(logger) << "Configuration mismatch: minimize-fast-duration ("
+ << _minimize_fast_duration
+ << ") is longer than minimize-slow-duration ("
+ << _minimize_slow_duration << "). Not changing speed.";
+ return;
+ }
+
+ if (_minimize_count < 0)
+ _minimize_count = 0;
+ if (_minimize_count > _minimize_speed_threshold)
+ _minimize_count = _minimize_speed_threshold;
+
+ /* Adjust the speed so that it gets linearly closer to maximum speed as we
+ approach the threshold */
+ int speed_range = _minimize_slow_duration - _minimize_fast_duration;
+ float position = (_minimize_speed_threshold <= 0) ? 1.0 :
+ static_cast<float>(_minimize_count) / _minimize_speed_threshold;
+ int duration = _minimize_slow_duration - std::ceil(position * speed_range);
+
+ if (duration != mDuration) {
+ mDuration = duration;
+ DurationChanged.emit();
+ }
+}
diff --git a/plugins/unityshell/src/WindowMinimizeSpeedController.h b/plugins/unityshell/src/WindowMinimizeSpeedController.h
new file mode 100644
index 000000000..49bcbad14
--- /dev/null
+++ b/plugins/unityshell/src/WindowMinimizeSpeedController.h
@@ -0,0 +1,57 @@
+// -*- Mode: C++; indent-tabs-mode: nil; tab-width: 2 -*-
+/* Compiz unity plugin
+ * unity.h
+ *
+ * Copyright (c) 2010-11 Canonical Ltd.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * Your own copyright notice would go above. You are free to choose whatever
+ * licence you want, just take note that some compiz code is GPL and you will
+ * not be able to re-use it if you want to use a different licence.
+ */
+
+#ifndef WINDOWMINIMIZESPEEDCONTROLLER_H
+#define WINDOWMINIMIZESPEEDCONTROLLER_H
+
+#include <core/core.h>
+#include <UnityCore/GLibWrapper.h>
+#include <UnityCore/GLibSignal.h>
+#include <sigc++/sigc++.h>
+
+typedef struct _GSettings GSettings;
+
+using namespace unity;
+
+class WindowMinimizeSpeedController
+{
+public:
+ WindowMinimizeSpeedController();
+ void UpdateCount();
+ int getDuration();
+ sigc::signal<void> DurationChanged;
+
+private:
+ void SetDuration();
+
+ glib::Object<GSettings> _settings;
+ int _minimize_count;
+ int _minimize_speed_threshold;
+ int _minimize_slow_duration;
+ int _minimize_fast_duration;
+ glib::Signal<void, GSettings*, gchar* > _minimize_count_changed;
+ glib::Signal<void, GSettings*, gchar* > _minimize_speed_threshold_changed;
+ glib::Signal<void, GSettings*, gchar* > _minimize_slow_duration_changed;
+ glib::Signal<void, GSettings*, gchar* > _minimize_fast_duration_changed;
+ int mDuration;
+};
+
+#endif // WINDOWMINIMIZESPEEDCONTROLLER_H
diff --git a/plugins/unityshell/src/unityshell.cpp b/plugins/unityshell/src/unityshell.cpp
index 450618c1e..e3c187d7d 100644
--- a/plugins/unityshell/src/unityshell.cpp
+++ b/plugins/unityshell/src/unityshell.cpp
@@ -29,7 +29,6 @@
#include "Launcher.h"
#include "LauncherIcon.h"
#include "LauncherController.h"
-#include "DevicesSettings.h"
#include "PluginAdapter.h"
#include "QuicklistManager.h"
#include "StartupNotifyService.h"
@@ -44,6 +43,9 @@
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <libnotify/notify.h>
+#include <cairo-xlib-xrender.h>
+
+#include <text/text.h>
#include <sstream>
#include <memory>
@@ -81,6 +83,10 @@ nux::logging::Logger logger("unity.shell");
UnityScreen* uScreen = 0;
+static unsigned int CLOSE_ICON_SIZE = 19;
+static unsigned int CLOSE_ICON_SPACE = 5;
+static unsigned int SCALE_WINDOW_TITLE_SIZE = 28;
+
void reset_glib_logging();
void configure_logging();
void capture_g_log_calls(const gchar* log_domain,
@@ -101,6 +107,34 @@ const std::string RELAYOUT_TIMEOUT = "relayout-timeout";
} // namespace local
} // anon namespace
+class WindowCairoContext
+{
+ public:
+ Pixmap pixmap_;
+ cairo_surface_t* surface_;
+ GLTexture::List texture_;
+ cairo_t *cr_;
+
+ WindowCairoContext ()
+ : pixmap_ (0), surface_ (0), cr_ (0)
+ {
+ }
+
+ ~WindowCairoContext ()
+ {
+ if (cr_)
+ cairo_destroy (cr_);
+
+ if (surface_)
+ cairo_surface_destroy (surface_);
+
+ texture_.clear ();
+
+ if (pixmap_)
+ XFreePixmap (screen->dpy (), pixmap_);
+ }
+};
+
UnityScreen::UnityScreen(CompScreen* screen)
: BaseSwitchScreen (screen)
, PluginClassHandler <UnityScreen, CompScreen> (screen)
@@ -126,6 +160,8 @@ UnityScreen::UnityScreen(CompScreen* screen)
, panel_texture_has_changed_(true)
, paint_panel_(false)
, scale_just_activated_(false)
+ , highlighted_window_(0)
+ , minimize_speed_controller(new WindowMinimizeSpeedController())
{
Timer timer;
#ifndef USE_GLES
@@ -259,7 +295,6 @@ UnityScreen::UnityScreen(CompScreen* screen)
optionSetIconSizeNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
optionSetAutohideAnimationNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
optionSetDashBlurExperimentalNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
- optionSetDevicesOptionNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
optionSetShortcutOverlayNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
optionSetShowDesktopIconNotify(boost::bind(&UnityScreen::optionChanged, this, _1, _2));
optionSetShowLauncherInitiate(boost::bind(&UnityScreen::showLauncherKeyInitiate, this, _1, _2, _3));
@@ -364,6 +399,10 @@ UnityScreen::UnityScreen(CompScreen* screen)
}
panel::Style::Instance().changed.connect(sigc::mem_fun(this, &UnityScreen::OnPanelStyleChanged));
+
+ minimize_speed_controller->DurationChanged.connect(
+ sigc::mem_fun(this, &UnityScreen::OnMinimizeDurationChanged)
+ );
}
UnityScreen::~UnityScreen()
@@ -1004,6 +1043,11 @@ void UnityWindow::handleEvent (XEvent *event)
}
}
+CompRect UnityWindow::closeButtonArea ()
+{
+ return close_button_area_;
+}
+
bool UnityScreen::shellCouldBeHidden(CompOutput const& output)
{
std::vector<Window> const& nuxwins(nux::XInputWindow::NativeHandleList());
@@ -1285,6 +1329,24 @@ void UnityScreen::handleEvent(XEvent* event)
launcher_controller_->KeyNavTerminate(false);
EnableCancelAction(CancelActionTarget::LAUNCHER_SWITCHER, false);
}
+ if (PluginAdapter::Default()->IsScaleActive() &&
+ event->xbutton.button == Button1 &&
+ highlighted_window_ != 0)
+ {
+ CompWindow *w = screen->findWindow (highlighted_window_);
+ if (w)
+ {
+ UnityWindow *uw = UnityWindow::get (w);
+ CompPoint pointer (pointerX, pointerY);
+ if (uw->closeButtonArea ().contains (pointer))
+ {
+ w->close (0);
+ skip_other_plugins = true;
+ }
+ }
+
+ }
+
break;
case ButtonRelease:
if (switcher_controller_ && switcher_controller_->Visible())
@@ -2238,6 +2300,40 @@ bool UnityWindow::glDraw(const GLMatrix& matrix,
}
void
+UnityScreen::OnMinimizeDurationChanged ()
+{
+ /* Update the compiz plugin setting with the new computed speed so that it
+ * will be used in the following minimizations */
+ CompPlugin *p = CompPlugin::find("animation");
+ if (p)
+ {
+ CompOption::Vector &opts = p->vTable->getOptions();
+
+ for (CompOption &o : opts)
+ {
+ if (o.name () == std::string ("minimize_durations"))
+ {
+ /* minimize_durations is a list value, but minimize applies only to
+ * normal windows, so there's always one value */
+ CompOption::Value& value = o.value();
+ CompOption::Value::Vector& list = value.list();
+ CompOption::Value::Vector::iterator i = list.begin();
+ if (i != list.end()) {
+ i->set(minimize_speed_controller->getDuration());
+ }
+ value.set(list);
+ screen->setOptionForPlugin(p->vTable->name().c_str(),
+ o.name().c_str(), value);
+ break;
+ }
+ }
+ }
+ else {
+ LOG_WARN(logger) << "Animation plugin not found. Can't set minimize speed.";
+ }
+}
+
+void
UnityWindow::minimize ()
{
if (!window->managed ())
@@ -2353,6 +2449,11 @@ void UnityWindow::windowNotify(CompWindowNotify n)
case CompWindowNotifyBeforeDestroy:
being_destroyed.emit();
break;
+ case CompWindowNotifyMinimize:
+ /* Updating the count in dconf will trigger a "changed" signal to which
+ * the method setting the new animation speed is attached */
+ UnityScreen::get(screen)->minimize_speed_controller->UpdateCount();
+ break;
default:
break;
}
@@ -2621,9 +2722,6 @@ void UnityScreen::optionChanged(CompOption* opt, UnityshellOptions::Options num)
case UnityshellOptions::AutomaximizeValue:
PluginAdapter::Default()->SetCoverageAreaBeforeAutomaximize(optionGetAutomaximizeValue() / 100.0f);
break;
- case UnityshellOptions::DevicesOption:
- unity::DevicesSettings::GetDefault().SetDevicesOption((unity::DevicesSettings::DevicesOption) optionGetDevicesOption());
- break;
case UnityshellOptions::AltTabTimeout:
switcher_controller_->detail_on_timeout = optionGetAltTabTimeout();
case UnityshellOptions::AltTabBiasViewport:
@@ -3058,9 +3156,11 @@ UnityWindow::UnityWindow(CompWindow* window)
, gWindow(GLWindow::get(window))
, mMinimizeHandler()
, mShowdesktopHandler(nullptr)
+ , window_header_style_(0)
{
WindowInterface::setHandler(window);
GLWindowInterface::setHandler(gWindow);
+ ScaleWindowInterface::setHandler (ScaleWindow::get (window));
if (UnityScreen::get (screen)->optionGetShowMinimizedWindows () &&
window->mapNum ())
@@ -3105,6 +3205,292 @@ UnityWindow::UnityWindow(CompWindow* window)
}
}
+void UnityWindow::DrawTexture (GLTexture* icon,
+ const GLWindowPaintAttrib& attrib,
+ const GLMatrix& transform,
+ unsigned int mask,
+ float x, float y,
+ int &maxWidth, int &maxHeight)
+{
+ if (icon)
+ {
+ int width, height;
+ width = icon->width ();
+ height = icon->height ();
+
+ if (height > maxHeight)
+ maxHeight = height;
+
+ if (width > maxWidth)
+ maxWidth = width;
+
+ CompRegion iconReg (0, 0, width, height);
+ GLTexture::MatrixList ml (1);
+
+ ml[0] = icon->matrix ();
+ gWindow->vertexBuffer ()->begin ();
+ if (width && height)
+ gWindow->glAddGeometry (ml, iconReg, iconReg);
+
+ if (gWindow->vertexBuffer ()->end ())
+ {
+ GLMatrix wTransform (transform);
+
+ wTransform.translate (x, y, 0.0f);
+
+ gWindow->glDrawTexture (icon, wTransform, attrib, mask);
+ }
+ }
+}
+
+WindowCairoContext* UnityWindow::CreateCairoContext (float width, float height)
+{
+ XRenderPictFormat *format;
+ Screen *xScreen;
+ WindowCairoContext *context = new WindowCairoContext();
+
+ xScreen = ScreenOfDisplay (screen->dpy (), screen->screenNum ());
+
+ format = XRenderFindStandardFormat (screen->dpy (), PictStandardARGB32);
+ context->pixmap_ = XCreatePixmap (screen->dpy (),
+ screen->root (),
+ width, height, 32);
+
+ context->texture_ = GLTexture::bindPixmapToTexture (context->pixmap_,
+ width, height,
+ 32);
+ if (context->texture_.empty ())
+ {
+ delete context;
+ return 0;
+ }
+
+ context->surface_ = cairo_xlib_surface_create_with_xrender_format (screen->dpy (),
+ context->pixmap_,
+ xScreen,
+ format,
+ width,
+ height);
+ context->cr_ = cairo_create (context->surface_);
+
+ // clear
+ cairo_save (context->cr_);
+ cairo_set_operator (context->cr_, CAIRO_OPERATOR_CLEAR);
+ cairo_paint (context->cr_);
+ cairo_restore (context->cr_);
+
+ return context;
+}
+
+void UnityWindow::RenderText (WindowCairoContext *context,
+ float x, float y,
+ float maxWidth, float maxHeight)
+{
+ PangoFontDescription* font = pango_font_description_new ();
+ pango_font_description_set_family (font, "sans");
+ pango_font_description_set_absolute_size (font, 12 * PANGO_SCALE);
+ pango_font_description_set_style (font, PANGO_STYLE_NORMAL);
+ pango_font_description_set_weight (font, PANGO_WEIGHT_BOLD);
+
+ PangoLayout* layout = pango_cairo_create_layout (context->cr_);
+ pango_layout_set_font_description (layout, font);
+ pango_layout_set_ellipsize (layout, PANGO_ELLIPSIZE_END);
+ pango_layout_set_height (layout, maxHeight);
+
+ pango_layout_set_auto_dir (layout, false);
+ pango_layout_set_text (layout,
+ GetWindowName (window->id ()).c_str (),
+ -1);
+
+ /* update the size of the pango layout */
+ pango_layout_set_width (layout, maxWidth * PANGO_SCALE);
+ pango_cairo_update_layout (context->cr_, layout);
+
+ cairo_set_operator (context->cr_, CAIRO_OPERATOR_OVER);
+
+ cairo_set_source_rgba (context->cr_,
+ 1.0,
+ 1.0,
+ 1.0,
+ 1.0);
+
+ // alignment
+ int lWidth, lHeight;
+ pango_layout_get_pixel_size (layout, &lWidth, &lHeight);
+
+ y = ((maxHeight - lHeight) / 2.0) + y;
+ cairo_translate (context->cr_, x, y);
+ pango_cairo_show_layout (context->cr_, layout);
+}
+
+void UnityWindow::DrawWindowTitle (const GLWindowPaintAttrib& attrib,
+ const GLMatrix& transform,
+ unsigned int mask,
+ float x, float y, float x2, float y2)
+{
+ const float width = x2 - x;
+
+ // Paint a fake window decoration
+ WindowCairoContext *context = CreateCairoContext (width, SCALE_WINDOW_TITLE_SIZE);
+
+ cairo_save (context->cr_);
+ cairo_push_group (context->cr_);
+
+ // Round window decoration top border
+ const double height = SCALE_WINDOW_TITLE_SIZE;
+ const double aspect = 1.0;
+ const double corner_radius = height / 10.0;
+ const double radius = corner_radius / aspect;
+ const double degrees = M_PI / 180.0;
+
+ cairo_new_sub_path (context->cr_);
+
+ cairo_arc (context->cr_, radius, radius, radius, 180 * degrees, 270 * degrees);
+ cairo_arc (context->cr_, width - radius, radius, radius, -90 * degrees, 0 * degrees);
+ cairo_line_to (context->cr_, width, height);
+ cairo_line_to (context->cr_, 0, height);
+
+ cairo_close_path (context->cr_);
+ cairo_clip (context->cr_);
+
+ // Draw window decoration abased on gtk style
+ gtk_render_background (window_header_style_, context->cr_, 0, 0, width, SCALE_WINDOW_TITLE_SIZE);
+ gtk_render_frame (window_header_style_, context->cr_, 0, 0, width, SCALE_WINDOW_TITLE_SIZE);
+
+ cairo_pop_group_to_source (context->cr_);
+
+ cairo_paint_with_alpha (context->cr_, 1.0);
+ cairo_restore (context->cr_);
+
+ // Draw windows title
+ RenderText (context,
+ CLOSE_ICON_SPACE * 2 + CLOSE_ICON_SIZE,
+ 0.0,
+ width, SCALE_WINDOW_TITLE_SIZE);
+
+ mask |= PAINT_WINDOW_BLEND_MASK;
+ int maxWidth, maxHeight;
+ foreach(GLTexture *icon, context->texture_)
+ {
+ DrawTexture (icon, attrib, transform, mask,
+ x, y,
+ maxWidth , maxHeight);
+ }
+
+ delete context;
+}
+
+void UnityWindow::scalePaintDecoration (const GLWindowPaintAttrib& attrib,
+ const GLMatrix& transform,
+ const CompRegion& region,
+ unsigned int mask)
+{
+ ScaleWindow *sWindow = ScaleWindow::get (window);
+ if (!sWindow)
+ return;
+
+ sWindow->scalePaintDecoration (attrib, transform, region, mask);
+
+ if (!sWindow->hasSlot()) // animation not finished
+ return;
+
+ if (!window_header_style_)
+ {
+ GtkWidgetPath* widget_path = gtk_widget_path_new ();
+ gint pos = gtk_widget_path_append_type (widget_path, GTK_TYPE_WINDOW);
+ gtk_widget_path_iter_set_name (widget_path, pos, "UnityPanelWidget");
+
+ window_header_style_ = gtk_style_context_new ();
+ gtk_style_context_set_path (window_header_style_, widget_path);
+ gtk_style_context_add_class (window_header_style_, "gnome-panel-menu-bar");
+ gtk_style_context_add_class (window_header_style_, "unity-panel");
+
+ // get close button
+ panel::Style& style = panel::Style::Instance();
+
+ std::vector<std::string> files = style.GetWindowButtonFileNames (panel::WindowButtonType::CLOSE,
+ panel::WindowState::NORMAL);
+
+ CompString pName ("unityshell");
+ foreach (std::string file, files)
+ {
+ CompString fileName (file.c_str ());
+ CompSize size (CLOSE_ICON_SIZE, CLOSE_ICON_SIZE);
+ close_icon_ = GLTexture::readImageToTexture (fileName,
+ pName,
+ size);
+ if (close_icon_.size () != 0)
+ break;
+ }
+
+ if (close_icon_.size () == 0)
+ {
+ CompString fileName (PKGDATADIR"/close_dash.png");
+ CompSize size (CLOSE_ICON_SIZE, CLOSE_ICON_SIZE);
+ close_icon_ = GLTexture::readImageToTexture (fileName,
+ pName,
+ size);
+ }
+ }
+
+ // Make the windows header opaque to override the original
+ GLWindowPaintAttrib sAttrib (attrib);
+ sAttrib.opacity = OPAQUE;
+
+ ScalePosition pos = sWindow->getCurrentPosition ();
+ int maxHeight, maxWidth;
+ // Use "2" as margin to make sure to cover all originial decoration
+ const float width = (window->width () + 4) * pos.scale;
+ const float x = pos.x () + window->x () - (2 * pos.scale);
+ const float y = pos.y () + window->y () - SCALE_WINDOW_TITLE_SIZE;
+ const float iconX = x + CLOSE_ICON_SPACE;
+ const float iconY = y + ((SCALE_WINDOW_TITLE_SIZE - CLOSE_ICON_SIZE) / 2.0);
+
+ maxHeight = maxWidth = 0;
+
+ DrawWindowTitle (sAttrib,
+ transform,
+ mask,
+ x, y,
+ x + width, y + SCALE_WINDOW_TITLE_SIZE);
+
+ mask |= PAINT_WINDOW_BLEND_MASK;
+ foreach(GLTexture *icon, close_icon_)
+ {
+ DrawTexture (icon, sAttrib, transform, mask,
+ iconX, iconY,
+ maxWidth , maxHeight);
+ }
+
+ close_button_area_ = CompRect (iconX, iconY, maxWidth, maxHeight);
+}
+
+void UnityWindow::scaleSelectWindow ()
+{
+ UnityScreen* us = UnityScreen::get(screen);
+
+ if (us->highlighted_window_ != window->id ())
+ {
+ CompositeWindow *cWindow = CompositeWindow::get (window);
+ if (cWindow)
+ cWindow->addDamage ();
+
+ cWindow = 0;
+ CompWindow *old_window = screen->findWindow (us->highlighted_window_);
+ if (old_window)
+ cWindow = CompositeWindow::get (old_window);
+
+ if (cWindow)
+ cWindow->addDamage ();
+
+ us->highlighted_window_ = window->id ();
+ }
+
+ ScaleWindow *sWindow = ScaleWindow::get (window);
+ if (sWindow)
+ sWindow->scaleSelectWindow ();
+}
+
UnityWindow::~UnityWindow()
{
UnityScreen* us = UnityScreen::get(screen);
@@ -3123,6 +3509,9 @@ UnityWindow::~UnityWindow()
window->minimize ();
}
+ if (window_header_style_)
+ g_object_unref (window_header_style_);
+
ShowdesktopHandler::animating_windows.remove (static_cast <ShowdesktopHandlerWindowInterface *> (this));
if (mShowdesktopHandler)
@@ -3162,6 +3551,84 @@ bool UnityPluginVTable::init()
return true;
}
+CompString UnityWindow::GetUtf8Property (Window id,
+ Atom atom)
+{
+ Atom type;
+ int result, format;
+ unsigned long nItems, bytesAfter;
+ char *val;
+ CompString retval;
+ Atom utf8StringAtom;
+
+ utf8StringAtom = XInternAtom (screen->dpy (), "UTF8_STRING", 0);
+ result = XGetWindowProperty (screen->dpy (), id, atom, 0L, 65536, False,
+ utf8StringAtom, &type, &format, &nItems,
+ &bytesAfter, (unsigned char **) &val);
+
+ if (result != Success)
+ return retval;
+
+ if (type == utf8StringAtom && format == 8 && val && nItems > 0)
+ {
+ char valueString[nItems + 1];
+ strncpy (valueString, val, nItems);
+ valueString[nItems] = 0;
+ retval = valueString;
+ }
+ if (val)
+ XFree (val);
+
+ return retval;
+}
+
+CompString UnityWindow::GetTextProperty (Window id,
+ Atom atom)
+{
+ XTextProperty text;
+ CompString retval;
+
+ text.nitems = 0;
+ if (XGetTextProperty (screen->dpy (), id, &text, atom))
+ {
+ if (text.value)
+ {
+ char valueString[text.nitems + 1];
+
+ strncpy (valueString, (char *) text.value, text.nitems);
+ valueString[text.nitems] = 0;
+
+ retval = valueString;
+
+ XFree (text.value);
+ }
+ }
+
+ return retval;
+}
+
+
+CompString UnityWindow::GetWindowName (Window id)
+{
+ CompString name;
+ Atom visibleNameAtom;
+
+ visibleNameAtom = XInternAtom (screen->dpy (), "_NET_WM_VISIBLE_NAME", 0);
+ name = GetUtf8Property (id, visibleNameAtom);
+ if (name.empty ())
+ {
+ Atom wmNameAtom = XInternAtom (screen->dpy (), "_NET_WM_NAME", 0);
+ name = GetUtf8Property (id, wmNameAtom);
+ }
+
+
+ if (name.empty ())
+ name = GetTextProperty (id, XA_WM_NAME);
+
+ return name;
+}
+
+
namespace
{
diff --git a/plugins/unityshell/src/unityshell.h b/plugins/unityshell/src/unityshell.h
index 4cf7be93b..b3000c42b 100644
--- a/plugins/unityshell/src/unityshell.h
+++ b/plugins/unityshell/src/unityshell.h
@@ -29,6 +29,7 @@
#include <sigc++/sigc++.h>
#include <boost/shared_ptr.hpp>
+#include <scale/scale.h>
#include <core/core.h>
#include <core/pluginclasshandler.h>
#include <composite/composite.h>
@@ -62,9 +63,13 @@
#include "HudController.h"
#include "ThumbnailGenerator.h"
+#include "WindowMinimizeSpeedController.h"
+
namespace unity
{
+class WindowCairoContext;
+
/* base screen class */
class UnityScreen :
public unity::debug::Introspectable,
@@ -182,6 +187,8 @@ public:
void SetUpAndShowSwitcher(switcher::ShowMode show_mode = switcher::ShowMode::CURRENT_VIEWPORT);
+ void OnMinimizeDurationChanged();
+
switcher::Controller::Ptr switcher_controller();
launcher::Controller::Ptr launcher_controller();
@@ -235,7 +242,7 @@ private:
void OnPanelStyleChanged();
void InitGesturesSupport();
-
+
nux::animation::TickSource tick_source_;
nux::animation::AnimationController animation_controller_;
@@ -323,7 +330,10 @@ private:
UBusManager ubus_manager_;
glib::SourceManager sources_;
unity::ThumbnailGenerator thumb_generator;
-
+
+ Window highlighted_window_;
+
+ WindowMinimizeSpeedController* minimize_speed_controller;
friend class UnityWindow;
};
@@ -332,6 +342,7 @@ class UnityWindow :
public GLWindowInterface,
public ShowdesktopHandlerWindowInterface,
public compiz::WindowInputRemoverLockAcquireInterface,
+ public WrapableHandler<ScaleWindowInterface, 4>,
public BaseSwitchWindow,
public PluginClassHandler <UnityWindow, CompWindow>
{
@@ -388,6 +399,8 @@ public:
void handleEvent (XEvent *event);
+ CompRect closeButtonArea ();
+
typedef compiz::CompizMinimizedWindowHandler<UnityScreen, UnityWindow>
UnityMinimizedHandler;
std::unique_ptr <UnityMinimizedHandler> mMinimizeHandler;
@@ -396,6 +409,13 @@ public:
//! Emited when CompWindowNotifyBeforeDestroy is received
sigc::signal<void> being_destroyed;
+
+ void scaleSelectWindow ();
+ void scalePaintDecoration (const GLWindowPaintAttrib &,
+ const GLMatrix &,
+ const CompRegion &,
+ unsigned int);
+
private:
void DoEnableFocus ();
void DoDisableFocus ();
@@ -427,8 +447,32 @@ private:
compiz::WindowInputRemoverLock::Ptr GetInputRemover ();
+ void DrawWindowTitle (const GLWindowPaintAttrib& attrib,
+ const GLMatrix& transform,
+ unsigned int mask,
+ float x, float y, float x2, float y2);
+ void DrawTexture (GLTexture *icon,
+ const GLWindowPaintAttrib& attrib,
+ const GLMatrix& transform,
+ unsigned int mask,
+ float x, float y,
+ int &maxWidth, int &maxHeight);
+ void RenderText (WindowCairoContext *context,
+ float x, float y,
+ float maxWidth, float maxHeight);
+ WindowCairoContext* CreateCairoContext (float width, float height);
+
+ // based on compiz text plugin
+ CompString GetWindowName (Window id);
+ CompString GetUtf8Property (Window id, Atom atom);
+ CompString GetTextProperty (Window id, Atom atom);
+
compiz::WindowInputRemoverLock::Weak input_remover_;
glib::Source::UniquePtr focus_desktop_timeout_;
+
+ GLTexture::List close_icon_;
+ CompRect close_button_area_;
+ GtkStyleContext* window_header_style_;
};
diff --git a/plugins/unityshell/unityshell.xml.in b/plugins/unityshell/unityshell.xml.in
index 1f0dab978..98571394a 100644
--- a/plugins/unityshell/unityshell.xml.in
+++ b/plugins/unityshell/unityshell.xml.in
@@ -394,26 +394,6 @@
<default>75</default>
</option>
- <option name="devices_option" type="int">
- <_short>Show Devices</_short>
- <_long>Show devices in the launcher</_long>
- <min>0</min>
- <max>2</max>
- <default>1</default>
- <desc>
- <value>0</value>
- <_name>Never</_name>
- </desc>
- <desc>
- <value>1</value>
- <_name>Only Mounted</_name>
- </desc>
- <desc>
- <value>2</value>
- <_name>Always</_name>
- </desc>
- </option>
-
<option name="shortcut_overlay" type="bool">
<_short>Enable Shortcut Hints Overlay</_short>
<_long>Enable Shortcut Hints Overlay</_long>