diff options
| author | Sam Spilsbury <sam.spilsbury@canonical.com> | 2012-09-05 08:44:06 +0800 |
|---|---|---|
| committer | Sam Spilsbury <sam.spilsbury@canonical.com> | 2012-09-05 08:44:06 +0800 |
| commit | d5893765285fcc917799a8f503cb54fcc3691147 (patch) | |
| tree | 4aaf2ff4f8ff4120284ae8f23fab8e16c41fdc23 /plugins | |
| parent | 8c42d7a33835c285fb499df0a96da1a29083eb14 (diff) | |
| parent | 5d9ebc0f1f61ea1ffb36cb083aa315aac2f4812d (diff) | |
Merge lp:unity
(bzr r2637.7.2)
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/unityshell/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | plugins/unityshell/src/WindowMinimizeSpeedController.cpp | 108 | ||||
| -rw-r--r-- | plugins/unityshell/src/WindowMinimizeSpeedController.h | 57 | ||||
| -rw-r--r-- | plugins/unityshell/src/unityshell.cpp | 477 | ||||
| -rw-r--r-- | plugins/unityshell/src/unityshell.h | 48 | ||||
| -rw-r--r-- | plugins/unityshell/unityshell.xml.in | 20 |
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> |
