/* * Copyright (C) 2015-2016 Canonical, Ltd. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "MirSurface.h" #include #include // local #include "SurfaceManager.h" #define MIRSURFACE_DEBUG 0 #if MIRSURFACE_DEBUG #define DEBUG_MSG(params) qDebug().nospace() << "MirSurface[" << (void*)this << "," << m_name << "]::" << __func__ << " " << params #define XDEBUG_MSG(params) qDebug().nospace() << "MirSurface[" << (void*)this << "," << m_name << "]::" << params const char *stateToStr(Mir::State state) { switch (state) { case Mir::UnknownState: return "unknown"; case Mir::RestoredState: return "restored"; case Mir::MinimizedState: return "minimized"; case Mir::MaximizedState: return "maximized"; case Mir::VertMaximizedState: return "vertMaximized"; case Mir::FullscreenState: return "fullscreen"; case Mir::HorizMaximizedState: return "horizMaximized"; case Mir::MaximizedLeftState: return "maximizedLeft"; case Mir::MaximizedRightState: return "maximizedRight"; case Mir::MaximizedTopLeftState: return "maximizedTopLeft"; case Mir::MaximizedTopRightState: return "maximizedTopRight"; case Mir::MaximizedBottomLeftState: return "maximizedBottomLeft"; case Mir::MaximizedBottomRightState: return "maximizedBottomRight"; case Mir::HiddenState: return "hidden"; default: return "???"; } } #else #define DEBUG_MSG(params) ((void)0) #define XDEBUG_MSG(params) ((void)0) #endif using namespace unity::shell::application; MirSurface::MirSurface(const QString& name, Mir::Type type, Mir::State state, MirSurface *parentSurface, const QUrl& screenshot, const QUrl &qmlFilePath) : unity::shell::application::MirSurfaceInterface(nullptr) , m_name(name) , m_type(type) , m_state(state) , m_orientationAngle(Mir::Angle0) , m_screenshotUrl(screenshot) , m_qmlFilePath(qmlFilePath) , m_live(true) , m_focused(false) , m_activeFocus(false) , m_width(-1) , m_height(-1) , m_slowToResize(false) , m_shellChrome(Mir::NormalChrome) , m_parentSurface(parentSurface) , m_childSurfaceList(new MirSurfaceListModel(this)) { DEBUG_MSG("state=" << stateToStr(state)); QQmlEngine::setObjectOwnership(this, QQmlEngine::CppOwnership); m_delayedResizeTimer.setInterval(600); m_delayedResizeTimer.setSingleShot(true); connect(&m_delayedResizeTimer, &QTimer::timeout, this, &MirSurface::applyDelayedResize); m_zombieTimer.setInterval(100); m_zombieTimer.setSingleShot(true); connect(&m_zombieTimer, &QTimer::timeout, this, [this](){ this->setLive(false); }); updateInputBoundsAfterResize(); } MirSurface::~MirSurface() { DEBUG_MSG(""); // Early warning, while MirSurface methods can still be accessed. Q_EMIT destroyed(this); } QString MirSurface::name() const { return m_name; } QString MirSurface::persistentId() const { return m_name+"Id"; } QString MirSurface::appId() const { return m_name+"appId"; } Mir::Type MirSurface::type() const { return m_type; } Mir::State MirSurface::state() const { return m_state; } void MirSurface::requestState(Mir::State state) { if (state == m_state) { return; } DEBUG_MSG(stateToStr(state)); Q_EMIT stateRequested(state); } void MirSurface::setState(Mir::State state) { if (state == m_state) { return; } DEBUG_MSG(stateToStr(state)); bool oldVisible = visible(); m_state = state; Q_EMIT stateChanged(state); if (visible() != oldVisible) { XDEBUG_MSG("visibleChanged("<count(); ++i) { m_childSurfaceList->get(i)->close(); } if (!m_zombieTimer.isActive()) { m_zombieTimer.start(); Q_EMIT closeRequested(); } } void MirSurface::activate() { DEBUG_MSG(""); SurfaceManager::instance()->activate(this); } void MirSurface::requestFocus() { DEBUG_MSG(""); Q_EMIT focusRequested(); } void MirSurface::setFocused(bool value) { if (m_focused == value) return; DEBUG_MSG("(" << value << ")"); m_focused = value; Q_EMIT focusedChanged(value); } bool MirSurface::focused() const { return m_focused; } QRect MirSurface::inputBounds() const { return m_inputBounds; } void MirSurface::setInputBounds(const QRect &boundsRect) { if (boundsRect != m_inputBounds) { m_inputBounds = boundsRect; DEBUG_MSG("(" << m_inputBounds << ")"); Q_EMIT inputBoundsChanged(m_inputBounds); } } void MirSurface::openMenu(qreal x, qreal y, qreal width, qreal height) { auto *menu = SurfaceManager::instance()->createSurface("menu", Mir::MenuType, Mir::HiddenState, this /* parentSurface */, QUrl() /* screenshot */, QUrl("qrc:///Unity/Application/KateMenu.qml")); menu->setRequestedPosition(QPoint(x,y)); menu->resize(width, height); menu->requestState(Mir::RestoredState); SurfaceManager::instance()->notifySurfaceCreated(menu); } void MirSurface::openDialog(qreal x, qreal y, qreal width, qreal height) { auto *dialog = SurfaceManager::instance()->createSurface("dialog", Mir::DialogType, Mir::HiddenState, this /* parentSurface */, QUrl() /* screenshot */, QUrl("qrc:///Unity/Application/KateDialog.qml")); dialog->setRequestedPosition(QPoint(x,y)); dialog->resize(width, height); dialog->requestState(Mir::RestoredState); SurfaceManager::instance()->notifySurfaceCreated(dialog); dialog->requestFocus(); } void MirSurface::setRequestedPosition(const QPoint &value) { if (value != m_requestedPosition) { m_requestedPosition = value; Q_EMIT requestedPositionChanged(value); // fake-miral: always comply m_position = m_requestedPosition; XDEBUG_MSG("positionChanged("<