SVN commit 1160253 by hein: Added a new "Ask the window manager to perform the animation" option to the animation settings (only shown if Yakuake was built against KDE SC 4.6 Alpha 1 or higher). If this option is enabled (it is by default) and the KDE Desktop Effect "Sliding Popups" is enabled as well, the animation will be performed by KDE's window manager KWin, for much improved smooth- ness on many systems. BUG:216432 CCMAIL:kde@martin-graesslin.com M +6 -0 ChangeLog M +6 -0 app/CMakeLists.txt M +0 -2 app/config/skinlistdelegate.cpp M +6 -0 app/config/windowsettings.cpp M +19 -5 app/config/windowsettings.ui M +6 -1 app/config/yakuake.kcfg M +0 -1 app/firstrundialog.cpp M +148 -23 app/mainwindow.cpp M +19 -3 app/mainwindow.h U app/sessionstack.cpp M +1 -2 app/titlebar.h --- trunk/extragear/utils/yakuake/ChangeLog #1160252:1160253 @@ -3,6 +3,12 @@ respected immediately when toggling the "Keep window open when it loses focus" preference from the title bar or the main menu. * Yakuake now depends on KDE 4.3. +* Added a new "Ask the window manager to perform the animation" option to + the animation settings (only shown if Yakuake was built against KDE SC + 4.6 Alpha 1 or higher). If this option is enabled (it is by default) and + the KDE Desktop Effect "Sliding Popups" is enabled as well, the animation + will be performed by KDE's window manager KWin, for much improved smooth- + ness on many systems. Changes in 2.9.7: --- trunk/extragear/utils/yakuake/app/CMakeLists.txt #1160252:1160253 @@ -35,6 +35,12 @@ target_link_libraries(yakuake ${KDE4_KPARTS_LIBS}) +macro_ensure_version("4.4.0" ${KDE_VERSION} KDE_IS_46_OR_HIGHER) + +if(Q_WS_X11 AND KDE_IS_46_OR_HIGHER) + target_link_libraries(yakuake ${X11_X11_LIB}) +endif(Q_WS_X11 AND KDE_IS_46_OR_HIGHER) + install(TARGETS yakuake ${INSTALL_TARGETS_DEFAULT_ARGS}) install(FILES yakuake.desktop DESTINATION ${XDG_APPS_INSTALL_DIR}) --- trunk/extragear/utils/yakuake/app/config/skinlistdelegate.cpp #1160252:1160253 @@ -22,8 +22,6 @@ #include "skinlistdelegate.h" #include "appearancesettings.h" -#include - #include #include #include --- trunk/extragear/utils/yakuake/app/config/windowsettings.cpp #1160252:1160253 @@ -24,11 +24,17 @@ #include +#include + WindowSettings::WindowSettings(QWidget* parent) : QWidget(parent) { setupUi(this); +#if !KDE_IS_VERSION(4,5,60) + kcfg_UseWMAssist->hide(); +#endif + for (int i = 2; i <= QApplication::desktop()->numScreens(); i++) kcfg_Screen->insertItem(i, i18nc("@item:inlistbox", "Screen %1", i)); --- trunk/extragear/utils/yakuake/app/config/windowsettings.ui #1160252:1160253 @@ -1,3 +1,4 @@ + WindowSettings @@ -5,11 +6,14 @@ 0 0 - 285 + 289 441 - + + + 0 + 0 @@ -48,7 +52,7 @@ false - + 0 0 @@ -69,7 +73,7 @@ Size and Animation - + @@ -229,6 +233,16 @@ + + + + If this option is enabled, Yakuake will ask the window manager to perform the window open/retract animation. If the window manager is unable to provide the requested service, Yakuake will fall back to an animation strategy of progressively adjusting the window mask. + + + Ask the window manager to perform the animation + + + @@ -237,7 +251,7 @@ Position - + --- trunk/extragear/utils/yakuake/app/config/yakuake.kcfg #1160252:1160253 @@ -137,9 +137,14 @@ + + + Whether to try and let the window manager perform the window open/retract animation. Yakuake will fall back to an animation strategy of progressively adjusting the window mask if the window manager is unable to provide the requested service. + true + - The number of frames of the open/retract animation. + The number of frames of the open/retract animation. One frame is taken to be 10 miliseconds. 20 0 50 --- trunk/extragear/utils/yakuake/app/firstrundialog.cpp #1160252:1160253 @@ -24,7 +24,6 @@ #include "ui_firstrundialog.h" #include -#include FirstRunDialog::FirstRunDialog(MainWindow* mainWindow) : KDialog(mainWindow) --- trunk/extragear/utils/yakuake/app/mainwindow.cpp #1160252:1160253 @@ -51,9 +51,14 @@ #include #include #include -#include +#if defined(Q_WS_X11) && KDE_IS_VERSION(4,5,60) +#include +#include +#endif + + MainWindow::MainWindow(QWidget* parent) : KMainWindow(parent, Qt::CustomizeWindowHint | Qt::FramelessWindowHint) { @@ -68,7 +73,12 @@ m_tabBar = new TabBar(this); m_titleBar = new TitleBar(this); m_firstRunDialog = NULL; + m_listenForActivationChanges = false; +#if defined(Q_WS_X11) && KDE_IS_VERSION(4,5,60) + m_kwinAssistPropSet = false; +#endif + setupActions(); setupMenu(); @@ -531,7 +541,7 @@ void MainWindow::configureKeys() { KShortcutsDialog::configure(actionCollection()); - KWindowSystem::activateWindow(winId()); + activate(); } void MainWindow::configureApp() @@ -658,11 +668,14 @@ int maxHeight = workArea.height() * newHeight / 100; + int targetWidth = workArea.width() * newWidth / 100; + setGeometry(workArea.x() + workArea.width() * newPosition * (100 - newWidth) / 10000, - workArea.y(), workArea.width() * newWidth / 100, maxHeight); + workArea.y(), targetWidth, maxHeight); maxHeight -= m_titleBar->height(); - m_titleBar->setGeometry(0, maxHeight, width(), m_titleBar->height()); + m_titleBar->setGeometry(0, maxHeight, targetWidth, m_titleBar->height()); + if (!isVisible()) m_titleBar->updateMask(); if (Settings::frames() > 0) m_animationStepSize = maxHeight / Settings::frames(); @@ -789,7 +802,7 @@ void MainWindow::changeEvent(QEvent* event) { - if (event->type() == QEvent::ActivationChange) + if (m_listenForActivationChanges && event->type() == QEvent::ActivationChange) { if (isVisible() && !KApplication::activeWindow() && !Settings::keepOpen()) toggleWindowState(); @@ -800,43 +813,127 @@ void MainWindow::toggleWindowState() { - if (m_animationTimer.isActive()) return; + bool visible = isVisible(); - if (isVisible()) + if (visible && !isActiveWindow() && Settings::keepOpen() && Settings::toggleToFocus()) { - if (!isActiveWindow() && Settings::keepOpen() && Settings::toggleToFocus()) - { KWindowSystem::forceActiveWindow(winId()); + return; } +#if defined(Q_WS_X11) && KDE_IS_VERSION(4,5,60) + if (!Settings::useWMAssist() && m_kwinAssistPropSet) + kwinAssistPropCleanup(); + + if (Settings::useWMAssist() && KWindowSystem::compositingActive()) + kwinAssistToggleWindowState(visible); + else +#endif + xshapeToggleWindowState(visible); +} + +#if defined(Q_WS_X11) && KDE_IS_VERSION(4,5,60) +void MainWindow::kwinAssistToggleWindowState(bool visible) +{ + bool gotEffect = false; + + Display* display = QX11Info::display(); + Atom atom = XInternAtom(display, "_KDE_SLIDE", false); + int count; + Atom* list = XListProperties(display, DefaultRootWindow(display), &count); + + if (list != NULL) + { + gotEffect = (qFind(list, list + count, atom) != list + count); + + XFree(list); + } + + if (gotEffect) + { + Atom atom = XInternAtom(display, "_KDE_SLIDE", false); + + if (Settings::frames() > 0) + { + QVarLengthArray data(4); + + data[0] = 0; + data[1] = 1; + data[2] = Settings::frames() * 10; + data[3] = Settings::frames() * 10; + + XChangeProperty(display, winId(), atom, atom, 32, PropModeReplace, + reinterpret_cast(data.data()), data.size()); + + m_kwinAssistPropSet = true; + } + else + XDeleteProperty(display, winId(), atom); + + if (visible) + { + sharedPreHideWindow(); + + hide(); + + sharedAfterHideWindow(); + } + else + { + sharedPreOpenWindow(); + + show(); + + sharedAfterOpenWindow(); + } + + return; + } + + xshapeToggleWindowState(visible); +} + +void MainWindow::kwinAssistPropCleanup() +{ + Display* display = QX11Info::display(); + Atom atom = XInternAtom(display, "_KDE_SLIDE", false); + + XDeleteProperty(display, winId(), atom); + + m_kwinAssistPropSet = false; +} +#endif + +void MainWindow::xshapeToggleWindowState(bool visible) +{ + if (m_animationTimer.isActive()) return; + + if (visible) + { + sharedPreHideWindow(); + m_animationFrame = Settings::frames(); - connect(&m_animationTimer, SIGNAL(timeout()), this, SLOT(retractWindow())); + connect(&m_animationTimer, SIGNAL(timeout()), this, SLOT(xshapeRetractWindow())); m_animationTimer.start(); } else { - applyWindowGeometry(); - m_animationFrame = 0; - connect(&m_animationTimer, SIGNAL(timeout()), this, SLOT(openWindow())); + connect(&m_animationTimer, SIGNAL(timeout()), this, SLOT(xshapeOpenWindow())); m_animationTimer.start(); } } -void MainWindow::openWindow() +void MainWindow::xshapeOpenWindow() { if (m_animationFrame == 0) { - updateUseTranslucency(); + sharedPreOpenWindow(); - applyWindowProperties(); - show(); - - if (Settings::pollMouse()) toggleMousePoll(false); } if (m_animationFrame == Settings::frames()) @@ -847,7 +944,7 @@ m_titleBar->move(0, height() - m_titleBar->height()); updateMask(); - if (!Settings::firstRun()) KWindowSystem::forceActiveWindow(winId()); + sharedAfterOpenWindow(); } else { @@ -865,7 +962,7 @@ } } -void MainWindow::retractWindow() +void MainWindow::xshapeRetractWindow() { if (m_animationFrame == 0) { @@ -874,7 +971,7 @@ hide(); - if (Settings::pollMouse()) toggleMousePoll(true); + sharedAfterHideWindow(); } else { @@ -886,6 +983,34 @@ } } +void MainWindow::sharedPreOpenWindow() +{ + applyWindowGeometry(); + + updateUseTranslucency(); + + applyWindowProperties(); + + if (Settings::pollMouse()) toggleMousePoll(false); +} + +void MainWindow::sharedAfterOpenWindow() +{ + if (!Settings::firstRun()) KWindowSystem::forceActiveWindow(winId()); + + m_listenForActivationChanges = true; +} + +void MainWindow::sharedPreHideWindow() +{ + m_listenForActivationChanges = false; +} + +void MainWindow::sharedAfterHideWindow() +{ + if (Settings::pollMouse()) toggleMousePoll(true); +} + void MainWindow::activate() { KWindowSystem::activateWindow(winId()); @@ -955,7 +1080,7 @@ if (action->isChecked()) return screenGeometry; - int currentDesktop = KWindowSystem::windowInfo(winId(), NET::CurrentDesktop).desktop(); + int currentDesktop = KWindowSystem::windowInfo(winId(), NET::WMDesktop).desktop(); if (KApplication::desktop()->numScreens() > 1) { --- trunk/extragear/utils/yakuake/app/mainwindow.h #1160252:1160253 @@ -23,11 +23,11 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H - #include "settings.h" #include #include +#include #include #include #include @@ -102,8 +102,9 @@ void increaseWindowHeight(); void decreaseWindowHeight(); - void openWindow(); - void retractWindow(); + void xshapeOpenWindow(); + void xshapeRetractWindow(); + void activate(); void toggleMousePoll(bool poll); @@ -134,6 +135,19 @@ void updateWindowHeightMenu(); void updateWindowWidthMenu(); +#if defined(Q_WS_X11) && KDE_IS_VERSION(4,5,60) + void kwinAssistToggleWindowState(bool visible); + void kwinAssistPropCleanup(); + bool m_kwinAssistPropSet; +#endif + + void xshapeToggleWindowState(bool visible); + + void sharedPreOpenWindow(); + void sharedAfterOpenWindow(); + void sharedPreHideWindow(); + void sharedAfterHideWindow(); + void updateMask(); int getScreen(); @@ -164,6 +178,8 @@ QTimer m_mousePoller; int m_animationFrame; int m_animationStepSize; + + bool m_listenForActivationChanges; }; #endif --- trunk/extragear/utils/yakuake/app/titlebar.h #1160252:1160253 @@ -41,6 +41,7 @@ ~TitleBar(); void applySkin(); + void updateMask(); QString title(); @@ -57,8 +58,6 @@ private: - void updateMask(); - MainWindow* m_mainWindow; Skin* m_skin;