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) 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(); diff --git a/effects/magnifier/magnifier.cpp b/effects/magnifier/magnifier.cpp index 22b9994a87..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); @@ -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; @@ -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); 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; diff --git a/eglonxbackend.cpp b/eglonxbackend.cpp index cc5df0d2d7..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")) { @@ -277,6 +280,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/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); } } diff --git a/glxbackend.cpp b/glxbackend.cpp index 773bb91886..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 @@ -432,6 +435,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'); } } 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) { 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