void ScreenInfo::updateAvailableGeometry(int screen) { if (screen == m_screen) { Q_EMIT availableGeometryChanged(availableGeometry()); Q_EMIT panelsFreeGeometryChanged(panelsFreeGeometry()); } }
//Resizes the window so that "content" will have "wanted" size. //Requires that only the only resizeable widget contains "content". //Window will be moved so that it does not cross monitors boundaries. //If "wanted" size can't fit on the monitor, it will be resized //depending on "keep_aspect". If false, height and width will be clipped. //If true, it will be scaled so "content" keeps it aspect ratio. //Function returns "content"'s new size. QSize windowManager::resize_content( QSize wanted, QSize content, bool keep_aspect, bool only_upscale ){ auto desktop = QApplication::desktop(); //Get the difference in size between the content and the whole window QSize difference = window.frameGeometry().size() - content; //Prepare resize dimensions, but keep it within "space" auto getPosition = [&]( int monitor ){ //Take the full area and subtract the constant widths (which doesn't scale with aspect) QRect space = desktop->availableGeometry( monitor ); space.setSize( space.size() - difference ); QRect position = constrain( space, QRect( contrain_point( space, window.pos() ), wanted ), keep_aspect ); return std::make_pair( position, qsize_area( position.size() ) ); }; //Find the best monitor, but stay on the first monitor if several can fit the entire window auto best = getPosition( desktop->screenNumber( &window ) ); for( int i=0; i<desktop->screenCount(); i++ ) best = std::max( best, getPosition( i ), []( std::pair<QRect,int> a, std::pair<QRect,int> b ){ return a.second < b.second; } ); //Move and resize window. We need to convert dimensions to window size though. window.move( best.first.topLeft() ); window.resize( best.first.size() + window.size() - content ); return best.first.size(); }
const QRect XfitMan::availableGeometry(const QWidget *widget) const { if (!widget) { qWarning("XfitMan::availableGeometry(): Attempt " "to get the available geometry of a null widget"); return QRect(); } return availableGeometry(QApplication::desktop()->screenNumber(widget)); }
void ScreenInfo::setScreen(int screen) { if (m_screen != screen) { m_screen = screen; Q_EMIT screenChanged(m_screen); Q_EMIT geometryChanged(geometry()); Q_EMIT availableGeometryChanged(availableGeometry()); Q_EMIT panelsFreeGeometryChanged(panelsFreeGeometry()); } }
const QRect QDesktopWidget::availableGeometry(const QWidget *widget) const { if (!widget) { qWarning("QDesktopWidget::availableGeometry(): Attempt " "to get the available geometry of a null widget"); return QRect(); } QRect rect = QWidgetPrivate::screenGeometry(widget); if (rect.isNull()) return availableGeometry(screenNumber(widget)); else return rect; }
void TaskbarProxy::showPager (int x, int y, bool showThumbs) { if (Pager_) { Pager_->deleteLater (); return; } auto desktop = QApplication::desktop (); const auto screen = desktop->screenNumber ({ x, y }); Pager_ = new PagerWindow (screen, showThumbs, Proxy_); new Util::AutoResizeMixin ({ x, y }, [screen, desktop] () { return desktop->availableGeometry (screen); }, Pager_); Pager_->show (); }
QRect ScreenInfo::panelsFreeGeometry() const { /* We cannot just return the system's availableGeometry(), because that * doesn't consider the Launcher, if it's set to auto-hide. */ QRect screenRect = QApplication::desktop()->screenGeometry(m_screen); QRect availableRect = QApplication::desktop()->availableGeometry(m_screen); const bool accountForLauncher = !launcher2dConfiguration().property("onlyOneLauncher").toBool() || m_screen == 0; QRect availableGeometry( screenRect.left() + (accountForLauncher ? LauncherClient::MaximumWidth : 0), availableRect.top(), screenRect.width() - (accountForLauncher ? LauncherClient::MaximumWidth : 0), availableRect.height() ); if (QApplication::isRightToLeft()) { availableGeometry.moveLeft(screenRect.left()); } return availableGeometry; }
/*! Convenience method to resize all the maximized and fullscreen windows of this platform screen. */ void QPlatformScreen::resizeMaximizedWindows() { QList<QWindow*> windows = QGuiApplication::allWindows(); // 'screen()' still has the old geometry info while 'this' has the new geometry info const QRect oldGeometry = screen()->geometry(); const QRect oldAvailableGeometry = screen()->availableGeometry(); const QRect newGeometry = geometry(); const QRect newAvailableGeometry = availableGeometry(); // make sure maximized and fullscreen windows are updated for (int i = 0; i < windows.size(); ++i) { QWindow *w = windows.at(i); if (platformScreenForWindow(w) != this) continue; if (w->windowState() & Qt::WindowMaximized || w->geometry() == oldAvailableGeometry) w->setGeometry(newAvailableGeometry); else if (w->windowState() & Qt::WindowFullScreen || w->geometry() == oldGeometry) w->setGeometry(newGeometry); } }
const QRect XfitMan::availableGeometry(const QPoint &point) const { return availableGeometry(QApplication::desktop()->screenNumber(point)); }
/*! \brief handle the XCB screen change event and update properties On a mobile device, the ideal use case is that the accelerometer would drive the orientation. This could be achieved by using QSensors to read the accelerometer and adjusting the rotation in QML, or by reading the orientation from the QScreen object and doing the same, or in many other ways. However, on X we have the XRandR extension, which makes it possible to have the whole screen rotated, so that individual apps DO NOT have to rotate themselves. Apps could optionally use the QScreen::primaryOrientation property to optimize layout though. Furthermore, there is no support in X for accelerometer events anyway. So it makes more sense on a Linux system running X to just run a daemon which monitors the accelerometer and runs xrandr automatically to do the rotation, then apps do not have to be aware of it (but probably the window manager would resize them accordingly). updateGeometry() is written with this design in mind. Therefore the physical geometry, available geometry, virtual geometry, orientation and primaryOrientation should all change at the same time. On a system which cannot rotate the whole screen, it would be correct for only the orientation (not the primary orientation) to change. */ void QXcbScreen::handleScreenChange(xcb_randr_screen_change_notify_event_t *change_event) { updateGeometry(change_event->config_timestamp); switch (change_event->rotation) { case XCB_RANDR_ROTATION_ROTATE_0: // xrandr --rotate normal m_orientation = Qt::LandscapeOrientation; m_virtualSize.setWidth(change_event->width); m_virtualSize.setHeight(change_event->height); m_virtualSizeMillimeters.setWidth(change_event->mwidth); m_virtualSizeMillimeters.setHeight(change_event->mheight); break; case XCB_RANDR_ROTATION_ROTATE_90: // xrandr --rotate left m_orientation = Qt::PortraitOrientation; m_virtualSize.setWidth(change_event->height); m_virtualSize.setHeight(change_event->width); m_virtualSizeMillimeters.setWidth(change_event->mheight); m_virtualSizeMillimeters.setHeight(change_event->mwidth); break; case XCB_RANDR_ROTATION_ROTATE_180: // xrandr --rotate inverted m_orientation = Qt::InvertedLandscapeOrientation; m_virtualSize.setWidth(change_event->width); m_virtualSize.setHeight(change_event->height); m_virtualSizeMillimeters.setWidth(change_event->mwidth); m_virtualSizeMillimeters.setHeight(change_event->mheight); break; case XCB_RANDR_ROTATION_ROTATE_270: // xrandr --rotate right m_orientation = Qt::InvertedPortraitOrientation; m_virtualSize.setWidth(change_event->height); m_virtualSize.setHeight(change_event->width); m_virtualSizeMillimeters.setWidth(change_event->mheight); m_virtualSizeMillimeters.setHeight(change_event->mwidth); break; // We don't need to do anything with these, since QScreen doesn't store reflection state, // and Qt-based applications probably don't need to care about it anyway. case XCB_RANDR_ROTATION_REFLECT_X: break; case XCB_RANDR_ROTATION_REFLECT_Y: break; } QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry()); QWindowSystemInterface::handleScreenAvailableGeometryChange(QPlatformScreen::screen(), availableGeometry()); QWindowSystemInterface::handleScreenOrientationChange(QPlatformScreen::screen(), m_orientation); QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(QPlatformScreen::screen(), Q_MM_PER_INCH * m_virtualSize.width() / m_virtualSizeMillimeters.width(), Q_MM_PER_INCH * m_virtualSize.height() / m_virtualSizeMillimeters.height()); }