Multi screen support
This commit is contained in:
parent
5e18359d6f
commit
3c389e7950
14 changed files with 250 additions and 61 deletions
|
@ -36,6 +36,7 @@ add_executable(cutefish-filemanager
|
|||
widgets/rubberband.cpp
|
||||
widgets/itemviewadapter.cpp
|
||||
|
||||
desktop/desktop.cpp
|
||||
desktop/desktopview.cpp
|
||||
desktop/desktopsettings.cpp
|
||||
|
||||
|
|
51
desktop/desktop.cpp
Normal file
51
desktop/desktop.cpp
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (C) 2021 CutefishOS Team.
|
||||
*
|
||||
* Author: Reion Wong <reionwong@gmail.com>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "desktop.h"
|
||||
#include <QGuiApplication>
|
||||
|
||||
Desktop::Desktop(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
for (QScreen *screen : QGuiApplication::screens()) {
|
||||
screenAdded(screen);
|
||||
}
|
||||
|
||||
connect(qApp, &QGuiApplication::screenAdded, this, &Desktop::screenAdded);
|
||||
connect(qApp, &QGuiApplication::screenRemoved, this, &Desktop::screenRemoved);
|
||||
}
|
||||
|
||||
void Desktop::screenAdded(QScreen *screen)
|
||||
{
|
||||
if (!m_list.contains(screen)) {
|
||||
DesktopView *view = new DesktopView(screen);
|
||||
view->show();
|
||||
m_list.insert(screen, view);
|
||||
}
|
||||
}
|
||||
|
||||
void Desktop::screenRemoved(QScreen *screen)
|
||||
{
|
||||
if (m_list.contains(screen)) {
|
||||
DesktopView *view = m_list.find(screen).value();
|
||||
view->setVisible(false);
|
||||
view->deleteLater();
|
||||
m_list.remove(screen);
|
||||
}
|
||||
}
|
43
desktop/desktop.h
Normal file
43
desktop/desktop.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (C) 2021 CutefishOS Team.
|
||||
*
|
||||
* Author: Reion Wong <reionwong@gmail.com>
|
||||
*
|
||||
* 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 3 of the License, or
|
||||
* 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DESKTOP_H
|
||||
#define DESKTOP_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QScreen>
|
||||
|
||||
#include "desktopview.h"
|
||||
|
||||
class Desktop : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit Desktop(QObject *parent = nullptr);
|
||||
|
||||
private slots:
|
||||
void screenAdded(QScreen *qscreen);
|
||||
void screenRemoved(QScreen *qscreen);
|
||||
|
||||
private:
|
||||
QMap<QScreen *, DesktopView *> m_list;
|
||||
};
|
||||
|
||||
#endif // DESKTOP_H
|
|
@ -24,16 +24,19 @@
|
|||
#include <QQmlContext>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QApplication>
|
||||
#include <QGuiApplication>
|
||||
#include <QScreen>
|
||||
|
||||
#include <KWindowSystem>
|
||||
|
||||
DesktopView::DesktopView(QQuickView *parent)
|
||||
DesktopView::DesktopView(QScreen *screen, QQuickView *parent)
|
||||
: QQuickView(parent)
|
||||
, m_screen(screen)
|
||||
{
|
||||
m_screenRect = qApp->primaryScreen()->geometry();
|
||||
m_screenAvailableRect = qApp->primaryScreen()->availableVirtualGeometry();
|
||||
m_screenRect = m_screen->geometry();
|
||||
m_screenAvailableRect = m_screen->availableVirtualGeometry();
|
||||
|
||||
qDebug() << screen->name() << m_screenAvailableRect;
|
||||
|
||||
KWindowSystem::setType(winId(), NET::Desktop);
|
||||
KWindowSystem::setState(winId(), NET::KeepBelow);
|
||||
|
@ -42,16 +45,19 @@ DesktopView::DesktopView(QQuickView *parent)
|
|||
engine()->addImageProvider("thumbnailer", new ThumbnailProvider());
|
||||
|
||||
setTitle(tr("Desktop"));
|
||||
setScreen(qApp->primaryScreen());
|
||||
setScreen(m_screen);
|
||||
setResizeMode(QQuickView::SizeRootObjectToView);
|
||||
setSource(QStringLiteral("qrc:/qml/Desktop/Main.qml"));
|
||||
|
||||
onGeometryChanged();
|
||||
onPrimaryScreenChanged(QGuiApplication::primaryScreen());
|
||||
|
||||
connect(qApp->primaryScreen(), &QScreen::virtualGeometryChanged, this, &DesktopView::onGeometryChanged);
|
||||
connect(qApp->primaryScreen(), &QScreen::geometryChanged, this, &DesktopView::onGeometryChanged);
|
||||
connect(qApp->primaryScreen(), &QScreen::availableGeometryChanged, this, &DesktopView::onAvailableGeometryChanged);
|
||||
connect(qApp->primaryScreen(), &QScreen::virtualGeometryChanged, this, &DesktopView::onAvailableGeometryChanged);
|
||||
// 主屏改变
|
||||
connect(qGuiApp, &QGuiApplication::primaryScreenChanged, this, &DesktopView::onPrimaryScreenChanged);
|
||||
|
||||
connect(m_screen, &QScreen::virtualGeometryChanged, this, &DesktopView::onGeometryChanged);
|
||||
connect(m_screen, &QScreen::geometryChanged, this, &DesktopView::onGeometryChanged);
|
||||
connect(m_screen, &QScreen::availableGeometryChanged, this, &DesktopView::onAvailableGeometryChanged);
|
||||
connect(m_screen, &QScreen::virtualGeometryChanged, this, &DesktopView::onAvailableGeometryChanged);
|
||||
}
|
||||
|
||||
QRect DesktopView::screenRect()
|
||||
|
@ -64,9 +70,17 @@ QRect DesktopView::screenAvailableRect()
|
|||
return m_screenAvailableRect;
|
||||
}
|
||||
|
||||
void DesktopView::onPrimaryScreenChanged(QScreen *screen)
|
||||
{
|
||||
bool isPrimaryScreen = m_screen->name() == screen->name();
|
||||
|
||||
setSource(isPrimaryScreen ? QStringLiteral("qrc:/qml/Desktop/Main.qml")
|
||||
: QStringLiteral("qrc:/qml/Desktop/Wallpaper.qml"));
|
||||
}
|
||||
|
||||
void DesktopView::onGeometryChanged()
|
||||
{
|
||||
m_screenRect = qApp->primaryScreen()->geometry().adjusted(0, 0, 1, 1);
|
||||
m_screenRect = m_screen->geometry().adjusted(0, 0, 1, 1);
|
||||
setGeometry(m_screenRect);
|
||||
emit screenRectChanged();
|
||||
}
|
||||
|
@ -75,6 +89,6 @@ void DesktopView::onAvailableGeometryChanged(const QRect &geometry)
|
|||
{
|
||||
Q_UNUSED(geometry);
|
||||
|
||||
m_screenAvailableRect = qApp->primaryScreen()->availableVirtualGeometry();
|
||||
m_screenAvailableRect = m_screen->availableVirtualGeometry();
|
||||
emit screenAvailableGeometryChanged();
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#define DESKTOPVIEW_H
|
||||
|
||||
#include <QQuickView>
|
||||
#include <QScreen>
|
||||
|
||||
class DesktopView : public QQuickView
|
||||
{
|
||||
|
@ -29,7 +30,7 @@ class DesktopView : public QQuickView
|
|||
Q_PROPERTY(QRect screenAvailableRect READ screenAvailableRect NOTIFY screenAvailableGeometryChanged)
|
||||
|
||||
public:
|
||||
explicit DesktopView(QQuickView *parent = nullptr);
|
||||
explicit DesktopView(QScreen *screen = nullptr, QQuickView *parent = nullptr);
|
||||
|
||||
QRect screenRect();
|
||||
QRect screenAvailableRect();
|
||||
|
@ -39,10 +40,12 @@ signals:
|
|||
void screenAvailableGeometryChanged();
|
||||
|
||||
private slots:
|
||||
void onPrimaryScreenChanged(QScreen *screen);
|
||||
void onGeometryChanged();
|
||||
void onAvailableGeometryChanged(const QRect &geometry);
|
||||
|
||||
private:
|
||||
QScreen *m_screen;
|
||||
QRect m_screenRect;
|
||||
QRect m_screenAvailableRect;
|
||||
};
|
||||
|
|
4
main.cpp
4
main.cpp
|
@ -31,6 +31,7 @@
|
|||
#include "model/positioner.h"
|
||||
#include "widgets/rubberband.h"
|
||||
#include "widgets/itemviewadapter.h"
|
||||
#include "desktop/desktop.h"
|
||||
#include "desktop/desktopsettings.h"
|
||||
#include "desktop/desktopview.h"
|
||||
#include "helper/datehelper.h"
|
||||
|
@ -94,8 +95,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
if (parser.isSet(desktopOption)) {
|
||||
app.setApplicationName("cutefish-desktop");
|
||||
DesktopView view;
|
||||
view.show();
|
||||
Desktop desktop;
|
||||
return app.exec();
|
||||
} else if (parser.isSet(emptyTrashOption)) {
|
||||
// Empty Dialog
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
#include "../helper/datehelper.h"
|
||||
#include "../helper/filelauncher.h"
|
||||
|
||||
#include "../cio/cfilesizejob.h"
|
||||
|
||||
// Qt
|
||||
#include <QSet>
|
||||
#include <QDir>
|
||||
|
@ -79,10 +81,12 @@ FolderModel::FolderModel(QObject *parent)
|
|||
, m_filterPatternMatchAll(true)
|
||||
, m_complete(false)
|
||||
, m_isDesktop(false)
|
||||
, m_selectedItemSize("")
|
||||
, m_actionCollection(this)
|
||||
, m_dragInProgress(false)
|
||||
, m_viewAdapter(nullptr)
|
||||
, m_mimeAppManager(MimeAppManager::self())
|
||||
, m_sizeJob(nullptr)
|
||||
{
|
||||
DirLister *dirLister = new DirLister(this);
|
||||
dirLister->setDelayedMimeTypes(true);
|
||||
|
@ -1100,6 +1104,10 @@ void FolderModel::openDeleteDialog()
|
|||
view->show();
|
||||
}
|
||||
|
||||
void FolderModel::updateSelectedItemsSize()
|
||||
{
|
||||
}
|
||||
|
||||
void FolderModel::restoreFromTrash()
|
||||
{
|
||||
if (!m_selectionModel->hasSelection())
|
||||
|
@ -1134,6 +1142,35 @@ void FolderModel::selectionChanged(const QItemSelection &selected, const QItemSe
|
|||
}
|
||||
}
|
||||
|
||||
if (m_sizeJob == nullptr) {
|
||||
m_sizeJob = new CFileSizeJob;
|
||||
|
||||
connect(m_sizeJob, &CFileSizeJob::sizeChanged, this, [=] {
|
||||
m_selectedItemSize = KIO::convertSize(m_sizeJob->totalSize());
|
||||
if (!m_selectionModel->hasSelection())
|
||||
m_selectedItemSize = "";
|
||||
emit selectedItemSizeChanged();
|
||||
});
|
||||
|
||||
connect(m_sizeJob, &CFileSizeJob::result, this, [=] {
|
||||
m_selectedItemSize = KIO::convertSize(m_sizeJob->totalSize());
|
||||
if (!m_selectionModel->hasSelection())
|
||||
m_selectedItemSize = "";
|
||||
emit selectedItemSizeChanged();
|
||||
});
|
||||
}
|
||||
|
||||
m_sizeJob->stop();
|
||||
|
||||
if (!m_selectionModel->hasSelection()) {
|
||||
m_sizeJob->blockSignals(true);
|
||||
m_selectedItemSize = "";
|
||||
emit selectedItemSizeChanged();
|
||||
} else {
|
||||
m_sizeJob->blockSignals(false);
|
||||
m_sizeJob->start(selectedUrls());
|
||||
}
|
||||
|
||||
updateActions();
|
||||
|
||||
emit selectionCountChanged();
|
||||
|
@ -1246,6 +1283,11 @@ bool FolderModel::matchPattern(const KFileItem &item) const
|
|||
return false;
|
||||
}
|
||||
|
||||
QString FolderModel::selectedItemSize() const
|
||||
{
|
||||
return m_selectedItemSize;
|
||||
}
|
||||
|
||||
bool FolderModel::isDesktop() const
|
||||
{
|
||||
return m_isDesktop;
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include <KActionCollection>
|
||||
|
||||
class QDrag;
|
||||
class CFileSizeJob;
|
||||
class FolderModel : public QSortFilterProxyModel, public QQmlParserStatus
|
||||
{
|
||||
Q_OBJECT
|
||||
|
@ -57,6 +58,7 @@ class FolderModel : public QSortFilterProxyModel, public QQmlParserStatus
|
|||
Q_PROPERTY(QString filterPattern READ filterPattern WRITE setFilterPattern NOTIFY filterPatternChanged)
|
||||
Q_PROPERTY(int count READ count NOTIFY countChanged)
|
||||
Q_PROPERTY(QStringList filterMimeTypes READ filterMimeTypes WRITE setFilterMimeTypes NOTIFY filterMimeTypesChanged)
|
||||
Q_PROPERTY(QString selectedItemSize READ selectedItemSize NOTIFY selectedItemSizeChanged)
|
||||
|
||||
public:
|
||||
enum DataRole {
|
||||
|
@ -198,11 +200,15 @@ public:
|
|||
Q_INVOKABLE void openChangeWallpaperDialog();
|
||||
Q_INVOKABLE void openDeleteDialog();
|
||||
|
||||
Q_INVOKABLE void updateSelectedItemsSize();
|
||||
|
||||
void restoreFromTrash();
|
||||
|
||||
bool isDesktop() const;
|
||||
void setIsDesktop(bool isDesktop);
|
||||
|
||||
QString selectedItemSize() const;
|
||||
|
||||
signals:
|
||||
void urlChanged();
|
||||
void resolvedUrlChanged();
|
||||
|
@ -219,6 +225,7 @@ signals:
|
|||
void countChanged();
|
||||
void filterPatternChanged();
|
||||
void filterMimeTypesChanged();
|
||||
void selectedItemSizeChanged();
|
||||
|
||||
void notification(const QString &message);
|
||||
|
||||
|
@ -263,6 +270,8 @@ private:
|
|||
bool m_isDesktop;
|
||||
bool m_suffixVisible;
|
||||
|
||||
QString m_selectedItemSize;
|
||||
|
||||
KActionCollection m_actionCollection;
|
||||
QHash<int, DragImage *> m_dragImages;
|
||||
QModelIndexList m_dragIndexes;
|
||||
|
@ -274,6 +283,8 @@ private:
|
|||
// Save path history
|
||||
PathHistory m_pathHistory;
|
||||
MimeAppManager *m_mimeAppManager;
|
||||
|
||||
CFileSizeJob *m_sizeJob;
|
||||
};
|
||||
|
||||
#endif // FOLDERMODEL_H
|
||||
|
|
1
qml.qrc
1
qml.qrc
|
@ -59,5 +59,6 @@
|
|||
<file>images/light/drive-optical.svg</file>
|
||||
<file>qml/Dialogs/OpenWithDialog.qml</file>
|
||||
<file>qml/Dialogs/DeleteDialog.qml</file>
|
||||
<file>qml/Desktop/Wallpaper.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -30,56 +30,12 @@ import "../"
|
|||
Item {
|
||||
id: rootItem
|
||||
|
||||
FM.DesktopSettings {
|
||||
id: settings
|
||||
}
|
||||
|
||||
GlobalSettings {
|
||||
id: globalSettings
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: backgroundLoader
|
||||
Wallpaper {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 0
|
||||
sourceComponent: settings.backgroundType === 0 ? wallpaper : background
|
||||
}
|
||||
|
||||
Component {
|
||||
id: background
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: settings.backgroundColor
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: wallpaper
|
||||
|
||||
Image {
|
||||
source: "file://" + settings.wallpaper
|
||||
sourceSize: Qt.size(width * Screen.devicePixelRatio,
|
||||
height * Screen.devicePixelRatio)
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
clip: true
|
||||
cache: false
|
||||
|
||||
ColorOverlay {
|
||||
id: dimsWallpaper
|
||||
anchors.fill: parent
|
||||
source: parent
|
||||
color: "#000000"
|
||||
opacity: FishUI.Theme.darkMode && settings.dimsWallpaper ? 0.4 : 0.0
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FM.FolderModel {
|
||||
|
|
60
qml/Desktop/Wallpaper.qml
Normal file
60
qml/Desktop/Wallpaper.qml
Normal file
|
@ -0,0 +1,60 @@
|
|||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.12
|
||||
import QtQuick.Window 2.12
|
||||
import QtGraphicalEffects 1.0
|
||||
|
||||
import Cutefish.FileManager 1.0 as FM
|
||||
import FishUI 1.0 as FishUI
|
||||
|
||||
Item {
|
||||
id: control
|
||||
|
||||
FM.DesktopSettings {
|
||||
id: settings
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: backgroundLoader
|
||||
anchors.fill: parent
|
||||
anchors.margins: 0
|
||||
sourceComponent: settings.backgroundType === 0 ? wallpaper : background
|
||||
}
|
||||
|
||||
Component {
|
||||
id: background
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: settings.backgroundColor
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: wallpaper
|
||||
|
||||
Image {
|
||||
source: "file://" + settings.wallpaper
|
||||
sourceSize: Qt.size(width * Screen.devicePixelRatio,
|
||||
height * Screen.devicePixelRatio)
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
clip: true
|
||||
cache: false
|
||||
|
||||
ColorOverlay {
|
||||
id: dimsWallpaper
|
||||
anchors.fill: parent
|
||||
source: parent
|
||||
color: "#000000"
|
||||
opacity: FishUI.Theme.darkMode && settings.dimsWallpaper ? 0.4 : 0.0
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 200
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -64,7 +64,7 @@ GridView {
|
|||
|
||||
signal keyPress(var event)
|
||||
|
||||
cacheBuffer: Math.max(0, contentHeight)
|
||||
cacheBuffer: Math.max(0, control.height * 1.5)
|
||||
|
||||
onIconSizeChanged: {
|
||||
// 图标大小改变时需要重置状态,否则选中定位不准确
|
||||
|
@ -461,6 +461,8 @@ GridView {
|
|||
dirModel.setSelected(pressedItem.index)
|
||||
}
|
||||
|
||||
dirModel.updateSelectedItemsSize()
|
||||
|
||||
pressCanceled()
|
||||
}
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ ListView {
|
|||
|
||||
currentIndex: -1
|
||||
clip: true
|
||||
cacheBuffer: width
|
||||
|
||||
ScrollBar.vertical: ScrollBar { }
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
|
|
|
@ -249,6 +249,10 @@ Item {
|
|||
visible: dirModel.selectionCount >= 1
|
||||
}
|
||||
|
||||
Label {
|
||||
text: dirModel.selectedItemSize
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue