2
* Copyright (C) 2014-2015 Canonical, Ltd.
2
* Copyright (C) 2014-2016 Canonical, Ltd.
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
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,
223
226
auto spec = makeSurfaceSpec(window, input, connection);
228
// Install event handler as early as possible
229
mir_surface_spec_set_event_handler(spec.get(), inputCallback, inputContext);
224
231
const auto title = window->title().toUtf8();
225
232
mir_surface_spec_set_name(spec.get(), title.constData());
227
234
setSizingConstraints(spec.get(), window->minimumSize(), window->maximumSize(), window->sizeIncrement());
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);
233
240
if (window->flags() & LowChromeWindowHint) {
261
268
class UbuntuSurface
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)
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)
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);
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);
309
UbuntuSurface(UbuntuSurface const&) = delete;
310
UbuntuSurface& operator=(UbuntuSurface const&) = delete;
316
UbuntuSurface(const UbuntuSurface &) = delete;
317
UbuntuSurface& operator=(const UbuntuSurface &) = delete;
312
319
void resize(const QSize& newSize);
313
320
void updateTitle(const QString& title);
339
346
UbuntuInput * const mInput;
340
347
MirConnection * const mConnection;
342
MirSurface * const mMirSurface;
349
MirSurface* mMirSurface;
343
350
const EGLDisplay mEglDisplay;
344
const EGLSurface mEglSurface;
351
EGLSurface mEglSurface;
346
353
bool mNeedsRepaint;
503
510
mir_surface_apply_spec(mMirSurface, spec.get());
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)
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})
528
, mFormFactor(mir_form_factor_unknown)
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()));
533
updatePanelHeightHack(w->windowState() != Qt::WindowFullScreen);
520
536
UbuntuWindow::~UbuntuWindow()
525
541
void UbuntuWindow::handleSurfaceResized(int width, int height)
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);
530
546
mSurface->handleSurfaceResized(width, height);
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()));
562
void UbuntuWindow::handleSurfaceExposeChange(bool exposed)
564
QMutexLocker lock(&mMutex);
565
qCDebug(ubuntumirclient, "handleSurfaceExposeChange(window=%p, exposed=%s)", window(), exposed ? "true" : "false");
567
if (mWindowExposed == exposed) return;
568
mWindowExposed = exposed;
571
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
546
574
void UbuntuWindow::handleSurfaceFocused()
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
608
void UbuntuWindow::enablePanelHeightHack(bool enable)
636
void UbuntuWindow::updatePanelHeightHack(bool enable)
610
638
QMutexLocker lock(&mMutex);
626
void UbuntuWindow::setGeometry(const QRect& rect)
654
void UbuntuWindow::setGeometry(const QRect &rect)
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());
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);
638
663
mSurface->resize(newSize);
664
// Note: don't call handleGeometryChange here, wait to see what Mir replies with.
641
667
void UbuntuWindow::setVisible(bool visible)
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());
684
709
bool UbuntuWindow::isExposed() const
686
return mWindowVisible;
711
return mWindowVisible && mWindowExposed;
689
714
QPoint UbuntuWindow::mapToGlobal(const QPoint &pos) const
716
741
mSurface->onSwapBuffersDone();
744
void UbuntuWindow::handleScreenPropertiesChange(MirFormFactor formFactor, float scale)
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"));
753
if (!qFuzzyCompare(scale, mScale)) {
755
// update the panelHeight hack since it depends on GU
756
updatePanelHeightHack(mSurface->state() != mir_surface_state_fullscreen);
758
Q_EMIT mNativeInterface->windowPropertyChanged(this, QStringLiteral("scale"));
719
762
void UbuntuWindow::updateSurfaceState()
721
764
QMutexLocker lock(&mMutex);