You've already forked ukui-greeter
mirror of
https://github.com/ukui/ukui-greeter.git
synced 2026-03-09 09:25:38 -07:00
309 lines
8.8 KiB
C++
309 lines
8.8 KiB
C++
/* mainwindow.cpp
|
|
* Copyright (C) 2018 Tianjin KYLIN Information Technology Co., 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; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* 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, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
|
|
* 02110-1301, USA.
|
|
**/
|
|
#include "mainwindow.h"
|
|
#include <QDesktopWidget>
|
|
#include <QApplication>
|
|
#include <QPainter>
|
|
#include <QMouseEvent>
|
|
#include <QKeyEvent>
|
|
#include <QDebug>
|
|
#include <QDir>
|
|
#include <QScreen>
|
|
#include <QProcess>
|
|
#include <QtMath>
|
|
#include <QTimer>
|
|
#include "globalv.h"
|
|
#include "greeterwindow.h"
|
|
#include "common/configuration.h"
|
|
#include "common/monitorwatcher.h"
|
|
#include "display-switch/displayservice.h"
|
|
|
|
bool MainWindow::m_first = true;
|
|
|
|
MainWindow::MainWindow(QWidget *parent)
|
|
: QWidget(parent),
|
|
m_screenModel(new ScreenModel(this)),
|
|
m_configuration(Configuration::instance()),
|
|
m_activeScreen(nullptr),
|
|
m_monitorWatcher(new MonitorWatcher(this)),
|
|
m_timer(nullptr),
|
|
m_background(nullptr)
|
|
{
|
|
QDesktopWidget *_desktop = QApplication::desktop();
|
|
connect(_desktop, &QDesktopWidget::resized, this, &MainWindow::onScreenResized);
|
|
/* QDesktopWidget对显示器的插拔的支持不好 */
|
|
connect(m_monitorWatcher, &MonitorWatcher::monitorCountChanged, this, &MainWindow::onScreenCountChanged);
|
|
|
|
//设置窗口大小
|
|
setFixedSize(QApplication::primaryScreen()->virtualSize());
|
|
//设置监控鼠标移动
|
|
setMouseTracking(true);
|
|
|
|
//cof
|
|
m_cof.load(m_configuration->getValue("cof").toString());
|
|
|
|
//背景图片 优先级:用户桌面背景、背景图片、背景颜色
|
|
m_defaultBackgroundPath = m_configuration->getDefaultBackgroundName();
|
|
bool drawUserBackground = m_configuration->getValue("draw-user-background").toBool();
|
|
if(drawUserBackground) {
|
|
m_backgroundMode = DRAW_USER_BACKGROUND;
|
|
} else {
|
|
m_background = QSharedPointer<Background>(new Background);
|
|
QString backgroundPath = m_configuration->getValue("background").toString();
|
|
if(!backgroundPath.isEmpty()) {
|
|
m_backgroundMode = DRAW_BACKGROUND;
|
|
|
|
m_background->type = BACKGROUND_IMAGE;
|
|
m_background->image = backgroundPath;
|
|
} else {
|
|
QString color = m_configuration->getValue("background-color").toString();
|
|
if(!color.isEmpty()) {
|
|
m_backgroundMode = DRAW_COLOR;
|
|
|
|
m_background->type = BACKGROUND_COLOR;
|
|
m_background->color = color;
|
|
} else {
|
|
m_backgroundMode = DRAW_DEFAULT;
|
|
|
|
m_background->type = BACKGROUND_IMAGE;
|
|
m_background->image = m_defaultBackgroundPath;
|
|
}
|
|
}
|
|
}
|
|
qDebug() << "default background:" << m_defaultBackgroundPath;
|
|
if(m_background)
|
|
qDebug() << m_background->type << m_background->image;
|
|
|
|
m_timer = new QTimer(this);
|
|
m_transition.started = false;
|
|
|
|
//激活屏幕(即Greeter窗口所在屏幕位置)
|
|
m_greeterWnd = new GreeterWindow(this);
|
|
moveToScreen(QApplication::primaryScreen());
|
|
m_greeterWnd->initUI();
|
|
|
|
m_monitorWatcher->start();
|
|
|
|
connect(m_timer, &QTimer::timeout, this, &MainWindow::onTransition);
|
|
}
|
|
|
|
void MainWindow::paintEvent(QPaintEvent *e)
|
|
{
|
|
for(QScreen *screen : QApplication::screens()){
|
|
//在每个屏幕上绘制背景
|
|
QRect rect = screen->geometry();
|
|
|
|
|
|
if(m_transition.started)
|
|
drawTransitionAlpha(rect);
|
|
else {
|
|
drawBackground(m_background, rect);
|
|
}
|
|
|
|
QPainter painter(this);
|
|
|
|
//在没有登录窗口的屏幕上显示图标
|
|
if(screen != m_activeScreen)
|
|
{
|
|
QRect cofRect(rect.left() + (rect.width()-m_cof.width())/2,
|
|
rect.top() + (rect.height()-m_cof.height())/2,
|
|
m_cof.width(), m_cof.height());
|
|
painter.drawPixmap(cofRect, m_cof);
|
|
}
|
|
}
|
|
return QWidget::paintEvent(e);
|
|
}
|
|
|
|
|
|
/**
|
|
* 根据鼠标指针移动位置移动Greeter窗口所在屏幕
|
|
*/
|
|
void MainWindow::mouseMoveEvent(QMouseEvent *e)
|
|
{
|
|
if(QApplication::screens().count() > 1){
|
|
QPoint point = e->pos();
|
|
QScreen *curScreen = nullptr;
|
|
for(QScreen *screen : QApplication::screens()){
|
|
QRect screenRect = screen->geometry();
|
|
if(screenRect.contains(point)) {
|
|
curScreen = screen;
|
|
break;
|
|
}
|
|
}
|
|
if(curScreen != m_activeScreen && curScreen != nullptr){
|
|
qDebug() << "active screen: from " << m_activeScreen << "to " << curScreen;
|
|
moveToScreen(curScreen);
|
|
}
|
|
}
|
|
return QWidget::mouseMoveEvent(e);
|
|
}
|
|
|
|
/**
|
|
* 有屏幕分辨率发生改变,移动Greeter窗口位置
|
|
*/
|
|
void MainWindow::onScreenResized()
|
|
{
|
|
setGeometry(QApplication::desktop()->geometry());
|
|
qDebug() << "screen resize to " << geometry();
|
|
|
|
moveToScreen(QApplication::primaryScreen());
|
|
}
|
|
|
|
/**
|
|
* 有屏幕插拔,移动GreeterWindow到主屏幕
|
|
*/
|
|
void MainWindow::onScreenCountChanged(int newCount)
|
|
{
|
|
if(newCount < 2) {
|
|
QProcess enableMonitors;
|
|
enableMonitors.start("xrandr --auto");
|
|
enableMonitors.waitForFinished(-1);
|
|
} else {
|
|
DisplayService displayService;
|
|
displayService.switchDisplayMode(DISPLAY_MODE_EXTEND);
|
|
}
|
|
// if(m_first){
|
|
// show();
|
|
// activateWindow();
|
|
// }
|
|
|
|
move(0, 0);
|
|
setFixedSize(m_monitorWatcher->getVirtualSize());
|
|
moveToScreen(QApplication::primaryScreen());
|
|
repaint();
|
|
qDebug() << "total screen resize to " << geometry();
|
|
}
|
|
|
|
/**
|
|
* 移动Greeter窗口到screen屏幕上
|
|
*/
|
|
void MainWindow::moveToScreen(QScreen *screen)
|
|
{
|
|
m_activeScreen = screen;
|
|
QRect activeScreenRect = m_activeScreen->geometry();
|
|
if(m_monitorWatcher->getMonitorCount() == 1)
|
|
activeScreenRect = QRect(QPoint(0, 0), m_monitorWatcher->getVirtualSize());
|
|
m_greeterWnd->setGeometry(activeScreenRect);
|
|
Q_EMIT activeScreenChanged(activeScreenRect);
|
|
|
|
repaint();
|
|
}
|
|
|
|
void MainWindow::setBackground(QSharedPointer<Background> &background)
|
|
{
|
|
if(background)
|
|
qDebug() << background->image;
|
|
|
|
if(m_backgroundMode != DRAW_USER_BACKGROUND)
|
|
return;
|
|
|
|
stopTransition();
|
|
|
|
if(background) {
|
|
if(background->image.isEmpty())
|
|
background->image = m_defaultBackgroundPath;
|
|
}
|
|
|
|
if(m_background && background &&
|
|
m_background->image == background->image){
|
|
repaint();
|
|
return;
|
|
}
|
|
|
|
//如果是第一次绘制背景,则不需要渐变
|
|
if(!m_background.isNull())
|
|
startTransition(m_background, background);
|
|
|
|
m_background = background;
|
|
}
|
|
|
|
void MainWindow::startTransition(QSharedPointer<Background> &from,
|
|
QSharedPointer<Background> &to)
|
|
{
|
|
stopTransition();
|
|
|
|
m_transition.from = from;
|
|
m_transition.to = to;
|
|
m_transition.stage = 0.0;
|
|
m_transition.started = true;
|
|
|
|
m_timer->start(50);
|
|
}
|
|
|
|
void MainWindow::stopTransition()
|
|
{
|
|
if(m_timer && m_timer->isActive())
|
|
m_timer->stop();
|
|
m_transition.stage = 1.0;
|
|
m_transition.started = false;
|
|
}
|
|
|
|
void MainWindow::onTransition()
|
|
{
|
|
m_transition.stage += 0.05;//= (1 - cos(M_PI * m_transition.stage)) / 2;
|
|
|
|
if(m_transition.stage >= 1.0)
|
|
stopTransition();
|
|
|
|
repaint();
|
|
}
|
|
|
|
void MainWindow::drawTransitionAlpha(const QRect &rect)
|
|
{
|
|
drawBackground(m_transition.from, rect, 1.0 - m_transition.stage);
|
|
|
|
drawBackground(m_transition.to, rect, m_transition.stage);
|
|
}
|
|
|
|
void MainWindow::drawBackground(QSharedPointer<Background> &background,
|
|
const QRect &rect, float alpha)
|
|
{
|
|
if(background == nullptr)
|
|
return;
|
|
|
|
QPainter painter(this);
|
|
painter.setOpacity(alpha);
|
|
|
|
switch(background->type) {
|
|
case BACKGROUND_IMAGE:
|
|
{
|
|
QPixmap *pixmap = getBackground(background->image, rect);
|
|
painter.drawPixmap(rect, *pixmap);
|
|
break;
|
|
}
|
|
case BACKGROUND_COLOR:
|
|
{
|
|
painter.setBrush(background->color);
|
|
painter.drawRect(rect);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
QPixmap * MainWindow::getBackground(const QString &path, const QRect &rect)
|
|
{
|
|
QString resolution = QString("%1x%2").arg(rect.width()).arg(rect.height());
|
|
QPair<QString, QString> key(path, resolution);
|
|
|
|
if(!m_backgrounds.contains(key))
|
|
m_backgrounds[key] = new QPixmap(scaledPixmap(width(), height(), path));
|
|
|
|
return m_backgrounds[key];
|
|
}
|