Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ set(QT_DEFAULT_MAJOR_VERSION 6 CACHE STRING "")
set(QT_VERSION_MAJOR 6 CACHE STRING "")
#BUILD_SHARED_LIBS used by QHotkey and QtColorWidgets
option(BUILD_SHARED_LIBS OFF)
#QHOTKEY_INSTALL used by QHotkey; must be disabled on Windows
if(WIN32)
set(QHOTKEY_INSTALL OFF CACHE BOOL "qHotkey install")
endif()

#Needed due to linker error with QtColorWidget
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
Expand Down Expand Up @@ -134,7 +138,7 @@ endif()
# ToDo: Check if this is used anywhere
option(BUILD_STATIC_LIBS ON)

if(APPLE)
if(WIN32 OR APPLE)
FetchContent_Declare(
qHotKey
GIT_REPOSITORY https://github.com/flameshot-org/QHotkey
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -237,9 +237,9 @@ These shortcuts are available in GUI mode:

### Global

Flameshot uses <kbd>Print screen</kbd> (Windows) and <kbd>cmd</kbd>-<kbd>shift</kbd>-<kbd>x</kbd> (macOS) as default global hotkeys.

On Linux, Flameshot doesn't yet support <kbd>Prt Sc</kbd> out of the box, but with a bit of configuration you can set this up:
- Windows: <kbd>Prt Sc</kbd> (fixed, cannot be changed) and <kbd>Win</kbd> + <kbd>Shift</kbd> + <kbd>X</kbd> (can be changed in the settings)
- macOS: <kbd>cmd</kbd> + <kbd>Shift</kbd> + <kbd>X</kbd> (can be changed in the settings)
- Linux: Flameshot doesn't yet support <kbd>Prt Sc</kbd> out of the box, but you can set this up with a bit of configuration:

#### On KDE Plasma desktop

Expand Down
5 changes: 5 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,13 @@
endif ()

if (NOT USE_OPENSSL)
message(WARNING "OpenSSL is required to upload screenshots")

Check warning on line 297 in src/CMakeLists.txt

View workflow job for this annotation

GitHub Actions / VS 2022 x64-portable

OpenSSL is required to upload screenshots

Check warning on line 297 in src/CMakeLists.txt

View workflow job for this annotation

GitHub Actions / VS 2022 x64-installer

OpenSSL is required to upload screenshots

Check warning on line 297 in src/CMakeLists.txt

View workflow job for this annotation

GitHub Actions / VS 2022 x64-portable

OpenSSL is required to upload screenshots

Check warning on line 297 in src/CMakeLists.txt

View workflow job for this annotation

GitHub Actions / VS 2022 x64-installer

OpenSSL is required to upload screenshots
endif ()

target_link_libraries(
flameshot
qhotkey
)
endif ()

# Choose default color palette (small or large)
Expand Down Expand Up @@ -469,7 +474,7 @@
FILES_MATCHING
PATTERN "*.dll")
else ()
message(WARNING "Unable to find OpenSSL dlls.")

Check warning on line 477 in src/CMakeLists.txt

View workflow job for this annotation

GitHub Actions / VS 2022 x64-portable

Unable to find OpenSSL dlls.

Check warning on line 477 in src/CMakeLists.txt

View workflow job for this annotation

GitHub Actions / VS 2022 x64-installer

Unable to find OpenSSL dlls.

Check warning on line 477 in src/CMakeLists.txt

View workflow job for this annotation

GitHub Actions / VS 2022 x64-portable

Unable to find OpenSSL dlls.

Check warning on line 477 in src/CMakeLists.txt

View workflow job for this annotation

GitHub Actions / VS 2022 x64-installer

Unable to find OpenSSL dlls.
endif ()
endif ()

Expand Down
35 changes: 30 additions & 5 deletions src/config/setshortcutwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <QLabel>
#include <QLayout>
#include <QPixmap>
#include <QTimer>

SetShortcutDialog::SetShortcutDialog(QDialog* parent,
const QString& shortcutName)
Expand All @@ -34,7 +35,7 @@ SetShortcutDialog::SetShortcutDialog(QDialog* parent,
m_layout->addWidget(infoIcon);

QString msg = "";
#if defined(Q_OS_MAC)
#if defined(Q_OS_MACOS)
msg = tr(
"Press Esc to cancel or ⌘+Backspace to disable the keyboard shortcut.");
#else
Expand All @@ -58,6 +59,15 @@ SetShortcutDialog::SetShortcutDialog(QDialog* parent,
infoBottom->setMargin(10);
infoBottom->setAlignment(Qt::AlignCenter);
m_layout->addWidget(infoBottom);

// 0ms Delay: Event loop waits until after show(); widget fully initialized
QTimer::singleShot(0, this, &SetShortcutDialog::startCapture);
}

void SetShortcutDialog::startCapture()
{
grabKeyboard(); // Call AFTER show()!
setFocus();
}

const QKeySequence& SetShortcutDialog::shortcut()
Expand All @@ -67,16 +77,19 @@ const QKeySequence& SetShortcutDialog::shortcut()

void SetShortcutDialog::keyPressEvent(QKeyEvent* ke)
{
if (ke->modifiers() & Qt::ShiftModifier) {
Qt::KeyboardModifiers mods = ke->modifiers();

if (mods & Qt::ShiftModifier) {
m_modifier += "Shift+";
}
if (ke->modifiers() & Qt::ControlModifier) {
if (mods & Qt::ControlModifier) {
m_modifier += "Ctrl+";
}
if (ke->modifiers() & Qt::AltModifier) {
if (mods & Qt::AltModifier) {
m_modifier += "Alt+";
}
if (ke->modifiers() & Qt::MetaModifier) {
// ke->key() == Qt::Key_Meta required on Windows to grab Win key
if (ke->modifiers() & Qt::MetaModifier || ke->key() == Qt::Key_Meta) {
m_modifier += "Meta+";
}

Expand All @@ -91,3 +104,15 @@ void SetShortcutDialog::keyReleaseEvent(QKeyEvent* event)
}
accept();
}

void SetShortcutDialog::accept()
{
releaseKeyboard();
QDialog::accept();
}

void SetShortcutDialog::reject()
{
releaseKeyboard();
QDialog::reject();
}
10 changes: 7 additions & 3 deletions src/config/setshortcutwidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,16 @@ class SetShortcutDialog : public QDialog
const QKeySequence& shortcut();

public:
void keyPressEvent(QKeyEvent*);
void keyReleaseEvent(QKeyEvent* event);
void keyPressEvent(QKeyEvent*) override;
void keyReleaseEvent(QKeyEvent* event) override;

signals:
private slots:
void accept() override;
void reject() override;

private:
void startCapture();

QVBoxLayout* m_layout;
QString m_modifier;
QKeySequence m_ks;
Expand Down
212 changes: 209 additions & 3 deletions src/config/shortcutswidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
#include "src/core/qguiappcurrentscreen.h"
#include "src/utils/globalvalues.h"
#include "toolfactory.h"
#include <QCheckBox>
#include <QCursor>
#include <QDir>
#include <QHeaderView>
#include <QIcon>
#include <QKeyEvent>
#include <QLabel>
#include <QMessageBox>
#include <QRect>
#include <QScreen>
#include <QStringList>
Expand All @@ -34,11 +37,20 @@ ShortcutsWidget::ShortcutsWidget(QWidget* parent)
m_layout = new QVBoxLayout(this);
m_layout->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);

#if defined(Q_OS_WIN)
checkPrintScreenForcesSnipping();
#endif

initInfoTable();
connect(ConfigHandler::getInstance(),
&ConfigHandler::fileChanged,
this,
&ShortcutsWidget::populateInfoTable);

#if defined(Q_OS_WIN)
initMsScreenclipCheckbox();
#endif

show();
}

Expand Down Expand Up @@ -202,13 +214,15 @@ void ShortcutsWidget::loadShortcuts()
appendShortcut("SCREENSHOT_HISTORY", tr("Screenshot history"));
#endif
#elif defined(Q_OS_WIN)

if (this->isPrintScreenKeyForSnippingDisabled()) {
m_shortcuts << (QStringList() << "" << QObject::tr("Capture screen")
<< "Print Screen");
}
appendShortcut("TAKE_SCREENSHOT", tr("Capture screen"));
#ifdef ENABLE_IMGUR
m_shortcuts << (QStringList() << "" << QObject::tr("Screenshot history")
<< "Shift+Print Screen");
#endif
m_shortcuts << (QStringList()
<< "" << QObject::tr("Capture screen") << "Print Screen");
#else
// TODO - Linux doesn't support global shortcuts for (XServer and Wayland),
// possibly it will be solved in the QHotKey library later. So it is
Expand Down Expand Up @@ -241,3 +255,195 @@ const QString& ShortcutsWidget::nativeOSHotKeyText(const QString& text)
return m_res;
}
#endif

#if defined(Q_OS_WIN)
void ShortcutsWidget::checkPrintScreenForcesSnipping()
{
if (!isPrintScreenKeyForSnippingDisabled() &&
!ConfigHandler().ignorePrntScrForcesSnipping()) {
QMessageBox msgBox;
msgBox.setWindowTitle("Flameshot");
msgBox.setIcon(QMessageBox::Question);
msgBox.setText(tr("It seems, that Windows forces to open its screenshot"
" tool when the 'Print Screen' key is pressed. Would "
"you like to disable this so that Flameshot can use "
"the 'Print Screen' key?") +
"\n\n" +
tr("Flameshot must be restarted for changes to take "
"effect."));
QPushButton* yesBtn = msgBox.addButton(QMessageBox::Yes);
QPushButton* noBtn = msgBox.addButton(QMessageBox::No);
QPushButton* noDontAskAgainBtn =
new QPushButton(tr("No, don't ask again"));
msgBox.addButton(noDontAskAgainBtn, QMessageBox::RejectRole);
msgBox.setDefaultButton(yesBtn);
msgBox.exec();

if (msgBox.clickedButton() == yesBtn) {
if (!disablePrintScreenKeyForSnipping()) {
QMessageBox::warning(
this, "Flameshot", tr("The registry could not be changed!"));
}
} else if (msgBox.clickedButton() == noDontAskAgainBtn) {
ConfigHandler().setIgnorePrntScrForcesSnipping(true);
}
}
}

bool ShortcutsWidget::isPrintScreenKeyForSnippingDisabled()
{
QSettings PrintKeyForSnipping("HKEY_CURRENT_USER\\Control Panel\\Keyboard",
QSettings::NativeFormat);
return PrintKeyForSnipping.value("PrintScreenKeyForSnippingEnabled", 1)
.toInt() == 0;
}

bool ShortcutsWidget::disablePrintScreenKeyForSnipping()
{
QSettings PrintKeyForSnipping("HKEY_CURRENT_USER\\Control Panel\\Keyboard",
QSettings::NativeFormat);
PrintKeyForSnipping.setValue("PrintScreenKeyForSnippingEnabled", 0);
PrintKeyForSnipping.sync();
if (QSettings::AccessError == PrintKeyForSnipping.status()) {
return false;
}
return this->isPrintScreenKeyForSnippingDisabled();
}

void ShortcutsWidget::initMsScreenclipCheckbox()
{
m_registerMsScreenclip =
new QCheckBox(tr("Register Flameshot as MS-SCREENCLIP application "
"(administrator privileges required)"),
this);
m_registerMsScreenclip->setToolTip(
tr("After registering, you can select Flameshot as the default "
"screenshot application in Windows Settings."));
m_registerMsScreenclip->setChecked(isMsScreenclipRegistered());
m_layout->addWidget(m_registerMsScreenclip);

connect(
m_registerMsScreenclip, &QCheckBox::clicked, this, [this](bool checked) {
if (checked) {
if (!registerMsScreenclip()) {
QMessageBox::warning(
this,
"Flameshot",
tr("The registry could not be changed!") + "\n" +
tr("You may start Flameshot as administrator ONCE and "
"try again!"));
m_registerMsScreenclip->setChecked(false);
}
} else {
if (!unregisterMsScreenclip()) {
QMessageBox::warning(
this,
"Flameshot",
tr("The registry could not be changed!") + "\n" +
tr("You may start Flameshot as administrator ONCE and "
"try again!"));
m_registerMsScreenclip->setChecked(true);
}
}
});
}

bool ShortcutsWidget::isMsScreenclipRegistered()
{
QSettings URLAssociations(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Flameshot\\Capabilities\\URLAssociations",
QSettings::NativeFormat);
QString value = URLAssociations.value("ms-screenclip", "").toString();
if (value.toLower() != "flameshot")
return false;

QSettings RegisteredApplications(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\RegisteredApplications",
QSettings::NativeFormat);
value = RegisteredApplications.value("Flameshot", "").toString();
if (value.toLower() !=
QString("SOFTWARE\\Flameshot\\Capabilities").toLower())
return false;

QSettings FlameshotShellCmd(
"HKEY_CURRENT_USER\\Software\\Classes\\Flameshot\\Shell\\Open\\command",
QSettings::NativeFormat);
value = FlameshotShellCmd.value(".").toString();
if (value.toLower() != QString("\"" +
QDir::toNativeSeparators(
QCoreApplication::applicationFilePath()) +
"\" gui")
.toLower())
return false;

return true; // All registry entries found
}

bool ShortcutsWidget::registerMsScreenclip()
{
QSettings URLAssociations(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Flameshot\\Capabilities\\URLAssociations",
QSettings::NativeFormat);
URLAssociations.setValue("ms-screenclip", "Flameshot");
URLAssociations.sync();
if (QSettings::AccessError == URLAssociations.status()) {
return false;
}

QSettings RegisteredApplications(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\RegisteredApplications",
QSettings::NativeFormat);
RegisteredApplications.setValue("Flameshot",
"SOFTWARE\\Flameshot\\Capabilities");
RegisteredApplications.sync();
if (QSettings::AccessError == RegisteredApplications.status()) {
return false;
}

QSettings FlameshotShellCmd(
"HKEY_CURRENT_USER\\Software\\Classes\\Flameshot\\Shell\\Open\\command",
QSettings::NativeFormat);
FlameshotShellCmd.setValue(
".",
"\"" + QDir::toNativeSeparators(QCoreApplication::applicationFilePath()) +
"\" gui");
FlameshotShellCmd.sync();
if (QSettings::AccessError == FlameshotShellCmd.status()) {
return false;
}

return isMsScreenclipRegistered();
}

bool ShortcutsWidget::unregisterMsScreenclip()
{
QSettings FlameshotShellCmd("HKEY_CURRENT_USER\\Software\\Classes",
QSettings::NativeFormat);
FlameshotShellCmd.remove("Flameshot");
FlameshotShellCmd.sync();
if (QSettings::AccessError == FlameshotShellCmd.status()) {
return false;
}

QSettings RegisteredApplications(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\RegisteredApplications",
QSettings::NativeFormat);
RegisteredApplications.remove("Flameshot");
RegisteredApplications.sync();
if (QSettings::AccessError == RegisteredApplications.status()) {
return false;
}

QSettings URLAssociations(
"HKEY_LOCAL_MACHINE\\SOFTWARE\\Flameshot\\Capabilities\\URLAssociations",
QSettings::NativeFormat);
URLAssociations.remove("ms-screenclip");
URLAssociations.sync();
if (QSettings::AccessError == URLAssociations.status()) {
return false;
}

return !isMsScreenclipRegistered();
}

#endif
Loading
Loading