~gerboland/qtubuntu/enable-debug-mode

« back to all changes in this revision

Viewing changes to src/ubuntumirclient/window.cpp

  • Committer: Gerry Boland
  • Date: 2016-06-24 12:11:21 UTC
  • mfrom: (280.28.15 qtubuntu)
  • Revision ID: gerry.boland@canonical.com-20160624121121-086s2yy603hfsuus
Merge trunk & fix conflicts

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2014-2015 Canonical, Ltd.
 
2
 * Copyright (C) 2014-2016 Canonical, Ltd.
3
3
 *
4
4
 * This program is free software: you can redistribute it and/or modify it under
5
5
 * the terms of the GNU Lesser General Public License version 3, as published by
18
18
#include "window.h"
19
19
#include "clipboard.h"
20
20
#include "debugextension.h"
 
21
#include "nativeinterface.h"
21
22
#include "input.h"
22
23
#include "integration.h"
23
24
#include "screen.h"
218
219
    }
219
220
}
220
221
 
221
 
MirSurface *createMirSurface(QWindow *window, UbuntuScreen *screen, UbuntuInput *input, MirConnection *connection)
 
222
MirSurface *createMirSurface(QWindow *window, int mirOutputId, UbuntuInput *input,
 
223
                             MirConnection *connection, mir_surface_event_callback inputCallback,
 
224
                             void* inputContext)
222
225
{
223
226
    auto spec = makeSurfaceSpec(window, input, connection);
 
227
 
 
228
    // Install event handler as early as possible
 
229
    mir_surface_spec_set_event_handler(spec.get(), inputCallback, inputContext);
 
230
 
224
231
    const auto title = window->title().toUtf8();
225
232
    mir_surface_spec_set_name(spec.get(), title.constData());
226
233
 
227
234
    setSizingConstraints(spec.get(), window->minimumSize(), window->maximumSize(), window->sizeIncrement());
228
235
 
229
236
    if (window->windowState() == Qt::WindowFullScreen) {
230
 
        mir_surface_spec_set_fullscreen_on_output(spec.get(), screen->mirOutputId());
 
237
        mir_surface_spec_set_fullscreen_on_output(spec.get(), mirOutputId);
231
238
    }
232
239
 
233
240
    if (window->flags() & LowChromeWindowHint) {
261
268
class UbuntuSurface
262
269
{
263
270
public:
264
 
    UbuntuSurface(UbuntuWindow *platformWindow, UbuntuScreen *screen, UbuntuInput *input, MirConnection *connection)
 
271
    UbuntuSurface(UbuntuWindow *platformWindow, EGLDisplay display, EGLConfig config, int mirOutputId,
 
272
                  UbuntuInput *input, MirConnection *connection)
265
273
        : mWindow(platformWindow->window())
266
274
        , mPlatformWindow(platformWindow)
267
275
        , mInput(input)
268
276
        , mConnection(connection)
269
 
        , mMirSurface(createMirSurface(mWindow, screen, input, connection))
270
 
        , mEglDisplay(screen->eglDisplay())
271
 
        , mEglSurface(eglCreateWindowSurface(mEglDisplay, screen->eglConfig(), nativeWindowFor(mMirSurface), nullptr))
 
277
        , mEglDisplay(display)
272
278
        , mNeedsRepaint(false)
273
279
        , mParented(mWindow->transientParent() || mWindow->parent())
274
280
        , mShellChrome(mWindow->flags() & LowChromeWindowHint ? mir_shell_chrome_low : mir_shell_chrome_normal)
275
281
    {
276
 
        mir_surface_set_event_handler(mMirSurface, surfaceEventCallback, this);
 
282
        mMirSurface = createMirSurface(mWindow, mirOutputId, input, connection, surfaceEventCallback, this);
 
283
        mEglSurface = eglCreateWindowSurface(mEglDisplay, config, nativeWindowFor(mMirSurface), nullptr);
277
284
 
278
285
        // Window manager can give us a final size different from what we asked for
279
286
        // so let's check what we ended up getting
306
313
            mir_surface_release_sync(mMirSurface);
307
314
    }
308
315
 
309
 
    UbuntuSurface(UbuntuSurface const&) = delete;
310
 
    UbuntuSurface& operator=(UbuntuSurface const&) = delete;
 
316
    UbuntuSurface(const UbuntuSurface &) = delete;
 
317
    UbuntuSurface& operator=(const UbuntuSurface &) = delete;
311
318
 
312
319
    void resize(const QSize& newSize);
313
320
    void updateTitle(const QString& title);
339
346
    UbuntuInput * const mInput;
340
347
    MirConnection * const mConnection;
341
348
 
342
 
    MirSurface * const mMirSurface;
 
349
    MirSurface* mMirSurface;
343
350
    const EGLDisplay mEglDisplay;
344
 
    const EGLSurface mEglSurface;
 
351
    EGLSurface mEglSurface;
345
352
 
346
353
    bool mNeedsRepaint;
347
354
    bool mParented;
503
510
    mir_surface_apply_spec(mMirSurface, spec.get());
504
511
}
505
512
 
506
 
UbuntuWindow::UbuntuWindow(QWindow *w, UbuntuClientIntegration *integration, UbuntuScreen *screen,
507
 
                           UbuntuInput *input, MirConnection *connection)
 
513
UbuntuWindow::UbuntuWindow(QWindow *w, const QSharedPointer<UbuntuClipboard> &clipboard,
 
514
                           UbuntuInput *input, UbuntuNativeInterface *native, EGLDisplay eglDisplay,
 
515
                           EGLConfig eglConfig, MirConnection *mirConnection)
508
516
    : QObject(nullptr)
509
517
    , QPlatformWindow(w)
510
518
    , mId(makeId())
511
 
    , mIntegration(integration)
 
519
    , mClipboard(clipboard)
512
520
    , mWindowState(w->windowState())
513
521
    , mWindowFlags(w->flags())
514
522
    , mWindowVisible(false)
515
 
    , mSurface(new UbuntuSurface{this, screen, input, connection})
 
523
    , mWindowExposed(true)
 
524
    , mNativeInterface(native)
 
525
    , mSurface(new UbuntuSurface{this, eglDisplay, eglConfig,
 
526
               static_cast<UbuntuScreen*>(w->screen()->handle())->mirOutputId(), input, mirConnection})
 
527
    , mScale(1.0)
 
528
    , mFormFactor(mir_form_factor_unknown)
516
529
{
517
 
    qCDebug(ubuntumirclient, "UbuntuWindow(window=%p, screen=%p, input=%p, surf=%p)", w, screen, input, mSurface.get());
 
530
    qCDebug(ubuntumirclient, "UbuntuWindow(window=%p, screen=%p, input=%p, surf=%p) with title '%s', role: '%d'",
 
531
            w, w->screen()->handle(), input, mSurface.get(), qPrintable(window()->title()), roleFor(window()));
 
532
 
 
533
    updatePanelHeightHack(w->windowState() != Qt::WindowFullScreen);
518
534
}
519
535
 
520
536
UbuntuWindow::~UbuntuWindow()
525
541
void UbuntuWindow::handleSurfaceResized(int width, int height)
526
542
{
527
543
    QMutexLocker lock(&mMutex);
528
 
    qCDebug(ubuntumirclient, "handleSurfaceResize(window=%p, width=%d, height=%d)", window(), width, height);
 
544
    qCDebug(ubuntumirclient, "handleSurfaceResize(window=%p, size=(%dx%d)px", window(), width, height);
529
545
 
530
546
    mSurface->handleSurfaceResized(width, height);
531
547
 
538
554
    lock.unlock();
539
555
    qCDebug(ubuntumirclient, "handleSurfaceResize(window=%p) redraw %d times", window(), numRepaints);
540
556
    for (int i = 0; i < numRepaints; i++) {
541
 
        qCDebug(ubuntumirclient, "handleSurfaceResize(window=%p) repainting width=%d, height=%d", window(), geometry().size().width(), geometry().size().height());
 
557
        qCDebug(ubuntumirclient, "handleSurfaceResize(window=%p) repainting size=(%dx%d)dp", window(), geometry().size().width(), geometry().size().height());
542
558
        QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
543
559
    }
544
560
}
545
561
 
 
562
void UbuntuWindow::handleSurfaceExposeChange(bool exposed)
 
563
{
 
564
    QMutexLocker lock(&mMutex);
 
565
    qCDebug(ubuntumirclient, "handleSurfaceExposeChange(window=%p, exposed=%s)", window(), exposed ? "true" : "false");
 
566
 
 
567
    if (mWindowExposed == exposed) return;
 
568
    mWindowExposed = exposed;
 
569
 
 
570
    lock.unlock();
 
571
    QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
 
572
}
 
573
 
546
574
void UbuntuWindow::handleSurfaceFocused()
547
575
{
548
576
    qCDebug(ubuntumirclient, "handleSurfaceFocused(window=%p)", window());
605
633
    window is always on the top-left corner, right below the indicators panel if not
606
634
    in fullscreen.
607
635
 */
608
 
void UbuntuWindow::enablePanelHeightHack(bool enable)
 
636
void UbuntuWindow::updatePanelHeightHack(bool enable)
609
637
{
610
638
    QMutexLocker lock(&mMutex);
611
639
 
623
651
    }
624
652
}
625
653
 
626
 
void UbuntuWindow::setGeometry(const QRect& rect)
 
654
void UbuntuWindow::setGeometry(const QRect &rect)
627
655
{
628
656
    QMutexLocker lock(&mMutex);
629
 
    qCDebug(ubuntumirclient, "setGeometry (window=%p, x=%d, y=%d, width=%d, height=%d)",
630
 
           window(), rect.x(), rect.y(), rect.width(), rect.height());
 
657
    qCDebug(ubuntumirclient, "setGeometry (window=%p, position=(%d, %d)dp, size=(%dx%d)dp)",
 
658
            window(), rect.x(), rect.y(), rect.width(), rect.height());
631
659
 
632
660
    //NOTE: mir surfaces cannot be moved by the client so ignore the topLeft coordinates
633
661
    const auto newSize = rect.size();
634
 
    auto newGeometry = geometry();
635
 
    newGeometry.setSize(newSize);
636
 
    QPlatformWindow::setGeometry(newGeometry);
637
662
 
638
663
    mSurface->resize(newSize);
 
664
    // Note: don't call handleGeometryChange here, wait to see what Mir replies with.
639
665
}
640
666
 
641
667
void UbuntuWindow::setVisible(bool visible)
660
686
    lock.unlock();
661
687
    updateSurfaceState();
662
688
    QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
663
 
    QWindowSystemInterface::flushWindowSystemEvents();
664
689
}
665
690
 
666
691
void UbuntuWindow::setWindowTitle(const QString& title)
675
700
    QMutexLocker lock(&mMutex);
676
701
    const auto win = window();
677
702
    qCDebug(ubuntumirclient, "propagateSizeHints(window=%p) min(%d,%d), max(%d,%d) increment(%d, %d)",
678
 
           win, win->minimumSize().width(), win->minimumSize().height(),
679
 
           win->maximumSize().width(), win->maximumSize().height(),
680
 
           win->sizeIncrement().width(), win->sizeIncrement().height());
 
703
            win, win->minimumSize().width(), win->minimumSize().height(),
 
704
            win->maximumSize().width(), win->maximumSize().height(),
 
705
            win->sizeIncrement().width(), win->sizeIncrement().height());
681
706
    mSurface->setSizingConstraints(win->minimumSize(), win->maximumSize(), win->sizeIncrement());
682
707
}
683
708
 
684
709
bool UbuntuWindow::isExposed() const
685
710
{
686
 
    return mWindowVisible;
 
711
    return mWindowVisible && mWindowExposed;
687
712
}
688
713
 
689
714
QPoint UbuntuWindow::mapToGlobal(const QPoint &pos) const
716
741
    mSurface->onSwapBuffersDone();
717
742
}
718
743
 
 
744
void UbuntuWindow::handleScreenPropertiesChange(MirFormFactor formFactor, float scale)
 
745
{
 
746
    // Update the scale & form factor native-interface properties for the windows affected
 
747
    // as there is no convenient way to emit signals for those custom properties on a QScreen
 
748
    if (formFactor != mFormFactor) {
 
749
        mFormFactor = formFactor;
 
750
        Q_EMIT mNativeInterface->windowPropertyChanged(this, QStringLiteral("formFactor"));
 
751
    }
 
752
 
 
753
    if (!qFuzzyCompare(scale, mScale)) {
 
754
        mScale = scale;
 
755
        // update the panelHeight hack since it depends on GU
 
756
        updatePanelHeightHack(mSurface->state() != mir_surface_state_fullscreen);
 
757
 
 
758
        Q_EMIT mNativeInterface->windowPropertyChanged(this, QStringLiteral("scale"));
 
759
    }
 
760
}
 
761
 
719
762
void UbuntuWindow::updateSurfaceState()
720
763
{
721
764
    QMutexLocker lock(&mMutex);
726
769
        mSurface->setState(newState);
727
770
 
728
771
        lock.unlock();
729
 
        enablePanelHeightHack(newState != mir_surface_state_fullscreen);
 
772
        updatePanelHeightHack(newState != mir_surface_state_fullscreen);
730
773
    }
731
774
}