Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Plasma
Plasma Mobile
Commits
1dd63227
Commit
1dd63227
authored
Mar 16, 2022
by
Devin Lin
🎨
Browse files
quicksettings/screenshot: Move C++ out of ShellUtil into package
parent
24c5b4a6
Pipeline
#151161
failed with stages
in 37 seconds
Changes
13
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
libmobileshell/CMakeLists.txt
View file @
1dd63227
...
...
@@ -7,8 +7,7 @@ if (BUILD_TESTING)
add_subdirectory
(
autotests
)
endif
()
qt_add_dbus_interfaces
(
DBUS_SRCS dbus/org.kde.KWin.ScreenShot2.xml
dbus/org.kde.KScreen.xml
qt_add_dbus_interfaces
(
DBUS_SRCS dbus/org.kde.KScreen.xml
${
KWIN_VIRTUALKEYBOARD_INTERFACE
}
)
set
(
mobileshell_LIB_SRCS
...
...
libmobileshell/shellutil.cpp
View file @
1dd63227
...
...
@@ -31,8 +31,6 @@
using
namespace
MobileShell
;
constexpr
int
SCREENSHOT_DELAY
=
200
;
/* -- Static Helpers --------------------------------------------------------------------------- */
static
QImage
allocateImage
(
const
QVariantMap
&
metadata
)
...
...
@@ -81,10 +79,6 @@ ShellUtil::ShellUtil(QObject *parent)
{
// setHasConfigurationInterface(true);
m_kscreenInterface
=
new
org
::
kde
::
KScreen
(
QStringLiteral
(
"org.kde.kded5"
),
QStringLiteral
(
"/modules/kscreen"
),
QDBusConnection
::
sessionBus
(),
this
);
m_screenshotInterface
=
new
OrgKdeKWinScreenShot2Interface
(
QStringLiteral
(
"org.kde.KWin.ScreenShot2"
),
QStringLiteral
(
"/org/kde/KWin/ScreenShot2"
),
QDBusConnection
::
sessionBus
(),
this
);
m_localeConfig
=
KSharedConfig
::
openConfig
(
QStringLiteral
(
"kdeglobals"
),
KConfig
::
SimpleConfig
);
m_localeConfigWatcher
=
KConfigWatcher
::
create
(
m_localeConfig
);
...
...
@@ -130,10 +124,12 @@ void ShellUtil::toggleTorch()
m_running
=
!
m_running
;
Q_EMIT
torchChanged
(
m_running
);
}
bool
ShellUtil
::
torchEnabled
()
const
{
return
m_running
;
}
bool
ShellUtil
::
autoRotate
()
{
QDBusPendingReply
<
bool
>
reply
=
m_kscreenInterface
->
getAutoRotate
();
...
...
@@ -157,76 +153,6 @@ void ShellUtil::setAutoRotate(bool value)
}
}
void
ShellUtil
::
handleMetaDataReceived
(
const
QVariantMap
&
metadata
,
int
fd
)
{
const
QString
type
=
metadata
.
value
(
QStringLiteral
(
"type"
)).
toString
();
if
(
type
!=
QLatin1String
(
"raw"
))
{
qWarning
()
<<
"Unsupported metadata type:"
<<
type
;
return
;
}
auto
watcher
=
new
QFutureWatcher
<
QImage
>
(
this
);
connect
(
watcher
,
&
QFutureWatcher
<
QImage
>::
finished
,
this
,
[
watcher
]()
{
watcher
->
deleteLater
();
QString
filePath
=
QStandardPaths
::
writableLocation
(
QStandardPaths
::
PicturesLocation
);
if
(
filePath
.
isEmpty
())
{
qWarning
()
<<
"Couldn't find a writable location for the screenshot!"
;
return
;
}
QDir
picturesDir
(
filePath
);
if
(
!
picturesDir
.
mkpath
(
QStringLiteral
(
"Screenshots"
)))
{
qWarning
()
<<
"Couldn't create folder at"
<<
picturesDir
.
path
()
+
QStringLiteral
(
"/Screenshots"
)
<<
"to take screenshot."
;
return
;
}
filePath
+=
QStringLiteral
(
"/Screenshots/Screenshot_%1.png"
).
arg
(
QDateTime
::
currentDateTime
().
toString
(
QStringLiteral
(
"yyyyMMdd_hhmmss"
)));
const
auto
m_result
=
watcher
->
result
();
if
(
m_result
.
isNull
()
||
!
m_result
.
save
(
filePath
))
{
qWarning
()
<<
"Screenshot failed"
;
}
else
{
KNotification
*
notif
=
new
KNotification
(
"captured"
);
notif
->
setComponentName
(
QStringLiteral
(
"plasma_phone_components"
));
notif
->
setTitle
(
i18n
(
"New Screenshot"
));
notif
->
setUrls
({
QUrl
::
fromLocalFile
(
filePath
)});
notif
->
setText
(
i18n
(
"New screenshot saved to %1"
,
filePath
));
notif
->
sendEvent
();
}
});
watcher
->
setFuture
(
QtConcurrent
::
run
(
readImage
,
fd
,
metadata
));
}
void
ShellUtil
::
takeScreenshot
()
{
// wait ~200 ms to wait for rest of animations
QTimer
::
singleShot
(
SCREENSHOT_DELAY
,
[
=
]()
{
int
lPipeFds
[
2
];
if
(
pipe2
(
lPipeFds
,
O_CLOEXEC
)
!=
0
)
{
qWarning
()
<<
"Could not take screenshot"
;
return
;
}
// We don't have access to the ScreenPool so we'll just take the first screen
QVariantMap
options
;
options
.
insert
(
QStringLiteral
(
"native-resolution"
),
true
);
auto
pendingCall
=
m_screenshotInterface
->
CaptureScreen
(
qGuiApp
->
screens
().
constFirst
()
->
name
(),
options
,
QDBusUnixFileDescriptor
(
lPipeFds
[
1
]));
close
(
lPipeFds
[
1
]);
auto
pipeFileDescriptor
=
lPipeFds
[
0
];
auto
watcher
=
new
QDBusPendingCallWatcher
(
pendingCall
,
this
);
connect
(
watcher
,
&
QDBusPendingCallWatcher
::
finished
,
this
,
[
this
,
watcher
,
pipeFileDescriptor
]()
{
watcher
->
deleteLater
();
const
QDBusPendingReply
<
QVariantMap
>
reply
=
*
watcher
;
if
(
reply
.
isError
())
{
qWarning
()
<<
"Screenshot request failed:"
<<
reply
.
error
().
message
();
}
else
{
handleMetaDataReceived
(
reply
,
pipeFileDescriptor
);
}
});
});
}
bool
ShellUtil
::
isSystem24HourFormat
()
{
KConfigGroup
localeSettings
=
KConfigGroup
(
m_localeConfig
,
"Locale"
);
...
...
libmobileshell/shellutil.h
View file @
1dd63227
...
...
@@ -36,7 +36,6 @@ public Q_SLOTS:
void
executeCommand
(
const
QString
&
command
);
void
launchApp
(
const
QString
&
app
);
void
toggleTorch
();
void
takeScreenshot
();
bool
autoRotate
();
void
setAutoRotate
(
bool
value
);
...
...
@@ -51,14 +50,12 @@ Q_SIGNALS:
void
isSystem24HourFormatChanged
();
private:
void
handleMetaDataReceived
(
const
QVariantMap
&
metadata
,
int
fd
);
bool
m_running
=
false
;
KConfigWatcher
::
Ptr
m_localeConfigWatcher
;
KSharedConfig
::
Ptr
m_localeConfig
;
org
::
kde
::
KScreen
*
m_kscreenInterface
;
OrgKdeKWinScreenShot2Interface
*
m_screenshotInterface
;
};
}
// namespace MobileShell
quicksettings/CMakeLists.txt
View file @
1dd63227
...
...
@@ -11,8 +11,8 @@ plasma_install_package(keyboardtoggle org.kde.plasma.keyboardtoggle quicksetting
plasma_install_package
(
location org.kde.plasma.location quicksettings
)
plasma_install_package
(
mobiledata org.kde.plasma.mobiledata quicksettings
)
plasma_install_package
(
screenrotation org.kde.plasma.screenrotation quicksettings
)
plasma_install_package
(
screenshot org.kde.plasma.screenshot quicksettings
)
plasma_install_package
(
settingsapp org.kde.plasma.settingsapp quicksettings
)
plasma_install_package
(
wifi org.kde.plasma.wifi quicksettings
)
add_subdirectory
(
nightcolor
)
add_subdirectory
(
powermenu
)
add_subdirectory
(
screenshot
)
quicksettings/screenshot/CMakeLists.txt
0 → 100644
View file @
1dd63227
# SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
# SPDX-License-Identifier: GPL-2.0-or-later
qt_add_dbus_interfaces
(
DBUS_SRCS dbus/org.kde.KWin.ScreenShot2.xml
)
set
(
screenshotplugin_SRCS
screenshotplugin.cpp
screenshotutil.cpp
${
DBUS_SRCS
}
)
add_library
(
screenshotplugin
${
screenshotplugin_SRCS
}
)
find_package
(
KF5
${
KF5_MIN_VERSION
}
REQUIRED COMPONENTS
Declarative
)
target_link_libraries
(
screenshotplugin
PUBLIC
Qt::Core
PRIVATE
Qt::DBus
KF5::CoreAddons
KF5::QuickAddons
KF5::ConfigCore
KF5::ConfigGui
KF5::I18n
KF5::Notifications
)
set_property
(
TARGET screenshotplugin PROPERTY LIBRARY_OUTPUT_DIRECTORY
${
CMAKE_RUNTIME_OUTPUT_DIRECTORY
}
/org/kde/plasma/quicksetting/screenshot
)
file
(
COPY qmldir DESTINATION
${
CMAKE_RUNTIME_OUTPUT_DIRECTORY
}
/org/kde/plasma/quicksetting/screenshot
)
install
(
TARGETS screenshotplugin DESTINATION
${
QML_INSTALL_DIR
}
/org/kde/plasma/quicksetting/screenshot
)
install
(
FILES qmldir
${
qml_SRC
}
DESTINATION
${
QML_INSTALL_DIR
}
/org/kde/plasma/quicksetting/screenshot
)
plasma_install_package
(
package org.kde.plasma.screenshot quicksettings
)
libmobileshell
/dbus/org.kde.KWin.ScreenShot2.xml
→
quicksettings/screenshot
/dbus/org.kde.KWin.ScreenShot2.xml
View file @
1dd63227
File moved
quicksettings/screenshot/contents/ui/main.qml
→
quicksettings/screenshot/
package/
contents/ui/main.qml
View file @
1dd63227
...
...
@@ -4,6 +4,7 @@
import
QtQuick
2.15
import
org
.
kde
.
plasma
.
private
.
mobileshell
1.0
as
MobileShell
import
org
.
kde
.
plasma
.
quicksetting
.
screenshot
1.0
MobileShell.QuickSetting
{
text
:
i18n
(
"
Screenshot
"
)
...
...
@@ -32,6 +33,6 @@ MobileShell.QuickSetting {
Timer
{
id
:
timer
interval
:
500
onTriggered
:
MobileShell
.
Shell
Util
.
takeScreen
s
hot
()
onTriggered
:
ScreenShot
Util
.
takeScreen
S
hot
()
}
}
quicksettings/screenshot/metadata.desktop
→
quicksettings/screenshot/
package/
metadata.desktop
View file @
1dd63227
File moved
quicksettings/screenshot/qmldir
0 → 100644
View file @
1dd63227
# SPDX-FileCopyrightText: 2022 Devin Lin <devin@kde.org>
# SPDX-License-Identifier: GPL-2.0-or-later
module org.kde.plasma.quicksetting.screenshot
plugin screenshotplugin
classname ScreenShotPlugin
quicksettings/screenshot/screenshotplugin.cpp
0 → 100644
View file @
1dd63227
/*
* SPDX-FileCopyrightText: 2022 by Devin Lin <devin@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include
"screenshotplugin.h"
#include
<QQmlContext>
#include
<QQuickItem>
#include
"screenshotutil.h"
void
ScreenShotPlugin
::
registerTypes
(
const
char
*
uri
)
{
Q_ASSERT
(
QLatin1String
(
uri
)
==
QLatin1String
(
"org.kde.plasma.quicksetting.screenshot"
));
qmlRegisterSingletonType
<
ScreenShotUtil
>
(
uri
,
1
,
0
,
"ScreenShotUtil"
,
[](
QQmlEngine
*
,
QJSEngine
*
)
{
return
new
ScreenShotUtil
;
});
}
//#include "moc_nightcolorplugin.cpp"
quicksettings/screenshot/screenshotplugin.h
0 → 100644
View file @
1dd63227
/*
* SPDX-FileCopyrightText: 2022 by Devin Lin <devin@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include
<QUrl>
#include
<QQmlEngine>
#include
<QQmlExtensionPlugin>
class
ScreenShotPlugin
:
public
QQmlExtensionPlugin
{
Q_OBJECT
Q_PLUGIN_METADATA
(
IID
"org.qt-project.Qt.QQmlExtensionInterface"
)
public:
void
registerTypes
(
const
char
*
uri
)
override
;
};
quicksettings/screenshot/screenshotutil.cpp
0 → 100644
View file @
1dd63227
/*
* SPDX-FileCopyrightText: 2015 Marco Martin <mart@kde.org>
* SPDX-FileCopyrightText: 2018 Bhushan Shah <bshah@kde.org>
* SPDX-FileCopyrightText: 2022 by Devin Lin <devin@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include
"screenshotutil.h"
#include
<fcntl.h>
#include
<qplatformdefs.h>
#include
<unistd.h>
#include
<KLocalizedString>
#include
<KNotification>
#include
<QGuiApplication>
#include
<QImage>
#include
<QScreen>
#include
<QTimer>
#include
<QtConcurrent/QtConcurrent>
constexpr
int
SCREENSHOT_DELAY
=
200
;
/* -- Static Helpers --------------------------------------------------------------------------- */
static
QImage
allocateImage
(
const
QVariantMap
&
metadata
)
{
bool
ok
;
const
uint
width
=
metadata
.
value
(
QStringLiteral
(
"width"
)).
toUInt
(
&
ok
);
if
(
!
ok
)
{
return
QImage
();
}
const
uint
height
=
metadata
.
value
(
QStringLiteral
(
"height"
)).
toUInt
(
&
ok
);
if
(
!
ok
)
{
return
QImage
();
}
const
uint
format
=
metadata
.
value
(
QStringLiteral
(
"format"
)).
toUInt
(
&
ok
);
if
(
!
ok
)
{
return
QImage
();
}
return
QImage
(
width
,
height
,
QImage
::
Format
(
format
));
}
static
QImage
readImage
(
int
fileDescriptor
,
const
QVariantMap
&
metadata
)
{
QFile
file
;
if
(
!
file
.
open
(
fileDescriptor
,
QFileDevice
::
ReadOnly
,
QFileDevice
::
AutoCloseHandle
))
{
close
(
fileDescriptor
);
return
QImage
();
}
QImage
result
=
allocateImage
(
metadata
);
if
(
result
.
isNull
())
{
return
QImage
();
}
QDataStream
stream
(
&
file
);
stream
.
readRawData
(
reinterpret_cast
<
char
*>
(
result
.
bits
()),
result
.
sizeInBytes
());
return
result
;
}
ScreenShotUtil
::
ScreenShotUtil
(
QObject
*
parent
)
:
QObject
{
parent
}
{
m_screenshotInterface
=
new
OrgKdeKWinScreenShot2Interface
(
QStringLiteral
(
"org.kde.KWin.ScreenShot2"
),
QStringLiteral
(
"/org/kde/KWin/ScreenShot2"
),
QDBusConnection
::
sessionBus
(),
this
);
}
void
ScreenShotUtil
::
takeScreenShot
()
{
// wait ~200 ms to wait for rest of animations
QTimer
::
singleShot
(
SCREENSHOT_DELAY
,
[
=
]()
{
int
lPipeFds
[
2
];
if
(
pipe2
(
lPipeFds
,
O_CLOEXEC
)
!=
0
)
{
qWarning
()
<<
"Could not take screenshot"
;
return
;
}
// We don't have access to the ScreenPool so we'll just take the first screen
QVariantMap
options
;
options
.
insert
(
QStringLiteral
(
"native-resolution"
),
true
);
auto
pendingCall
=
m_screenshotInterface
->
CaptureScreen
(
qGuiApp
->
screens
().
constFirst
()
->
name
(),
options
,
QDBusUnixFileDescriptor
(
lPipeFds
[
1
]));
close
(
lPipeFds
[
1
]);
auto
pipeFileDescriptor
=
lPipeFds
[
0
];
auto
watcher
=
new
QDBusPendingCallWatcher
(
pendingCall
,
this
);
connect
(
watcher
,
&
QDBusPendingCallWatcher
::
finished
,
this
,
[
this
,
watcher
,
pipeFileDescriptor
]()
{
watcher
->
deleteLater
();
const
QDBusPendingReply
<
QVariantMap
>
reply
=
*
watcher
;
if
(
reply
.
isError
())
{
qWarning
()
<<
"Screenshot request failed:"
<<
reply
.
error
().
message
();
}
else
{
handleMetaDataReceived
(
reply
,
pipeFileDescriptor
);
}
});
});
}
void
ScreenShotUtil
::
handleMetaDataReceived
(
const
QVariantMap
&
metadata
,
int
fd
)
{
const
QString
type
=
metadata
.
value
(
QStringLiteral
(
"type"
)).
toString
();
if
(
type
!=
QLatin1String
(
"raw"
))
{
qWarning
()
<<
"Unsupported metadata type:"
<<
type
;
return
;
}
auto
watcher
=
new
QFutureWatcher
<
QImage
>
(
this
);
connect
(
watcher
,
&
QFutureWatcher
<
QImage
>::
finished
,
this
,
[
watcher
]()
{
watcher
->
deleteLater
();
QString
filePath
=
QStandardPaths
::
writableLocation
(
QStandardPaths
::
PicturesLocation
);
if
(
filePath
.
isEmpty
())
{
qWarning
()
<<
"Couldn't find a writable location for the screenshot!"
;
return
;
}
QDir
picturesDir
(
filePath
);
if
(
!
picturesDir
.
mkpath
(
QStringLiteral
(
"Screenshots"
)))
{
qWarning
()
<<
"Couldn't create folder at"
<<
picturesDir
.
path
()
+
QStringLiteral
(
"/Screenshots"
)
<<
"to take screenshot."
;
return
;
}
filePath
+=
QStringLiteral
(
"/Screenshots/Screenshot_%1.png"
).
arg
(
QDateTime
::
currentDateTime
().
toString
(
QStringLiteral
(
"yyyyMMdd_hhmmss"
)));
const
auto
m_result
=
watcher
->
result
();
if
(
m_result
.
isNull
()
||
!
m_result
.
save
(
filePath
))
{
qWarning
()
<<
"Screenshot failed"
;
}
else
{
KNotification
*
notif
=
new
KNotification
(
"captured"
);
notif
->
setComponentName
(
QStringLiteral
(
"plasma_phone_components"
));
notif
->
setTitle
(
i18n
(
"New Screenshot"
));
notif
->
setUrls
({
QUrl
::
fromLocalFile
(
filePath
)});
notif
->
setText
(
i18n
(
"New screenshot saved to %1"
,
filePath
));
notif
->
sendEvent
();
}
});
watcher
->
setFuture
(
QtConcurrent
::
run
(
readImage
,
fd
,
metadata
));
}
quicksettings/screenshot/screenshotutil.h
0 → 100644
View file @
1dd63227
/*
* SPDX-FileCopyrightText: 2022 by Devin Lin <devin@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#pragma once
#include
<QObject>
#include
<QVariantMap>
#include
"screenshot2interface.h"
class
ScreenShotUtil
:
public
QObject
{
Q_OBJECT
public:
ScreenShotUtil
(
QObject
*
parent
=
nullptr
);
Q_INVOKABLE
void
takeScreenShot
();
void
handleMetaDataReceived
(
const
QVariantMap
&
metadata
,
int
fd
);
private:
OrgKdeKWinScreenShot2Interface
*
m_screenshotInterface
;
};
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment