feat(desktop): ship the desktop as the org.cutefish.filemanager.desktop QML module

main
reionwong 3 weeks ago
parent 9b1332be2f
commit 36686ab228

@ -11,8 +11,9 @@ set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
include(GNUInstallDirs)
find_package(Qt6 COMPONENTS Core DBus Quick LinguistTools REQUIRED)
# find_package(FishUI REQUIRED)
find_package(KF6KIO)
find_package(KF6Solid)
@ -20,15 +21,30 @@ find_package(KF6WindowSystem)
find_package(KF6Config)
find_package(KF6XmlGui REQUIRED)
qt6_add_dbus_adaptor(DBUS_SOURCES
com.cutefish.FileManager.xml
application.h Application)
add_executable(cutefish-filemanager
main.cpp
application.cpp
# Where QML modules go, so the desktop plugin lands next to FishUI.
find_program(QT_PATHS_EXECUTABLE NAMES qtpaths6 REQUIRED)
execute_process(COMMAND ${QT_PATHS_EXECUTABLE} -query QT_INSTALL_QML
OUTPUT_VARIABLE INSTALL_QMLDIR
OUTPUT_STRIP_TRAILING_WHITESPACE
)
if (NOT INSTALL_QMLDIR)
message(FATAL_ERROR "qml directory cannot be detected.")
endif ()
# ---------------------------------------------------------------------------
# cutefish-filemanager-core
#
# Everything the file manager knows about files: models, jobs, thumbnails,
# dialogs, drag and drop, and the shared QML. Both the file manager window and
# the desktop QML plugin are built on top of it, so the desktop and the browser
# behave the same and there is only one place to fix a bug.
# ---------------------------------------------------------------------------
add_library(cutefish-filemanager-core STATIC
qmltypes.cpp
# FolderModel opens its delete dialog through Window, so the shared code
# cannot live in the executable alone -- the desktop plugin needs it too.
window.cpp
dbusinterface.cpp
draganddrop/declarativedroparea.cpp
draganddrop/declarativedragdropevent.cpp
@ -47,11 +63,10 @@ add_executable(cutefish-filemanager
dialogs/createfolderdialog.cpp
dialogs/filepropertiesdialog.cpp
dialogs/openwithdialog.cpp
widgets/rubberband.cpp
widgets/itemviewadapter.cpp
desktop/desktop.cpp
desktop/desktopview.cpp
desktop/desktopsettings.cpp
desktop/dockdbusinterface.cpp
@ -71,12 +86,18 @@ add_executable(cutefish-filemanager
desktopiconprovider.cpp
qml.qrc
)
${DBUS_SOURCES}
# The core is linked into a shared plugin, so it has to be position independent.
set_target_properties(cutefish-filemanager-core PROPERTIES POSITION_INDEPENDENT_CODE ON)
target_include_directories(cutefish-filemanager-core PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
target_link_libraries(cutefish-filemanager
PRIVATE
target_link_libraries(cutefish-filemanager-core
PUBLIC
Qt6::Core
Qt6::DBus
Qt6::Quick
@ -88,10 +109,30 @@ target_link_libraries(cutefish-filemanager
KF6::WindowSystem
KF6::ConfigCore
KF6::XmlGui
)
# FishUI
# ---------------------------------------------------------------------------
# cutefish-filemanager -- the file browser window
# ---------------------------------------------------------------------------
qt6_add_dbus_adaptor(DBUS_SOURCES
com.cutefish.FileManager.xml
application.h Application)
add_executable(cutefish-filemanager
main.cpp
application.cpp
dbusinterface.cpp
${DBUS_SOURCES}
)
target_link_libraries(cutefish-filemanager PRIVATE cutefish-filemanager-core)
# ---------------------------------------------------------------------------
# The desktop, as a QML module for cutefish-shell
# ---------------------------------------------------------------------------
add_subdirectory(desktopplugin)
file(GLOB TS_FILES translations/*.ts)
qt6_add_translation(QM_FILES ${TS_FILES})
add_custom_target(translations DEPENDS ${QM_FILES} SOURCES ${TS_FILES})

@ -1,55 +0,0 @@
/*
* 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 <QQmlContext>
#include <QQmlEngine>
#include <QGuiApplication>
#include <QDBusServiceWatcher>
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);
}
}

@ -1,84 +0,0 @@
/*
* Copyright (C) 2021 CutefishOS Team.
*
* Author: revenmartin <revenmartin@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 "desktopview.h"
#include "dockdbusinterface.h"
#include "thumbnailer/thumbnailprovider.h"
#include "desktopiconprovider.h"
#include <QQmlEngine>
#include <QQmlContext>
#include <QDebug>
#include <QGuiApplication>
#include <QScreen>
#include <KX11Extras>
DesktopView::DesktopView(QScreen *screen, QQuickView *parent)
: QQuickView(parent)
, m_screen(screen)
{
m_screenRect = m_screen->geometry();
this->setFlag(Qt::FramelessWindowHint);
this->setColor(QColor(Qt::transparent));
KX11Extras::setType(winId(), NET::Desktop);
KX11Extras::setState(winId(), NET::KeepBelow);
engine()->rootContext()->setContextProperty("desktopView", this);
engine()->rootContext()->setContextProperty("Dock", DockDBusInterface::self());
QWindow::fromWinId(winId())->setOpacity(0.99);
engine()->addImageProvider("thumbnailer", new ThumbnailProvider());
engine()->addImageProvider("icontheme", new DesktopIconProvider());
setTitle(tr("Desktop"));
setScreen(m_screen);
setResizeMode(QQuickView::SizeRootObjectToView);
onGeometryChanged();
onPrimaryScreenChanged(QGuiApplication::primaryScreen());
// 主屏改变
connect(qGuiApp, &QGuiApplication::primaryScreenChanged, this, &DesktopView::onPrimaryScreenChanged);
connect(m_screen, &QScreen::virtualGeometryChanged, this, &DesktopView::onGeometryChanged);
connect(m_screen, &QScreen::geometryChanged, this, &DesktopView::onGeometryChanged);
}
QRect DesktopView::screenRect()
{
return m_screenRect;
}
void DesktopView::onPrimaryScreenChanged(QScreen *screen)
{
bool isPrimaryScreen = m_screen->name() == screen->name();
onGeometryChanged();
setSource(isPrimaryScreen ? QStringLiteral("qrc:/qml/Desktop/Main.qml")
: QStringLiteral("qrc:/qml/Desktop/Wallpaper.qml"));
}
void DesktopView::onGeometryChanged()
{
m_screenRect = m_screen->geometry().adjusted(0, 0, 1, 1);
setGeometry(m_screenRect);
emit screenRectChanged();
}

@ -1,49 +0,0 @@
/*
* Copyright (C) 2021 CutefishOS Team.
*
* Author: revenmartin <revenmartin@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 DESKTOPVIEW_H
#define DESKTOPVIEW_H
#include <QQuickView>
#include <QScreen>
class Desktop;
class DesktopView : public QQuickView
{
Q_OBJECT
Q_PROPERTY(QRect screenRect READ screenRect NOTIFY screenRectChanged)
public:
explicit DesktopView(QScreen *screen = nullptr, QQuickView *parent = nullptr);
QRect screenRect();
signals:
void screenRectChanged();
private slots:
void onPrimaryScreenChanged(QScreen *screen);
void onGeometryChanged();
private:
QScreen *m_screen;
QRect m_screenRect;
};
#endif // DESKTOPVIEW_H

@ -0,0 +1,23 @@
# org.cutefish.filemanager.desktop
#
# Wraps the file manager core as a QML module so a shell can host the desktop
# without depending on KIO. The module installs as a normal Qt QML module, so
# `import org.cutefish.filemanager.desktop 1.0` just works.
set(PLUGIN_TARGET cutefishdesktopplugin)
set(PLUGIN_INSTALL_DIR ${INSTALL_QMLDIR}/org/cutefish/filemanager/desktop)
add_library(${PLUGIN_TARGET} MODULE
desktopplugin.cpp
desktopview.cpp
)
target_link_libraries(${PLUGIN_TARGET} PRIVATE
Qt6::Core
Qt6::Qml
Qt6::Quick
cutefish-filemanager-core
)
install(TARGETS ${PLUGIN_TARGET} DESTINATION ${PLUGIN_INSTALL_DIR})
install(FILES qmldir DESTINATION ${PLUGIN_INSTALL_DIR})

@ -0,0 +1,56 @@
/*
* Copyright (C) 2021 CutefishOS Team.
*
* 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 "desktopview.h"
#include "qmltypes.h"
#include <QQmlEngine>
#include <QQmlExtensionPlugin>
/**
* "org.cutefish.filemanager.desktop" -- the file manager's desktop, packaged so
* that any QML host (currently cutefish-shell) can place it in a window without
* linking against KIO or knowing anything about files.
*/
class CutefishDesktopPlugin : public QQmlExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid)
public:
void registerTypes(const char *uri) override
{
Q_ASSERT(QLatin1String(uri) == QLatin1String("org.cutefish.filemanager.desktop"));
CutefishFM::initResources();
CutefishFM::registerQmlTypes();
qmlRegisterType<DesktopView>(uri, 1, 0, "DesktopView");
}
void initializeEngine(QQmlEngine *engine, const char *uri) override
{
Q_UNUSED(uri)
// Qt 6 only runs this for the first engine that imports the module, so
// DesktopView registers the providers itself as well. Doing it here too
// keeps them available before any desktop item is instantiated.
CutefishFM::registerImageProviders(engine);
}
};
#include "desktopplugin.moc"

@ -0,0 +1,166 @@
/*
* Copyright (C) 2021 CutefishOS Team.
*
* 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 "desktopview.h"
#include "qmltypes.h"
#include "desktop/dockdbusinterface.h"
#include <QQmlComponent>
#include <QQmlContext>
#include <QQmlEngine>
#include <QScreen>
#include <QDebug>
static const char *kDesktopRootQml = "qrc:/qml/Desktop/Root.qml";
DesktopView::DesktopView(QQuickItem *parent)
: QQuickItem(parent)
, m_component(nullptr)
, m_context(nullptr)
, m_content(nullptr)
, m_primary(false)
{
setFlag(ItemHasContents, false);
CutefishFM::initResources();
}
DesktopView::~DesktopView() = default;
QScreen *DesktopView::screen() const
{
return m_screen.data();
}
void DesktopView::setScreen(QScreen *screen)
{
if (m_screen == screen)
return;
if (m_screen)
disconnect(m_screen, nullptr, this, nullptr);
m_screen = screen;
if (m_screen) {
connect(m_screen, &QScreen::geometryChanged, this, &DesktopView::updateScreenRect);
connect(m_screen, &QScreen::virtualGeometryChanged, this, &DesktopView::updateScreenRect);
}
emit screenChanged();
updateScreenRect();
}
bool DesktopView::isPrimary() const
{
return m_primary;
}
void DesktopView::setPrimary(bool primary)
{
if (m_primary == primary)
return;
m_primary = primary;
emit primaryChanged();
}
QString DesktopView::screenName() const
{
return m_screen ? m_screen->name() : QString();
}
QRect DesktopView::screenRect() const
{
return m_screenRect;
}
void DesktopView::updateScreenRect()
{
const QRect rect = m_screen ? m_screen->geometry() : QRect();
if (m_screenRect == rect)
return;
m_screenRect = rect;
emit screenRectChanged();
}
void DesktopView::componentComplete()
{
QQuickItem::componentComplete();
createContent();
}
void DesktopView::createContent()
{
if (m_content)
return;
QQmlEngine *engine = qmlEngine(this);
if (!engine) {
qWarning() << "DesktopView: no QML engine, cannot create the desktop.";
return;
}
CutefishFM::registerQmlTypes();
CutefishFM::registerImageProviders(engine);
// A dedicated child context keeps the desktop's context properties out of
// the host's root context, so several desktops (one per screen) can live in
// one engine without seeing each other's state.
m_context = new QQmlContext(qmlContext(this), this);
m_context->setContextProperty(QStringLiteral("desktopView"), this);
m_context->setContextProperty(QStringLiteral("Dock"), DockDBusInterface::self());
m_component = new QQmlComponent(engine, QUrl(QString::fromLatin1(kDesktopRootQml)), this);
if (m_component->isError()) {
qWarning() << "DesktopView: failed to load" << kDesktopRootQml << m_component->errors();
return;
}
QObject *object = m_component->beginCreate(m_context);
m_content = qobject_cast<QQuickItem *>(object);
if (!m_content) {
qWarning() << "DesktopView: the desktop root is not an Item." << m_component->errors();
delete object;
return;
}
m_content->setParentItem(this);
resizeContent();
m_component->completeCreate();
if (m_component->isError())
qWarning() << "DesktopView:" << m_component->errors();
}
void DesktopView::resizeContent()
{
if (m_content) {
m_content->setPosition(QPointF(0, 0));
m_content->setSize(size());
}
}
void DesktopView::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
{
QQuickItem::geometryChange(newGeometry, oldGeometry);
resizeContent();
}

@ -0,0 +1,96 @@
/*
* Copyright (C) 2021 CutefishOS Team.
*
* 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 CUTEFISH_DESKTOPVIEW_H
#define CUTEFISH_DESKTOPVIEW_H
#include <QQuickItem>
#include <QPointer>
#include <QRect>
class QQmlComponent;
class QQmlContext;
class QScreen;
/**
* The whole Cutefish desktop as a single QML item.
*
* Everything the desktop does -- wallpaper, icons, layout, selection, drag and
* drop, context menus and file operations -- lives behind this item and reuses
* the file manager core. A host only has to place the item in a window and tell
* it which screen it is on:
*
* import org.cutefish.filemanager.desktop 1.0
*
* DesktopView {
* anchors.fill: parent
* screen: Qt.application.screens[0]
* primary: true
* }
*
* The item owns no window state (flags, type hints, stacking); that is the
* host's job, so the same item works on X11, Wayland or inside a test harness.
*/
class DesktopView : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(QScreen *screen READ screen WRITE setScreen NOTIFY screenChanged)
Q_PROPERTY(bool primary READ isPrimary WRITE setPrimary NOTIFY primaryChanged)
Q_PROPERTY(QString screenName READ screenName NOTIFY screenChanged)
Q_PROPERTY(QRect screenRect READ screenRect NOTIFY screenRectChanged)
public:
explicit DesktopView(QQuickItem *parent = nullptr);
~DesktopView() override;
QScreen *screen() const;
void setScreen(QScreen *screen);
/**
* Only the primary screen shows icons; the others show the wallpaper alone,
* which is what the standalone desktop process used to do by swapping its
* QML source.
*/
bool isPrimary() const;
void setPrimary(bool primary);
QString screenName() const;
QRect screenRect() const;
signals:
void screenChanged();
void primaryChanged();
void screenRectChanged();
protected:
void componentComplete() override;
void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override;
private:
void createContent();
void updateScreenRect();
void resizeContent();
QQmlComponent *m_component;
QQmlContext *m_context;
QQuickItem *m_content;
QPointer<QScreen> m_screen;
QRect m_screenRect;
bool m_primary;
};
#endif // CUTEFISH_DESKTOPVIEW_H

@ -0,0 +1,2 @@
module org.cutefish.filemanager.desktop
plugin cutefishdesktopplugin

@ -18,55 +18,16 @@
*/
#include "application.h"
#include "model/placesmodel.h"
#include "model/foldermodel.h"
#include "model/pathbarmodel.h"
#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"
#include "helper/fm.h"
#include "helper/shortcut.h"
#include "draganddrop/declarativedragdropevent.h"
#include "draganddrop/declarativedroparea.h"
#include "draganddrop/declarativemimedata.h"
#include <QMimeData>
#include "qmltypes.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true);
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
// Register QML Type.
const char *uri = "Cutefish.FileManager";
const char *dragandrop_uri = "Cutefish.DragDrop";
qmlRegisterType<PlacesModel>(uri, 1, 0, "PlacesModel");
qmlRegisterType<FolderModel>(uri, 1, 0, "FolderModel");
qmlRegisterType<PathBarModel>(uri, 1, 0, "PathBarModel");
qmlRegisterType<Positioner>(uri, 1, 0, "Positioner");
qmlRegisterType<RubberBand>(uri, 1, 0, "RubberBand");
qmlRegisterType<ItemViewAdapter>(uri, 1, 0, "ItemViewAdapter");
qmlRegisterType<DesktopSettings>(uri, 1, 0, "DesktopSettings");
qmlRegisterType<Fm>(uri, 1, 0, "Fm");
qmlRegisterType<ShortCut>(uri, 1, 0, "ShortCut");
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
qmlRegisterType<QAction>();
qmlRegisterType<QMimeData>();
#else
qmlRegisterAnonymousType<QAction>(uri, 1);
qmlRegisterAnonymousType<QMimeData>(dragandrop_uri, 1);
#endif
qmlRegisterType<DeclarativeDropArea>(dragandrop_uri, 1, 0, "DropArea");
qmlRegisterUncreatableType<DeclarativeMimeData>(dragandrop_uri, 1, 0, "MimeData", QStringLiteral("MimeData cannot be created from QML."));
qmlRegisterUncreatableType<DeclarativeDragDropEvent>(dragandrop_uri, 2, 0, "DragDropEvent", QStringLiteral("DragDropEvent cannot be created from QML."));
// Same registration the desktop plugin performs, so both hosts of the
// shared QML see exactly the same types.
CutefishFM::registerQmlTypes();
Application app(argc, argv);
return app.run();

@ -16,6 +16,7 @@
<file>images/light/grid.svg</file>
<file>images/light/list.svg</file>
<file>qml/PathBar.qml</file>
<file>qml/Desktop/Root.qml</file>
<file>qml/Desktop/Main.qml</file>
<file>qml/FolderGridView.qml</file>
<file>qml/GlobalSettings.qml</file>

@ -1,8 +1,6 @@
/*
* 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
@ -17,28 +15,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DESKTOP_H
#define DESKTOP_H
#include <QObject>
#include <QScreen>
#include <QDBusInterface>
#include "desktopview.h"
class Desktop : public QObject
{
Q_OBJECT
public:
explicit Desktop(QObject *parent = nullptr);
import QtQuick 2.12
private slots:
void screenAdded(QScreen *qscreen);
void screenRemoved(QScreen *qscreen);
// Entry point of the desktop, loaded by the DesktopView item. The primary
// screen gets the full desktop (wallpaper + icons); the others get the
// wallpaper on its own.
Loader {
id: root
private:
QMap<QScreen *, DesktopView *> m_list;
};
asynchronous: false
source: desktopView.primary ? "Main.qml" : "Wallpaper.qml"
#endif // DESKTOP_H
onLoaded: {
item.width = Qt.binding(function() { return root.width })
item.height = Qt.binding(function() { return root.height })
}
}

@ -43,8 +43,12 @@ Item {
visible: settings.backgroundVisible
cache: false
// Clear cache
onSourceChanged: dirModel.clearPixmapCache()
// Clear cache. On secondary screens the wallpaper is the whole
// desktop, so there is no folder model to clear.
onSourceChanged: {
if (typeof dirModel !== "undefined")
dirModel.clearPixmapCache()
}
ColorOverlay {
id: dimsWallpaper

@ -18,9 +18,17 @@
*/
import QtQuick 2.12
import Qt.labs.settings 1.0
import QtCore
Settings {
// Pinned to one file on purpose. This QML is loaded both by the file
// manager window and, through the desktop plugin, by cutefish-shell; the
// default location follows the host application's name, which would give
// the two hosts different preferences and silently reset the desktop's
// icon size the first time the shell started.
location: StandardPaths.writableLocation(StandardPaths.GenericConfigLocation)
+ "/cutefishos/cutefish-filemanager.conf"
property int viewMethod: 1 // controls display mode: list or grid
// Port to C++

@ -0,0 +1,99 @@
/*
* Copyright (C) 2021 CutefishOS Team.
*
* 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 "qmltypes.h"
#include "model/placesmodel.h"
#include "model/foldermodel.h"
#include "model/pathbarmodel.h"
#include "model/positioner.h"
#include "widgets/rubberband.h"
#include "widgets/itemviewadapter.h"
#include "desktop/desktopsettings.h"
#include "helper/datehelper.h"
#include "helper/fm.h"
#include "helper/shortcut.h"
#include "desktopiconprovider.h"
#include "thumbnailer/thumbnailprovider.h"
#include "draganddrop/declarativedragdropevent.h"
#include "draganddrop/declarativedroparea.h"
#include "draganddrop/declarativemimedata.h"
#include <QQmlEngine>
#include <QMimeData>
#include <QAction>
// Q_INIT_RESOURCE declares an extern symbol, so it must be expanded at global
// scope rather than inside the CutefishFM namespace.
static void initCoreResources()
{
Q_INIT_RESOURCE(qml);
}
namespace CutefishFM {
void registerQmlTypes()
{
static bool registered = false;
if (registered)
return;
registered = true;
const char *uri = "Cutefish.FileManager";
const char *dragandrop_uri = "Cutefish.DragDrop";
qmlRegisterType<PlacesModel>(uri, 1, 0, "PlacesModel");
qmlRegisterType<FolderModel>(uri, 1, 0, "FolderModel");
qmlRegisterType<PathBarModel>(uri, 1, 0, "PathBarModel");
qmlRegisterType<Positioner>(uri, 1, 0, "Positioner");
qmlRegisterType<RubberBand>(uri, 1, 0, "RubberBand");
qmlRegisterType<ItemViewAdapter>(uri, 1, 0, "ItemViewAdapter");
qmlRegisterType<DesktopSettings>(uri, 1, 0, "DesktopSettings");
qmlRegisterType<Fm>(uri, 1, 0, "Fm");
qmlRegisterType<ShortCut>(uri, 1, 0, "ShortCut");
qmlRegisterAnonymousType<QAction>(uri, 1);
qmlRegisterAnonymousType<QMimeData>(dragandrop_uri, 1);
qmlRegisterType<DeclarativeDropArea>(dragandrop_uri, 1, 0, "DropArea");
qmlRegisterUncreatableType<DeclarativeMimeData>(dragandrop_uri, 1, 0, "MimeData",
QStringLiteral("MimeData cannot be created from QML."));
qmlRegisterUncreatableType<DeclarativeDragDropEvent>(dragandrop_uri, 2, 0, "DragDropEvent",
QStringLiteral("DragDropEvent cannot be created from QML."));
}
void initResources()
{
// The core is a static library, so the resource initialiser is only pulled
// in if something references it explicitly.
initCoreResources();
}
void registerImageProviders(QQmlEngine *engine)
{
if (!engine)
return;
if (!engine->imageProvider(QStringLiteral("thumbnailer")))
engine->addImageProvider(QStringLiteral("thumbnailer"), new ThumbnailProvider);
if (!engine->imageProvider(QStringLiteral("icontheme")))
engine->addImageProvider(QStringLiteral("icontheme"), new DesktopIconProvider);
}
}

@ -0,0 +1,54 @@
/*
* Copyright (C) 2021 CutefishOS Team.
*
* 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 CUTEFISH_FILEMANAGER_QMLTYPES_H
#define CUTEFISH_FILEMANAGER_QMLTYPES_H
class QQmlEngine;
namespace CutefishFM {
/**
* Registers every QML type of the file manager core: the "Cutefish.FileManager"
* and "Cutefish.DragDrop" modules.
*
* Both the file manager executable and the desktop QML plugin call this, so the
* shared QML (FolderGridView, dialogs, the desktop) behaves identically in
* either host. Calling it more than once is harmless.
*/
void registerQmlTypes();
/**
* Makes the core's compiled-in resources (":/qml", ":/images", ":/templates")
* available. Required because the core is a static library: without an explicit
* reference the linker would drop the resource initialiser.
*/
void initResources();
/**
* Installs the image providers the shared QML expects ("thumbnailer" and
* "icontheme") on @p engine, unless they are already present.
*
* Qt 6 only calls QQmlExtensionPlugin::initializeEngine() for the first engine
* that imports a module, so FishUI's own "icontheme" provider is missing from
* every engine created afterwards.
*/
void registerImageProviders(QQmlEngine *engine);
}
#endif // CUTEFISH_FILEMANAGER_QMLTYPES_H

@ -18,7 +18,7 @@
*/
#include "window.h"
#include "desktopiconprovider.h"
#include "qmltypes.h"
#include <QEvent>
#include <QDebug>
#include <QQuickWindow>
@ -30,7 +30,7 @@ Window::Window(QObject *parent)
// Qt6 only calls QQmlExtensionPlugin::initializeEngine() for the first engine
// that imports a module, so FishUI's "icontheme" provider is missing in every
// engine created afterwards. Register our own copy for each window.
addImageProvider("icontheme", new DesktopIconProvider());
CutefishFM::registerImageProviders(this);
}
void Window::load(const QUrl &url)

Loading…
Cancel
Save