[graphics/spectacle] /: Option to launch Spectacle without taking a screenshot or using last used capture mode

Méven Car null at kde.org
Tue Oct 19 18:45:46 BST 2021


Git commit 731f8b16c6b5b01c2c3f785eba7a7ea9f4b682ac by Méven Car, on behalf of Antonio Prcela.
Committed on 19/10/2021 at 17:45.
Pushed by meven into branch 'master'.

Option to launch Spectacle without taking a screenshot or using last used capture mode

FEATURE: 437368

Adds an option to set so one can launch spectacle with either taking a fullscreen screenshot, using last capture mode or not taking a screenshot on launch.

M  +8    -0    dbus/org.kde.Spectacle.xml
M  +9    -1    desktop/org.kde.spectacle.desktop.cmake
M  +2    -1    desktop/spectacle_newConfig.upd
M  +7    -1    doc/index.docbook
M  +7    -0    doc/man-spectacle.1.docbook
M  +5    -0    src/Gui/KSImageWidget.cpp
M  +1    -0    src/Gui/KSImageWidget.h
M  +15   -1    src/Gui/KSMainWindow.cpp
M  +1    -0    src/Gui/KSMainWindow.h
M  +29   -0    src/Gui/KSWidget.cpp
M  +4    -0    src/Gui/KSWidget.h
M  +47   -20   src/Gui/SettingsDialog/GeneralOptions.ui
M  +2    -1    src/Gui/SettingsDialog/GeneralOptionsPage.cpp
M  +9    -0    src/Gui/SettingsDialog/spectacle.kcfg
M  +11   -0    src/ShortcutActions.cpp
M  +1    -0    src/ShortcutActions.h
M  +53   -15   src/SpectacleCore.cpp
M  +3    -0    src/SpectacleCore.h
M  +5    -0    src/SpectacleDBusAdapter.cpp
M  +1    -0    src/SpectacleDBusAdapter.h

https://invent.kde.org/graphics/spectacle/commit/731f8b16c6b5b01c2c3f785eba7a7ea9f4b682ac

diff --git a/dbus/org.kde.Spectacle.xml b/dbus/org.kde.Spectacle.xml
index 40bd884..0ecd693 100644
--- a/dbus/org.kde.Spectacle.xml
+++ b/dbus/org.kde.Spectacle.xml
@@ -98,6 +98,14 @@
             </doc:doc>
         </method>
 
+        <method name="OpenWithoutScreenshot">
+            <doc:doc>
+                <doc:description>
+                    <doc:para>Launches Spectacle without taking a screenshot.</doc:para>
+                </doc:description>
+            </doc:doc>
+        </method>
+
         <signal name="ScreenshotTaken">
             <arg name="fileName" direction="out" type="s">
                 <doc:doc>
diff --git a/desktop/org.kde.spectacle.desktop.cmake b/desktop/org.kde.spectacle.desktop.cmake
index ba4064d..ac86e3d 100644
--- a/desktop/org.kde.spectacle.desktop.cmake
+++ b/desktop/org.kde.spectacle.desktop.cmake
@@ -168,7 +168,7 @@ Icon=spectacle
 Type=Application
 Terminal=false
 StartupNotify=false
-Actions=FullScreenScreenShot;CurrentMonitorScreenShot;ActiveWindowScreenShot;RectangularRegionScreenShot;WindowUnderCursorScreenShot;
+Actions=FullScreenScreenShot;CurrentMonitorScreenShot;ActiveWindowScreenShot;RectangularRegionScreenShot;WindowUnderCursorScreenShot;OpenWithoutScreenshot;
 X-DBUS-StartupType=Unique
 X-DBUS-ServiceName=org.kde.Spectacle
 X-KDE-Shortcuts=Print
@@ -402,3 +402,11 @@ Name[x-test]=xxCapture Window Under Cursorxx
 Name[zh_CN]=捕获光标所在窗口
 Exec=@QtBinariesDir@/qdbus org.kde.Spectacle / WindowUnderCursor true false
 X-KDE-Shortcuts=Meta+Ctrl+Print
+
+[Desktop Action OpenWithoutScreenshot]
+Name=Launch without taking a screenshot
+Name[de]=Ohne Aufnahme starten
+Name[en_GB]=Launch without taking a screenshot
+Name[sr at ijekavianlatin]=Pokreni bez snimanja
+Name[sr at latin]=Pokreni bez snimanja
+Exec=@QtBinariesDir@/qdbus org.kde.Spectacle / OpenWithoutScreenshot
diff --git a/desktop/spectacle_newConfig.upd b/desktop/spectacle_newConfig.upd
index f843010..48d304e 100644
--- a/desktop/spectacle_newConfig.upd
+++ b/desktop/spectacle_newConfig.upd
@@ -1,4 +1,4 @@
-Version=5
+Version=6
 Id=spectacle-new-config
 File=spectaclerc
 Group=GuiConfig,General
@@ -12,6 +12,7 @@ Group=GuiConfig,Save
 Key=compressionQuality
 Key=lastUsedSaveMode
 Group=General,Save
+Key=onLaunchActionIndex,onLaunchAction
 Key=copySaveLocation
 Key=lastSaveAsFile,lastSaveAsLocation
 Key=lastSaveFile,lastSaveLocation
diff --git a/doc/index.docbook b/doc/index.docbook
index ad39f8d..5d113c5 100644
--- a/doc/index.docbook
+++ b/doc/index.docbook
@@ -118,7 +118,7 @@
         <sect1 id="taking-screenshot">
             <title>Taking A Screenshot</title>
 
-            <para>When you open &spectacle;, it immediately takes a screenshot of the whole screen as a convenience and shows a preview of it in the main window. You can save this screenshot using the buttons on the bottom of the window, or take a new one using the controls to the right of the preview.</para>
+            <para>When you open &spectacle;, it immediately takes a screenshot, unless otherwise set in the general options, of the whole screen as a convenience and shows a preview of it in the main window. You can save this screenshot using the buttons on the bottom of the window, or take a new one using the controls to the right of the preview.</para>
 
             <para>To discard the current screenshot and take another screenshot, press the <guibutton>Take a New Screenshot</guibutton> (<keycombo action="simul">&Ctrl;<keycap>N</keycap></keycombo>) button.</para>
             
@@ -285,6 +285,12 @@
                     </textobject>
                 </mediaobject>
             <variablelist>
+                <varlistentry>
+                    <term><guilabel>When launching Spectacle</guilabel></term>
+                    <listitem>
+                        <para>Allows to <guilabel>Take full screen screenshot</guilabel>, use last-used capture mode, or do not take a screenshot automatically. The last-used capture mode is the one set in Capture Mode</para>
+                    </listitem>
+                </varlistentry>
                 <varlistentry>
                     <term><guilabel>After taking a screenshot</guilabel></term>
                     <listitem>
diff --git a/doc/man-spectacle.1.docbook b/doc/man-spectacle.1.docbook
index b45ad19..b390b96 100644
--- a/doc/man-spectacle.1.docbook
+++ b/doc/man-spectacle.1.docbook
@@ -82,6 +82,13 @@
 </listitem>
 </varlistentry>
 
+<varlistentry>
+<term><option>-l, --launchonly</option></term>
+<listitem>
+<para>Launch Spectacle without taking a screenshot.</para>
+</listitem>
+</varlistentry>
+
 <varlistentry>
 <term><option>-g, --gui</option></term>
 <listitem>
diff --git a/src/Gui/KSImageWidget.cpp b/src/Gui/KSImageWidget.cpp
index 0ff1810..6bf9abc 100644
--- a/src/Gui/KSImageWidget.cpp
+++ b/src/Gui/KSImageWidget.cpp
@@ -39,6 +39,11 @@ void KSImageWidget::setScaledPixmap()
     setPixmap(scaledPixmap);
 }
 
+bool KSImageWidget::isPixmapSet()
+{
+    return !mPixmap.isNull();
+}
+
 // drag handlers
 
 void KSImageWidget::mousePressEvent(QMouseEvent *event)
diff --git a/src/Gui/KSImageWidget.h b/src/Gui/KSImageWidget.h
index 3b16f7d..5ee53c9 100644
--- a/src/Gui/KSImageWidget.h
+++ b/src/Gui/KSImageWidget.h
@@ -23,6 +23,7 @@ class KSImageWidget : public QLabel
 public:
     explicit KSImageWidget(QWidget *parent = nullptr);
     void setScreenshot(const QPixmap &pixmap);
+    bool isPixmapSet();
 
 Q_SIGNALS:
 
diff --git a/src/Gui/KSMainWindow.cpp b/src/Gui/KSMainWindow.cpp
index 09e03fc..8612842 100644
--- a/src/Gui/KSMainWindow.cpp
+++ b/src/Gui/KSMainWindow.cpp
@@ -18,6 +18,7 @@
 #include <QDBusMessage>
 #include <QDesktopServices>
 #include <QKeyEvent>
+#include <QPainter>
 #include <QPrintDialog>
 #include <QPushButton>
 #include <QTimer>
@@ -539,6 +540,13 @@ void KSMainWindow::screenshotFailed()
                       KMessageWidget::Warning);
 }
 
+void KSMainWindow::setPlaceholderTextOnLaunch()
+{
+    QString placeholderText(i18n("Ready to take a screenshot"));
+    mKSWidget->showPlaceholderText(placeholderText);
+    setWindowTitle(placeholderText);
+}
+
 void KSMainWindow::showPreferencesDialog()
 {
     if (KConfigDialog::showDialog(QStringLiteral("settings"))) {
@@ -595,7 +603,13 @@ void KSMainWindow::restoreWindowTitle()
     if (isWindowModified()) {
         setWindowTitle(i18nc("@title:window Unsaved Screenshot", "Unsaved[*]"));
     } else {
-        setWindowTitle(Settings::lastSaveLocation().fileName());
+        // if a screenshot is not visible inside of mKSWidget, it means we have launched spectacle
+        // with the last mode set to 'rectangular region' and canceled the screenshot
+        if (mKSWidget->isScreenshotSet()) {
+            setWindowTitle(Settings::lastSaveLocation().fileName());
+        } else {
+            setPlaceholderTextOnLaunch();
+        }
     }
 }
 
diff --git a/src/Gui/KSMainWindow.h b/src/Gui/KSMainWindow.h
index d4147ef..d39955b 100644
--- a/src/Gui/KSMainWindow.h
+++ b/src/Gui/KSMainWindow.h
@@ -67,6 +67,7 @@ public Q_SLOTS:
     void imageSaved(const QUrl &location);
     void imageSavedAndCopied(const QUrl &location);
     void screenshotFailed();
+    void setPlaceholderTextOnLaunch();
 
 Q_SIGNALS:
 
diff --git a/src/Gui/KSWidget.cpp b/src/Gui/KSWidget.cpp
index 401ba89..bfdfe07 100644
--- a/src/Gui/KSWidget.cpp
+++ b/src/Gui/KSWidget.cpp
@@ -164,8 +164,23 @@ KSWidget::KSWidget(Platform::GrabModes theGrabModes, QWidget *parent)
     mRightLayout->addWidget(mTakeScreenshotButton, 1, Qt::AlignHCenter);
     mRightLayout->setContentsMargins(10, 0, 0, 10);
 
+    mPlaceholderLabel = new QLabel;
+
+    QFont placeholderLabelFont;
+    // To match the size of a level 2 Heading/KTitleWidget
+    placeholderLabelFont.setPointSize(qRound(placeholderLabelFont.pointSize() * 1.3));
+    mPlaceholderLabel->setFont(placeholderLabelFont);
+    mPlaceholderLabel->setTextInteractionFlags(Qt::NoTextInteraction);
+    mPlaceholderLabel->setWordWrap(true);
+    mPlaceholderLabel->setAlignment(Qt::AlignCenter);
+    // Match opacity of QML placeholder label component
+    auto *effect = new QGraphicsOpacityEffect(mPlaceholderLabel);
+    effect->setOpacity(0.5);
+    mPlaceholderLabel->setGraphicsEffect(effect);
+
     mMainLayout = new QGridLayout();
 
+    mMainLayout->addWidget(mPlaceholderLabel, 0, 0, 1, 1);
     mMainLayout->addWidget(mImageWidget, 0, 0, 1, 1);
     mMainLayout->addLayout(mRightLayout, 0, 1, 1, 1);
     mMainLayout->setColumnMinimumWidth(0, 320);
@@ -202,10 +217,24 @@ int KSWidget::imagePaddingWidth() const
     return lPaddingWidth;
 }
 
+bool KSWidget::isScreenshotSet()
+{
+    return mImageWidget->isPixmapSet();
+}
+
 // public slots
 
+void KSWidget::showPlaceholderText(const QString &label)
+{
+    mPlaceholderLabel->setText(label);
+    mPlaceholderLabel->show();
+}
+
 void KSWidget::setScreenshotPixmap(const QPixmap &thePixmap)
 {
+    if (mPlaceholderLabel->isVisible()) {
+        mPlaceholderLabel->hide();
+    }
     mImageWidget->setScreenshot(thePixmap);
 }
 
diff --git a/src/Gui/KSWidget.h b/src/Gui/KSWidget.h
index 86f334e..a0fcc87 100644
--- a/src/Gui/KSWidget.h
+++ b/src/Gui/KSWidget.h
@@ -44,6 +44,7 @@ public:
     enum class State { TakeNewScreenshot, Cancel };
 
     int imagePaddingWidth() const;
+    bool isScreenshotSet();
 
 Q_SIGNALS:
 
@@ -53,6 +54,7 @@ Q_SIGNALS:
 
 public Q_SLOTS:
 
+    void showPlaceholderText(const QString &label);
     void setScreenshotPixmap(const QPixmap &thePixmap);
     void lockOnClickDisabled();
     void lockOnClickEnabled();
@@ -87,12 +89,14 @@ private:
     QCheckBox *mQuitAfterSaveOrCopy{nullptr};
     QLabel *mCaptureModeLabel{nullptr};
     QLabel *mContentOptionsLabel{nullptr};
+    QLabel *mPlaceholderLabel { nullptr };
     bool mTransientWithParentAvailable{false};
     QAction *mTakeNewScreenshotAction{nullptr};
     QAction *mCancelAction{nullptr};
     KConfigDialogManager *mConfigManager{nullptr};
     QStackedLayout *mStack{nullptr};
     QWidget *placeHolder{nullptr};
+
 #ifdef KIMAGEANNOTATOR_FOUND
     kImageAnnotator::KImageAnnotator *mAnnotator{nullptr};
 #endif
diff --git a/src/Gui/SettingsDialog/GeneralOptions.ui b/src/Gui/SettingsDialog/GeneralOptions.ui
index 5141508..660deb1 100644
--- a/src/Gui/SettingsDialog/GeneralOptions.ui
+++ b/src/Gui/SettingsDialog/GeneralOptions.ui
@@ -12,20 +12,46 @@
   </property>
   <layout class="QFormLayout">
    <item row="0" column="0">
+    <widget class="QLabel" name="onLaunchSpectacleLabel">
+     <property name="text">
+      <string>When launching Spectacle:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1">
+    <widget class="QComboBox" name="kcfg_onLaunchAction">
+     <item>
+      <property name="text">
+       <string>Take full screen screenshot</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>Use last-used capture mode</string>
+      </property>
+     </item>
+     <item>
+      <property name="text">
+       <string>Do not take a screenshot automatically</string>
+      </property>
+     </item>
+    </widget>
+   </item>
+   <item row="1" column="0">
     <widget class="QLabel" name="afterScreenshotLabel">
      <property name="text">
       <string>After taking a screenshot:</string>
      </property>
     </widget>
    </item>
-   <item row="0" column="1">
+   <item row="1" column="1">
     <widget class="QCheckBox" name="kcfg_autoSaveImage">
      <property name="text">
       <string>Autosave file to default folder</string>
      </property>
     </widget>
    </item>
-   <item row="2" column="0" colspan="2">
+   <item row="3" column="0" colspan="2">
     <spacer name="verticalSpacer">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
@@ -41,21 +67,21 @@
      </property>
     </spacer>
    </item>
-   <item row="3" column="0" colspan="2">
+   <item row="4" column="0" colspan="2">
     <widget class="KTitleWidget" name="runningTitle">
      <property name="text">
       <string>While Spectacle is running</string>
      </property>
     </widget>
    </item>
-   <item row="4" column="0">
+   <item row="5" column="0">
     <widget class="QLabel" name="printKeyActionLabel">
      <property name="text">
       <string>Press screenshot key to:</string>
      </property>
     </widget>
    </item>
-   <item row="4" column="1">
+   <item row="5" column="1">
     <widget class="QGroupBox" name="kcfg_printKeyActionRunning">
      <property name="title">
       <string/>
@@ -94,7 +120,7 @@
      </layout>
     </widget>
    </item>
-   <item row="5" column="0" colspan="2">
+   <item row="6" column="0" colspan="2">
     <spacer name="verticalSpacer_2">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
@@ -110,42 +136,42 @@
      </property>
     </spacer>
    </item>
-   <item row="6" column="0" colspan="2">
+   <item row="7" column="0" colspan="2">
     <widget class="KTitleWidget" name="regionTitle">
      <property name="text">
       <string>Rectangular Region</string>
      </property>
     </widget>
    </item>
-   <item row="7" column="0">
+   <item row="8" column="0">
     <widget class="QLabel" name="generalLabel">
      <property name="text">
       <string>General:</string>
      </property>
     </widget>
    </item>
-   <item row="7" column="1">
+   <item row="8" column="1">
     <widget class="QCheckBox" name="kcfg_useLightMaskColour">
      <property name="text">
       <string>Use light background</string>
      </property>
     </widget>
    </item>
-   <item row="8" column="1">
+   <item row="9" column="1">
     <widget class="QCheckBox" name="kcfg_showMagnifier">
      <property name="text">
       <string>Show magnifier</string>
      </property>
     </widget>
    </item>
-   <item row="9" column="1">
+   <item row="10" column="1">
     <widget class="QCheckBox" name="kcfg_useReleaseToCapture">
      <property name="text">
       <string>Accept on click-and-release</string>
      </property>
     </widget>
    </item>
-   <item row="10" column="1">
+   <item row="11" column="1">
     <spacer name="verticalSpacer_3">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
@@ -161,16 +187,15 @@
      </property>
     </spacer>
    </item>
-   <item row="11" column="0">
+   <item row="12" column="0">
     <widget class="QLabel" name="rememberLabel">
      <property name="text">
       <string>Remember selected area:</string>
      </property>
     </widget>
    </item>
-   <item row="11" column="1">
-    <widget class="QRadioButton" name="
-    ">
+   <item row="12" column="1">
+    <widget class="QRadioButton" name="">
      <property name="text">
       <string>Never</string>
      </property>
@@ -182,7 +207,7 @@
      </attribute>
     </widget>
    </item>
-   <item row="12" column="1">
+   <item row="13" column="1">
     <widget class="QRadioButton" name="kcfg_alwaysRememberRegion">
      <property name="text">
       <string>Always</string>
@@ -192,7 +217,7 @@
      </attribute>
     </widget>
    </item>
-   <item row="13" column="1">
+   <item row="14" column="1">
     <widget class="QRadioButton" name="kcfg_rememberLastRectangularRegion">
      <property name="text">
       <string>Until Spectacle is closed</string>
@@ -202,7 +227,7 @@
      </attribute>
     </widget>
    </item>
-   <item row="1" column="1">
+   <item row="2" column="1">
     <widget class="QGroupBox" name="kcfg_clipboardGroup">
      <property name="title">
       <string/>
@@ -210,7 +235,7 @@
      <property name="flat">
       <bool>true</bool>
      </property>
-     <layout class="QVBoxLayout" name="verticalLayout">
+     <layout class="QVBoxLayout" name="verticalLayout2">
       <property name="leftMargin">
        <number>0</number>
       </property>
@@ -251,6 +276,8 @@
   </customwidget>
  </customwidgets>
  <tabstops>
+  <tabstop>defaultOnLaunchButton</tabstop>
+  <tabstop>kcfg_onLaunchAction</tabstop>
   <tabstop>kcfg_autoSaveImage</tabstop>
   <tabstop>newScreenshotButton</tabstop>
   <tabstop>newWindowButton</tabstop>
diff --git a/src/Gui/SettingsDialog/GeneralOptionsPage.cpp b/src/Gui/SettingsDialog/GeneralOptionsPage.cpp
index 954f2a9..fd05f67 100644
--- a/src/Gui/SettingsDialog/GeneralOptionsPage.cpp
+++ b/src/Gui/SettingsDialog/GeneralOptionsPage.cpp
@@ -13,6 +13,7 @@
 #include <KWindowSystem>
 
 #include <QCheckBox>
+#include <QComboBox>
 
 GeneralOptionsPage::GeneralOptionsPage(QWidget *parent)
     : QWidget(parent)
@@ -23,7 +24,7 @@ GeneralOptionsPage::GeneralOptionsPage(QWidget *parent)
     m_ui->runningTitle->setLevel(2);
     m_ui->regionTitle->setLevel(2);
 
-    // On Wayland  we can't programmatically raise and focus the window so we have to hide the option
+    //On Wayland  we can't programmatically raise and focus the window so we have to hide the option
     if (KWindowSystem::isPlatformWayland() || qstrcmp(qgetenv("XDG_SESSION_TYPE").data(), "wayland") == 0) {
         delete m_ui->activateWindowButton;
     }
diff --git a/src/Gui/SettingsDialog/spectacle.kcfg b/src/Gui/SettingsDialog/spectacle.kcfg
index 59bbab1..cfc3178 100644
--- a/src/Gui/SettingsDialog/spectacle.kcfg
+++ b/src/Gui/SettingsDialog/spectacle.kcfg
@@ -8,6 +8,15 @@
 <include>SpectacleCommon.h</include>
 <kcfgfile />
 <group name="General">
+    <entry name="onLaunchAction" type="Enum">
+        <label>What to do when Spectacle is launched</label>
+        <choices>
+        <choice name="TakeFullscreenScreenshot"></choice>
+        <choice name="UseLastUsedCapturemode"></choice>
+        <choice name="DoNotTakeScreenshot"></choice>
+        </choices>
+        <default>TakeFullscreenScreenshot</default>
+    </entry>
     <entry name="printKeyActionRunning" type="Enum">
         <label>What should happen if print key is pressed when Spectacle is already running</label>
         <choices>
diff --git a/src/ShortcutActions.cpp b/src/ShortcutActions.cpp
index a9420bf..c4a7a46 100644
--- a/src/ShortcutActions.cpp
+++ b/src/ShortcutActions.cpp
@@ -27,6 +27,7 @@ ShortcutActions::ShortcutActions()
     // CurrentMonitorScreenShot
     // RectangularRegionScreenShot
     // FullScreenScreenShot
+    // OpenWithoutScreenshot
     // _launch
     {
         QAction *action = new QAction(i18n("Launch Spectacle"));
@@ -58,6 +59,11 @@ ShortcutActions::ShortcutActions()
         action->setObjectName(QStringLiteral("WindowUnderCursorScreenShot"));
         mActions.addAction(action->objectName(), action);
     }
+    {
+        QAction *action = new QAction(i18n("Launch Spectacle without capturing"));
+        action->setObjectName(QStringLiteral("OpenWithoutScreenshot"));
+        mActions.addAction(action->objectName(), action);
+    }
 }
 
 KActionCollection *ShortcutActions::shortcutActions()
@@ -99,3 +105,8 @@ QAction *ShortcutActions::windowUnderCursorAction() const
 {
     return mActions.action(5);
 }
+
+QAction *ShortcutActions::openWithoutScreenshotAction() const
+{
+    return mActions.action(6);
+}
diff --git a/src/ShortcutActions.h b/src/ShortcutActions.h
index 9eb13f8..2472aa6 100644
--- a/src/ShortcutActions.h
+++ b/src/ShortcutActions.h
@@ -24,6 +24,7 @@ public:
     QAction *activeWindowAction() const;
     QAction *regionAction() const;
     QAction *windowUnderCursorAction() const;
+    QAction *openWithoutScreenshotAction() const;
 
 private:
     ShortcutActions();
diff --git a/src/SpectacleCore.cpp b/src/SpectacleCore.cpp
index 3c5806f..6b41891 100644
--- a/src/SpectacleCore.cpp
+++ b/src/SpectacleCore.cpp
@@ -85,20 +85,6 @@ void SpectacleCore::onActivateRequested(QStringList arguments, const QString & /
     populateCommandLineParser(parser.data());
     parser->parse(arguments);
 
-    // extract the capture mode
-    Spectacle::CaptureMode lCaptureMode = Spectacle::CaptureMode::AllScreens;
-    if (parser->isSet(QStringLiteral("current"))) {
-        lCaptureMode = Spectacle::CaptureMode::CurrentScreen;
-    } else if (parser->isSet(QStringLiteral("activewindow"))) {
-        lCaptureMode = Spectacle::CaptureMode::ActiveWindow;
-    } else if (parser->isSet(QStringLiteral("region"))) {
-        lCaptureMode = Spectacle::CaptureMode::RectangularRegion;
-    } else if (parser->isSet(QStringLiteral("windowundercursor"))) {
-        lCaptureMode = Spectacle::CaptureMode::TransientWithParent;
-    } else if (parser->isSet(QStringLiteral("transientonly"))) {
-        lCaptureMode = Spectacle::CaptureMode::WindowUnderCursor;
-    }
-
     mStartMode = SpectacleCore::StartMode::Gui;
     mNotify = true;
     qint64 lDelayMsec = 0;
@@ -110,6 +96,39 @@ void SpectacleCore::onActivateRequested(QStringList arguments, const QString & /
         mStartMode = SpectacleCore::StartMode::DBus;
     }
 
+    Spectacle::CaptureMode lCaptureMode = Spectacle::CaptureMode::AllScreens;
+    if (!mIsGuiInited && mStartMode == SpectacleCore::StartMode::Gui) {
+        if (parser->isSet(QStringLiteral("launchonly")) || Settings::onLaunchAction() == Settings::EnumOnLaunchAction::DoNotTakeScreenshot) {
+            initGuiNoScreenshot();
+            return;
+        } else if (Settings::onLaunchAction() == Settings::EnumOnLaunchAction::UseLastUsedCapturemode) {
+            lCaptureMode = Settings::captureMode();
+        } else if (parser->isSet(QStringLiteral("current"))) {
+            lCaptureMode = Spectacle::CaptureMode::CurrentScreen;
+        } else if (parser->isSet(QStringLiteral("activewindow"))) {
+            lCaptureMode = Spectacle::CaptureMode::ActiveWindow;
+        } else if (parser->isSet(QStringLiteral("region"))) {
+            lCaptureMode = Spectacle::CaptureMode::RectangularRegion;
+        } else if (parser->isSet(QStringLiteral("windowundercursor"))) {
+            lCaptureMode = Spectacle::CaptureMode::TransientWithParent;
+        } else if (parser->isSet(QStringLiteral("transientonly"))) {
+            lCaptureMode = Spectacle::CaptureMode::WindowUnderCursor;
+        }
+    } else {
+        // extract the capture mode
+        if (parser->isSet(QStringLiteral("current"))) {
+            lCaptureMode = Spectacle::CaptureMode::CurrentScreen;
+        } else if (parser->isSet(QStringLiteral("activewindow"))) {
+            lCaptureMode = Spectacle::CaptureMode::ActiveWindow;
+        } else if (parser->isSet(QStringLiteral("region"))) {
+            lCaptureMode = Spectacle::CaptureMode::RectangularRegion;
+        } else if (parser->isSet(QStringLiteral("windowundercursor"))) {
+            lCaptureMode = Spectacle::CaptureMode::TransientWithParent;
+        } else if (parser->isSet(QStringLiteral("transientonly"))) {
+            lCaptureMode = Spectacle::CaptureMode::WindowUnderCursor;
+        }
+    }
+
     auto lExportManager = ExportManager::instance();
     lExportManager->setCaptureMode(lCaptureMode);
 
@@ -233,6 +252,8 @@ void SpectacleCore::setUpShortcuts()
     KGlobalAccel::self()->setGlobalShortcut(ShortcutActions::self()->regionAction(), Qt::META | Qt::SHIFT | Qt::Key_Print);
 
     KGlobalAccel::self()->setGlobalShortcut(ShortcutActions::self()->currentScreenAction(), QList<QKeySequence>());
+
+    KGlobalAccel::self()->setGlobalShortcut(ShortcutActions::self()->openWithoutScreenshotAction(), QList<QKeySequence>());
 }
 
 QString SpectacleCore::filename() const
@@ -343,6 +364,11 @@ void SpectacleCore::screenshotUpdated(const QPixmap &thePixmap)
         }
     } break;
     case StartMode::Gui:
+        if (thePixmap.isNull()) {
+            mMainWindow->setScreenshotAndShow(thePixmap);
+            mMainWindow->setPlaceholderTextOnLaunch();
+            return;
+        }
         mMainWindow->setScreenshotAndShow(thePixmap);
 
         bool autoSaveImage = Settings::autoSaveImage();
@@ -475,6 +501,7 @@ void SpectacleCore::populateCommandLineParser(QCommandLineParser *lCmdLineParser
         {{QStringLiteral("u"), QStringLiteral("windowundercursor")}, i18n("Capture the window currently under the cursor, including parents of pop-up menus")},
         {{QStringLiteral("t"), QStringLiteral("transientonly")}, i18n("Capture the window currently under the cursor, excluding parents of pop-up menus")},
         {{QStringLiteral("r"), QStringLiteral("region")}, i18n("Capture a rectangular region of the screen")},
+        {{QStringLiteral("l"), QStringLiteral("launchonly")}, i18n("Launch Spectacle without taking a screenshot")},
         {{QStringLiteral("g"), QStringLiteral("gui")}, i18n("Start in GUI mode (default)")},
         {{QStringLiteral("b"), QStringLiteral("background")}, i18n("Take a screenshot and exit without showing the GUI")},
         {{QStringLiteral("s"), QStringLiteral("dbus")}, i18n("Start in DBus-Activation mode")},
@@ -535,7 +562,7 @@ Platform::GrabMode SpectacleCore::toPlatformGrabMode(Spectacle::CaptureMode theC
     return Platform::GrabMode::InvalidChoice;
 }
 
-void SpectacleCore::initGui(int theDelay, bool theIncludePointer, bool theIncludeDecorations)
+void SpectacleCore::ensureGuiInitiad()
 {
     if (!mIsGuiInited) {
         mMainWindow = std::make_unique<KSMainWindow>(mPlatform->supportedGrabModes(), mPlatform->supportedShutterModes());
@@ -545,6 +572,17 @@ void SpectacleCore::initGui(int theDelay, bool theIncludePointer, bool theInclud
 
         mIsGuiInited = true;
     }
+}
+
+void SpectacleCore::initGui(int theDelay, bool theIncludePointer, bool theIncludeDecorations)
+{
+    ensureGuiInitiad();
 
     takeNewScreenshot(ExportManager::instance()->captureMode(), theDelay, theIncludePointer, theIncludeDecorations);
 }
+
+void SpectacleCore::initGuiNoScreenshot()
+{
+    ensureGuiInitiad();
+    screenshotUpdated(QPixmap());
+}
diff --git a/src/SpectacleCore.h b/src/SpectacleCore.h
index 78ba2da..0f57672 100644
--- a/src/SpectacleCore.h
+++ b/src/SpectacleCore.h
@@ -45,6 +45,7 @@ public:
     void setFilename(const QString &filename);
 
     void populateCommandLineParser(QCommandLineParser *lCmdLineParser);
+    void initGuiNoScreenshot();
 
 Q_SIGNALS:
 
@@ -67,6 +68,7 @@ public Q_SLOTS:
     void onActivateRequested(QStringList arguments, const QString & /*workingDirectory */);
 
 private:
+    void ensureGuiInitiad();
     void initGui(int theDelay, bool theIncludePointer, bool theIncludeDecorations);
     Platform::GrabMode toPlatformGrabMode(Spectacle::CaptureMode theCaptureMode);
     void setUpShortcuts();
@@ -82,5 +84,6 @@ private:
     bool mCopyImageToClipboard;
     bool mCopyLocationToClipboard;
     bool mSaveToOutput;
+
     KWayland::Client::PlasmaShell *mWaylandPlasmashell = nullptr;
 };
diff --git a/src/SpectacleDBusAdapter.cpp b/src/SpectacleDBusAdapter.cpp
index 1a75ab9..e186fa1 100644
--- a/src/SpectacleDBusAdapter.cpp
+++ b/src/SpectacleDBusAdapter.cpp
@@ -41,3 +41,8 @@ void SpectacleDBusAdapter::RectangularRegion(bool includeMousePointer)
 {
     parent()->takeNewScreenshot(Spectacle::CaptureMode::RectangularRegion, 0, includeMousePointer, false);
 }
+
+void SpectacleDBusAdapter::OpenWithoutScreenshot()
+{
+    parent()->initGuiNoScreenshot();
+}
diff --git a/src/SpectacleDBusAdapter.h b/src/SpectacleDBusAdapter.h
index 3b85903..96e70a7 100644
--- a/src/SpectacleDBusAdapter.h
+++ b/src/SpectacleDBusAdapter.h
@@ -25,6 +25,7 @@ public Q_SLOTS:
     Q_NOREPLY void ActiveWindow(bool includeWindowDecorations, bool includeMousePointer);
     Q_NOREPLY void WindowUnderCursor(bool includeWindowDecorations, bool includeMousePointer);
     Q_NOREPLY void RectangularRegion(bool includeMousePointer);
+    Q_NOREPLY void OpenWithoutScreenshot();
 
 Q_SIGNALS:
 


More information about the kde-doc-english mailing list