From 57485cfefce6905ff307d203d5778a94a34a37ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Thu, 25 Jul 2013 19:12:30 +0200 Subject: [PATCH 1/9] fix magnifier effect exit precision is usually enough to end on exactly "1.0" so the effect was "hidden" but the mouse still polled. --- effects/magnifier/magnifier.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/effects/magnifier/magnifier.cpp b/effects/magnifier/magnifier.cpp index 22b9994a87..ad8d51a155 100644 --- a/effects/magnifier/magnifier.cpp +++ b/effects/magnifier/magnifier.cpp @@ -266,7 +266,7 @@ void MagnifierEffect::zoomIn() void MagnifierEffect::zoomOut() { target_zoom /= 1.2; - if (target_zoom < 1) { + if (target_zoom <= 1) { target_zoom = 1; if (polling) { polling = false; From bac8dc095fbcff59c0e6bdeecd4ee1c261519324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Thu, 25 Jul 2013 19:13:51 +0200 Subject: [PATCH 2/9] fix rendertarget warning on xrender accidental GL call in non GL compositing --- effects/magnifier/magnifier.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/effects/magnifier/magnifier.cpp b/effects/magnifier/magnifier.cpp index ad8d51a155..5ef9420aa1 100644 --- a/effects/magnifier/magnifier.cpp +++ b/effects/magnifier/magnifier.cpp @@ -255,7 +255,7 @@ void MagnifierEffect::zoomIn() polling = true; effects->startMousePolling(); } - if (!m_texture) { + if (effects->isOpenGLCompositing() && !m_texture) { m_texture = new GLTexture(magnifier_size.width(), magnifier_size.height()); m_texture->setYInverted(false); m_fbo = new GLRenderTarget(*m_texture); @@ -293,7 +293,7 @@ void MagnifierEffect::toggle() polling = true; effects->startMousePolling(); } - if (!m_texture) { + if (effects->isOpenGLCompositing() && !m_texture) { m_texture = new GLTexture(magnifier_size.width(), magnifier_size.height()); m_texture->setYInverted(false); m_fbo = new GLRenderTarget(*m_texture); From 50e3e909dadf37ffaa5cbe75b528ba458af207cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Tue, 23 Jul 2013 22:34:41 +0200 Subject: [PATCH 3/9] prevent yield/swap cpu overhead on nvidia CCBUG: 322060 REVIEW: 111663 --- eglonxbackend.cpp | 12 ++++++++++++ glxbackend.cpp | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/eglonxbackend.cpp b/eglonxbackend.cpp index cc5df0d2d7..86c763eb08 100644 --- a/eglonxbackend.cpp +++ b/eglonxbackend.cpp @@ -277,6 +277,18 @@ void EglOnXBackend::present() eglWaitGL(); if (char result = m_swapProfiler.end()) { gs_tripleBufferUndetected = gs_tripleBufferNeedsDetection = false; + if (result == 'd' && GLPlatform::instance()->driver() == Driver_NVidia) { + // TODO this is a workaround, we should get __GL_YIELD set before libGL checks it + if (qstrcmp(qgetenv("__GL_YIELD"), "USLEEP")) { + options->setGlPreferBufferSwap(0); + eglSwapInterval(dpy, 0); + kWarning(1212) << "\nIt seems you are using the nvidia driver without triple buffering\n" + "You must export __GL_YIELD=\"USLEEP\" to prevent large CPU overhead on synced swaps\n" + "Preferably, enable the TripleBuffer Option in the xorg.conf Device\n" + "For this reason, the tearing prevention has been disabled.\n" + "See https://bugs.kde.org/show_bug.cgi?id=322060\n"; + } + } setBlocksForRetrace(result == 'd'); } } diff --git a/glxbackend.cpp b/glxbackend.cpp index 773bb91886..7f2449cfe4 100644 --- a/glxbackend.cpp +++ b/glxbackend.cpp @@ -432,6 +432,18 @@ void GlxBackend::present() glXWaitGL(); if (char result = m_swapProfiler.end()) { gs_tripleBufferUndetected = gs_tripleBufferNeedsDetection = false; + if (result == 'd' && GLPlatform::instance()->driver() == Driver_NVidia) { + // TODO this is a workaround, we should get __GL_YIELD set before libGL checks it + if (qstrcmp(qgetenv("__GL_YIELD"), "USLEEP")) { + options->setGlPreferBufferSwap(0); + setSwapInterval(0); + kWarning(1212) << "\nIt seems you are using the nvidia driver without triple buffering\n" + "You must export __GL_YIELD=\"USLEEP\" to prevent large CPU overhead on synced swaps\n" + "Preferably, enable the TripleBuffer Option in the xorg.conf Device\n" + "For this reason, the tearing prevention has been disabled.\n" + "See https://bugs.kde.org/show_bug.cgi?id=322060\n"; + } + } setBlocksForRetrace(result == 'd'); } } From f4827fbac9e3ef2f2c63553943af6d29d89b6143 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Fri, 19 Jul 2013 16:28:05 +0200 Subject: [PATCH 4/9] update packing logics to honor activities and tabs at the same time using MaximizeArea instead MoveArea ratio: movearea allows to pack windows under panels and while one can expect users of packing to know alt+lmb, we usually do not allow to loose the titlebar Moreover this relies on packing against dock windows what fails with "virtual" struts as input shaping panels (eg. cairo-dock?) might use (ie. we we would also have packed against plasma panel shadows - back then ;-) BUG: 180084 REVIEW: 111603 FIXED-IN: 4.11 --- placement.cpp | 42 +++++++++++++++++------------------------- 1 file changed, 17 insertions(+), 25 deletions(-) diff --git a/placement.cpp b/placement.cpp index b23dc37d62..55fcb34e87 100644 --- a/placement.cpp +++ b/placement.cpp @@ -140,7 +140,7 @@ void Placement::placeAtRandom(Client* c, const QRect& area, Policy /*next*/) } // TODO: one day, there'll be C++11 ... -static inline bool isIrrelevant(Client *client, Client *regarding, int desktop) +static inline bool isIrrelevant(const Client *client, const Client *regarding, int desktop) { if (!client) return true; @@ -810,16 +810,14 @@ void Workspace::slotWindowQuickTileBottomRight() int Workspace::packPositionLeft(const Client* cl, int oldx, bool left_edge) const { - int newx = clientArea(MovementArea, cl).left(); + int newx = clientArea(MaximizeArea, cl).left(); if (oldx <= newx) // try another Xinerama screen - newx = clientArea(MovementArea, + newx = clientArea(MaximizeArea, QPoint(cl->geometry().left() - 1, cl->geometry().center().y()), cl->desktop()).left(); if (oldx <= newx) return oldx; - for (ClientList::ConstIterator it = clients.constBegin(); - it != clients.constEnd(); - ++it) { - if (!(*it)->isShown(false) || !(*it)->isOnDesktop(active_client->desktop())) + for (ClientList::ConstIterator it = clients.constBegin(), end = clients.constEnd(); it != end; ++it) { + if (isIrrelevant(*it, cl, cl->desktop())) continue; int x = left_edge ? (*it)->geometry().right() + 1 : (*it)->geometry().left() - 1; if (x > newx && x < oldx @@ -832,16 +830,14 @@ int Workspace::packPositionLeft(const Client* cl, int oldx, bool left_edge) cons int Workspace::packPositionRight(const Client* cl, int oldx, bool right_edge) const { - int newx = clientArea(MovementArea, cl).right(); + int newx = clientArea(MaximizeArea, cl).right(); if (oldx >= newx) // try another Xinerama screen - newx = clientArea(MovementArea, + newx = clientArea(MaximizeArea, QPoint(cl->geometry().right() + 1, cl->geometry().center().y()), cl->desktop()).right(); if (oldx >= newx) return oldx; - for (ClientList::ConstIterator it = clients.constBegin(); - it != clients.constEnd(); - ++it) { - if (!(*it)->isShown(false) || !(*it)->isOnDesktop(cl->desktop())) + for (ClientList::ConstIterator it = clients.constBegin(), end = clients.constEnd(); it != end; ++it) { + if (isIrrelevant(*it, cl, cl->desktop())) continue; int x = right_edge ? (*it)->geometry().left() - 1 : (*it)->geometry().right() + 1; if (x < newx && x > oldx @@ -854,16 +850,14 @@ int Workspace::packPositionRight(const Client* cl, int oldx, bool right_edge) co int Workspace::packPositionUp(const Client* cl, int oldy, bool top_edge) const { - int newy = clientArea(MovementArea, cl).top(); + int newy = clientArea(MaximizeArea, cl).top(); if (oldy <= newy) // try another Xinerama screen - newy = clientArea(MovementArea, + newy = clientArea(MaximizeArea, QPoint(cl->geometry().center().x(), cl->geometry().top() - 1), cl->desktop()).top(); if (oldy <= newy) return oldy; - for (ClientList::ConstIterator it = clients.constBegin(); - it != clients.constEnd(); - ++it) { - if (!(*it)->isShown(false) || !(*it)->isOnDesktop(cl->desktop())) + for (ClientList::ConstIterator it = clients.constBegin(), end = clients.constEnd(); it != end; ++it) { + if (isIrrelevant(*it, cl, cl->desktop())) continue; int y = top_edge ? (*it)->geometry().bottom() + 1 : (*it)->geometry().top() - 1; if (y > newy && y < oldy @@ -876,16 +870,14 @@ int Workspace::packPositionUp(const Client* cl, int oldy, bool top_edge) const int Workspace::packPositionDown(const Client* cl, int oldy, bool bottom_edge) const { - int newy = clientArea(MovementArea, cl).bottom(); + int newy = clientArea(MaximizeArea, cl).bottom(); if (oldy >= newy) // try another Xinerama screen - newy = clientArea(MovementArea, + newy = clientArea(MaximizeArea, QPoint(cl->geometry().center().x(), cl->geometry().bottom() + 1), cl->desktop()).bottom(); if (oldy >= newy) return oldy; - for (ClientList::ConstIterator it = clients.constBegin(); - it != clients.constEnd(); - ++it) { - if (!(*it)->isShown(false) || !(*it)->isOnDesktop(cl->desktop())) + for (ClientList::ConstIterator it = clients.constBegin(), end = clients.constEnd(); it != end; ++it) { + if (isIrrelevant(*it, cl, cl->desktop())) continue; int y = bottom_edge ? (*it)->geometry().top() - 1 : (*it)->geometry().bottom() + 1; if (y < newy && y > oldy From bc80d2417afb486806b021c58c723df2283fb4a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Fri, 26 Jul 2013 14:09:06 +0200 Subject: [PATCH 5/9] re-fix bouncing startup feedback BUG: 304253 FIXED-IN: 4.11 REVIEW: 111729 --- effects/startupfeedback/startupfeedback.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/effects/startupfeedback/startupfeedback.cpp b/effects/startupfeedback/startupfeedback.cpp index ca1964d763..063d9879f8 100644 --- a/effects/startupfeedback/startupfeedback.cpp +++ b/effects/startupfeedback/startupfeedback.cpp @@ -155,7 +155,9 @@ void StartupFeedbackEffect::prePaintScreen(ScreenPrePaintData& data, int time) switch(m_type) { case BouncingFeedback: m_progress = (m_progress + time) % BOUNCE_DURATION; - m_frame = qRound((qreal)m_progress / (qreal)BOUNCE_FRAME_DURATION) % BOUNCE_FRAMES;; + m_frame = qRound((qreal)m_progress / (qreal)BOUNCE_FRAME_DURATION) % BOUNCE_FRAMES; + m_currentGeometry = feedbackRect(); // bounce alters geometry with m_frame + data.paint.unite(m_currentGeometry); break; case BlinkingFeedback: m_progress = (m_progress + time) % BLINKING_DURATION; From 2f5ceb15e4f51d00e0c7f9a04ae34826e9544a7d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Fri, 26 Jul 2013 17:16:19 +0200 Subject: [PATCH 6/9] exit cube on doubleclick more natural than (preserved) rmb exit and also for single touch devices REVIEW: 111730 --- effects/cube/cube.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/effects/cube/cube.cpp b/effects/cube/cube.cpp index 5e4a8421b7..df01d7c5bb 100644 --- a/effects/cube/cube.cpp +++ b/effects/cube/cube.cpp @@ -30,6 +30,7 @@ along with this program. If not, see . #include #include +#include #include #include #include @@ -1948,6 +1949,8 @@ void CubeEffect::windowInputMouseEvent(QEvent* e) return; static QPoint oldpos; + static QElapsedTimer dblClckTime; + static int dblClckCounter(0); if (mouse->type() == QEvent::MouseMove && mouse->buttons().testFlag(Qt::LeftButton)) { const QPoint pos = mouse->pos(); QRect rect = effects->clientArea(FullArea, activeScreen, effects->currentDesktop()); @@ -1991,11 +1994,22 @@ void CubeEffect::windowInputMouseEvent(QEvent* e) else if (mouse->type() == QEvent::MouseButtonPress && mouse->button() == Qt::LeftButton) { oldpos = mouse->pos(); + if (dblClckTime.elapsed() > QApplication::doubleClickInterval()) + dblClckCounter = 0; + if (!dblClckCounter) + dblClckTime.start(); } else if (mouse->type() == QEvent::MouseButtonRelease) { effects->defineCursor(Qt::OpenHandCursor); - if (mouse->button() == Qt::XButton1) { + if (mouse->button() == Qt::LeftButton && ++dblClckCounter == 2) { + dblClckCounter = 0; + if (dblClckTime.elapsed() < QApplication::doubleClickInterval()) { + setActive(false); + return; + } + } + else if (mouse->button() == Qt::XButton1) { if (!rotating && !start) { rotating = true; if (invertMouse) From ac32664dc1356189d6a40923ecb2a6c392b0d9b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Wed, 17 Jul 2013 15:44:42 +0200 Subject: [PATCH 7/9] keep buffer swap pref automatic until GPU detected enforce to "e" (cheap) when driver is still unknown after detection must be assumed to have run, so a sane value is available when the context is up BUG: 322355 FIXED-IN: 4.11 REVIEW: 111548 --- eglonxbackend.cpp | 3 +++ glxbackend.cpp | 3 +++ options.cpp | 2 +- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/eglonxbackend.cpp b/eglonxbackend.cpp index 86c763eb08..9af3c0d507 100644 --- a/eglonxbackend.cpp +++ b/eglonxbackend.cpp @@ -74,6 +74,9 @@ void EglOnXBackend::init() glPlatform->detect(EglPlatformInterface); if (GLPlatform::instance()->driver() == Driver_Intel) options->setUnredirectFullscreen(false); // bug #252817 + options->setGlPreferBufferSwap(options->glPreferBufferSwap()); // resolve autosetting + if (options->glPreferBufferSwap() == Options::AutoSwapStrategy) + options->setGlPreferBufferSwap('e'); // for unknown drivers - should not happen glPlatform->printResults(); initGL(EglPlatformInterface); if (!hasGLExtension("GL_OES_EGL_image")) { diff --git a/glxbackend.cpp b/glxbackend.cpp index 7f2449cfe4..11f7017bf5 100644 --- a/glxbackend.cpp +++ b/glxbackend.cpp @@ -97,6 +97,9 @@ void GlxBackend::init() glPlatform->detect(GlxPlatformInterface); if (GLPlatform::instance()->driver() == Driver_Intel) options->setUnredirectFullscreen(false); // bug #252817 + options->setGlPreferBufferSwap(options->glPreferBufferSwap()); // resolve autosetting + if (options->glPreferBufferSwap() == Options::AutoSwapStrategy) + options->setGlPreferBufferSwap('e'); // for unknown drivers - should not happen glPlatform->printResults(); initGL(GlxPlatformInterface); // Check whether certain features are supported diff --git a/options.cpp b/options.cpp index cd3931cd8d..8f6a21f474 100644 --- a/options.cpp +++ b/options.cpp @@ -767,7 +767,7 @@ void Options::setGlPreferBufferSwap(char glPreferBufferSwap) // see http://www.x.org/releases/X11R7.7/doc/dri2proto/dri2proto.txt, item 2.5 if (GLPlatform::instance()->driver() == Driver_NVidia) glPreferBufferSwap = CopyFrontBuffer; - else + else if (GLPlatform::instance()->driver() != Driver_Unknown) // undetected, finally resolved when context is initialized glPreferBufferSwap = ExtendDamage; } if (m_glPreferBufferSwap == (GlSwapStrategy)glPreferBufferSwap) { From 6c420f2b11c4631f8be05ab185e5af554161ebd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Sat, 27 Jul 2013 13:09:07 +0200 Subject: [PATCH 8/9] don't require geometry changes for quick max/tile the present check can break quick everything depending on screen snapping settings. It so far. only worked for quick maximization due to horizontal "judder" and failed whenever that judder was not possible (due to screen snapping on left and/or right edge) BUG: 322852 FIXED-IN: 4.11 REVIEW: 111740 --- events.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/events.cpp b/events.cpp index 3fa04f861e..904811864b 100644 --- a/events.cpp +++ b/events.cpp @@ -1256,15 +1256,15 @@ bool Client::motionNotifyEvent(xcb_window_t w, int state, int x, int y, int x_ro if (!waitingMotionEvent()) { QRect oldGeo = geometry(); handleMoveResize(x, y, x_root, y_root); - if (!isFullScreen() && isMove() && oldGeo != geometry()) { - if (quick_tile_mode != QuickTileNone) { + if (!isFullScreen() && isMove()) { + if (quick_tile_mode != QuickTileNone && oldGeo != geometry()) { GeometryUpdatesBlocker blocker(this); setQuickTileMode(QuickTileNone); moveOffset = QPoint(double(moveOffset.x()) / double(oldGeo.width()) * double(geom_restore.width()), double(moveOffset.y()) / double(oldGeo.height()) * double(geom_restore.height())); moveResizeGeom = geom_restore; handleMoveResize(x, y, x_root, y_root); // fix position - } else if (isResizable()) { + } else if (quick_tile_mode == QuickTileNone && isResizable()) { checkQuickTilingMaximizationZones(x_root, y_root); } } From 90615561e4571e968dfcb87fdba4694bf0d75c13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20L=C3=BCbking?= Date: Wed, 31 Jul 2013 12:14:13 +0200 Subject: [PATCH 9/9] desk-grid: bind sc editor keyChange to kcm changed BUG: 316177 FIXED-IN: 4.11 REVIEW: 111812 --- effects/desktopgrid/desktopgrid_config.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/effects/desktopgrid/desktopgrid_config.cpp b/effects/desktopgrid/desktopgrid_config.cpp index 45fd205fd9..a3ba77a0ee 100644 --- a/effects/desktopgrid/desktopgrid_config.cpp +++ b/effects/desktopgrid/desktopgrid_config.cpp @@ -77,6 +77,7 @@ DesktopGridEffectConfig::DesktopGridEffectConfig(QWidget* parent, const QVariant addConfig(DesktopGridConfig::self(), m_ui); connect(m_ui->kcfg_LayoutMode, SIGNAL(currentIndexChanged(int)), this, SLOT(layoutSelectionChanged())); connect(m_ui->desktopNameAlignmentCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(changed())); + connect(m_ui->shortcutEditor, SIGNAL(keyChange()), this, SLOT(changed())); load(); layoutSelectionChanged();