kiran-flameshot/0002-feature-add-windows-capture-mode.patch
wangyucheng b2d60e96d0 feature(*): add windows capture mode
- 新增窗口捕获功能
2023-04-25 16:21:51 +08:00

291 lines
11 KiB
Diff
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

From 28943e130d80c183d40df77bc17c64f4593b6aca Mon Sep 17 00:00:00 2001
From: wangyucheng <wangyucheng@kylinsec.com.cn>
Date: Sun, 23 Apr 2023 14:29:42 +0800
Subject: [PATCH] feature: add windows capture mode
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 增加截图时代码捕获的功能
---
.gitignore | 2 +
flameshot.pro | 4 +
src/core/controller.cpp | 2 +-
src/widgets/capture/capturewidget.cpp | 98 +++++++++++++++++++++-
src/widgets/capture/capturewidget.h | 6 ++
src/widgets/capture/thicknesswidget.cpp | 1 +
src/widgets/capture/toowidget.cpp | 1 +
translations/Internationalization_zh_CN.ts | 6 +-
8 files changed, 114 insertions(+), 6 deletions(-)
diff --git a/.gitignore b/.gitignore
index e69de29..5acb669 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1,2 @@
+build
+.vscode
diff --git a/flameshot.pro b/flameshot.pro
index 0f368db..cec798d 100644
--- a/flameshot.pro
+++ b/flameshot.pro
@@ -5,6 +5,7 @@
#-------------------------------------------------
win32:LIBS += -luser32 -lshell32
+QMAKE_CXXFLAGS += -Wno-deprecated-declarations
TAG_VERSION = $$system(git --git-dir $$PWD/.git --work-tree $$PWD describe --always --tags)
isEmpty(TAG_VERSION){
@@ -16,12 +17,15 @@ DEFINES += WNCK_I_KNOW_THIS_IS_UNSTABLE
CONFIG += console
QT += core gui widgets network svg
+QT += x11extras
unix:!macx {
QT += dbus
}
CONFIG += c++11 link_pkgconfig
+
+PKGCONFIG += x11
PKGCONFIG += klog-qt5
PKGCONFIG += kiran-style-helper
diff --git a/src/core/controller.cpp b/src/core/controller.cpp
index ab46a4b..36abfbf 100644
--- a/src/core/controller.cpp
+++ b/src/core/controller.cpp
@@ -325,4 +325,4 @@ void Controller::doLater(int msec, QObject *receiver, lambda func) {
[timer, func](){ func(); timer->deleteLater(); });
timer->setInterval(msec);
timer->start();
-}
+}
\ No newline at end of file
diff --git a/src/widgets/capture/capturewidget.cpp b/src/widgets/capture/capturewidget.cpp
index 5985d21..5f05b25 100644
--- a/src/widgets/capture/capturewidget.cpp
+++ b/src/widgets/capture/capturewidget.cpp
@@ -240,7 +240,6 @@ void CaptureWidget::initOriginUI()
m_zoomIndicator = new ZoomIndicator(this);
m_zoomIndicator->hide();
-
m_isFirstReleaseButton = false;
}
@@ -406,7 +405,8 @@ void CaptureWidget::paintEvent(QPaintEvent *) {
QString helpTxt = tr("Press Enter to capture the screen."
"\nUse the Mouse Wheel to change the thickness of your tool."
"\nUse ctrl+c to save the picture to the clipboard."
- "\nUse ctrl+s to save the picture to the set location.");
+ "\nUse ctrl+s to save the picture to the set location."
+ "\nUse ctrl+d open capture window mode.");
// We draw the white contrasting background for the text, using the
//same text and options to get the boundingRect that the text will have.
@@ -566,7 +566,35 @@ void CaptureWidget::mouseMoveEvent(QMouseEvent *e) {
//QRect m_backgroundRect = m_selection->geometry();
QPoint topLeft = m_backgroundRect.topLeft() * devicePixelRatioF();
- if(curPos.x() + INDICATOR_WIDTH > m_context.desktop->screenGeometry().width() - 120)
+ //Active windows select mode
+ if (activeWindowSelectMode)
+ {
+ // new rect for active window
+ int minWith = INT_MAX;
+ int minHeight = INT_MAX;
+ int windowX = 0;
+ int windowY = 0;
+
+ for (auto win : m_wnds)
+ {
+ if (win.contains(curPos))
+ {
+ if (minWith > win.width() && minHeight > win.height())
+ {
+ minWith = win.width();
+ minHeight = win.height();
+ windowX = win.x();
+ windowY = win.y();
+ }
+ //new m_selection
+ }
+ m_selection->setVisible(true);
+ m_selection->setGeometry(QRect(windowX, windowY, minWith, minHeight).normalized());
+ update();
+ }
+ }
+
+ if (curPos.x() + INDICATOR_WIDTH > m_context.desktop->screenGeometry().width() - 120)
{
tmpPos.setX(curPos.x() - INDICATOR_WIDTH);
}
@@ -971,6 +999,8 @@ void CaptureWidget::initSelection() {
});
m_selection->setVisible(false);
m_selection->setGeometry(QRect());
+ // 初始化要捕获的窗口
+ getActiveWindow();
}
void CaptureWidget::setState(CaptureButton *b) {
@@ -1187,6 +1217,7 @@ void CaptureWidget::initShortcuts() {
new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_S), this, SLOT(saveScreenshot()));
new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_C), this, SLOT(copyScreenshot()));
new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Z), this, SLOT(undo()));
+ new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_D), this, SLOT(setActiveWindowSelectMode()));
new QShortcut(QKeySequence(Qt::CTRL + Qt::SHIFT + Qt::Key_Z), this, SLOT(redo()));
new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Right), this, SLOT(rightResize()));
new QShortcut(QKeySequence(Qt::SHIFT + Qt::Key_Left), this, SLOT(leftResize()));
@@ -1419,3 +1450,64 @@ void CaptureWidget::saveFullScreen()
{
saveScreenshot();
}
+
+void CaptureWidget::setActiveWindowSelectMode()
+{
+ activeWindowSelectMode = true;
+ m_showInitialMsg = false;
+ update();
+}
+
+void CaptureWidget::getActiveWindow()
+{
+ auto display = XOpenDisplay(nullptr);
+ // todo: 只获取了默认的屏幕,在多屏幕下无法获取到其他屏幕的窗口
+ auto root_window = DefaultRootWindow(display);
+
+ Window root_return, parent_return;
+ Window* child_list = nullptr;
+ unsigned int child_num = 0;
+ // 按z-order顺序获取根屏幕的所有子屏幕也就是所有的窗口
+ XQueryTree(display, root_window, &root_return, &parent_return, &child_list, &child_num);
+ // 绝大部分窗口可以排除也许可以给出一个常量比如2020个需要关注的可见窗口
+ m_wnds.reserve(child_num);
+ for (auto i = child_num; (int)i >= 0; i--)
+ {
+ XWindowAttributes attrs;
+ // 获取窗口相关数据
+ XGetWindowAttributes(display, child_list[i], &attrs);
+ int screenX = 0;
+ int screenY = 0;
+ Window childWin;
+ // 坐标系转换
+ XTranslateCoordinates(display, child_list[i], root_window, 0, 0, &screenX, &screenY, &childWin);
+ // 过滤掉不可见的窗口
+ if (attrs.map_state != IsViewable)
+ {
+ continue;
+ }
+ auto cur_wnd = QRect(screenX, screenY, attrs.width, attrs.height);
+ auto is_coverd = false;
+ // 只能判断是否被一个窗口遮挡,如果被两个窗口拼接遮挡则判断不了
+ if (m_wnds.isEmpty())
+ {
+ m_wnds.append(cur_wnd);
+ }
+ for (auto wnd : m_wnds)
+ {
+ if (wnd.contains(cur_wnd, true))
+ {
+ is_coverd = true;
+ break;
+ }
+ }
+ if (is_coverd)
+ {
+ is_coverd = false;
+ continue;
+ }
+ m_wnds.append(cur_wnd);
+ }
+ XFree(display);
+ XFree(child_list);
+}
\ No newline at end of file
diff --git a/src/widgets/capture/capturewidget.h b/src/widgets/capture/capturewidget.h
index 79246e4..d08aa4b 100644
--- a/src/widgets/capture/capturewidget.h
+++ b/src/widgets/capture/capturewidget.h
@@ -123,6 +123,7 @@ private slots:
void setDrawThickness(const int &t);
void setDrawRectStyle(const int &s);
void setDrawLineStyle(const int &l);
+ void setActiveWindowSelectMode();
protected:
void paintEvent(QPaintEvent *);
@@ -156,6 +157,10 @@ protected:
bool m_adjustmentButtonPressed;
bool m_inselection = true;
bool m_flag = false;
+ bool activeWindowSelectMode = false; //select active window
+
+ // save active window
+ QVector<QRect> m_wnds;
private:
void initSecondUI();
@@ -169,6 +174,7 @@ private:
void pushToolToStack();
void makeChild(QWidget *w);
void updateToolBar(QString toolName);
+ void getActiveWindow();
QRect extendedSelection() const;
QRect extendedRect(QRect *r) const;
diff --git a/src/widgets/capture/thicknesswidget.cpp b/src/widgets/capture/thicknesswidget.cpp
index 3f6360b..5046201 100644
--- a/src/widgets/capture/thicknesswidget.cpp
+++ b/src/widgets/capture/thicknesswidget.cpp
@@ -97,6 +97,7 @@ QVector<QRect> ThicknessWidget::handleMask() const {
spacing += i*4;
QRect *rect = new QRect(8 + i * 10 + spacing , 13 - i * 2 , (i+1)*4, (i+1)*4);
areas.append(*rect);
+ delete rect;
}
return areas;
}
diff --git a/src/widgets/capture/toowidget.cpp b/src/widgets/capture/toowidget.cpp
index 96d5fed..33428cf 100644
--- a/src/widgets/capture/toowidget.cpp
+++ b/src/widgets/capture/toowidget.cpp
@@ -127,6 +127,7 @@ QVector<QRect> Toowidget::handleMask() const {
for (int i = 0; i < m_colorList.size(); ++i) {
QRect *rect = new QRect(102 + i * 22, 9, 12, 12);
areas.append(*rect);
+ delete rect;
}
return areas;
}
diff --git a/translations/Internationalization_zh_CN.ts b/translations/Internationalization_zh_CN.ts
index f8bbbe5..3bfd5d5 100644
--- a/translations/Internationalization_zh_CN.ts
+++ b/translations/Internationalization_zh_CN.ts
@@ -156,7 +156,8 @@
<source>Press Enter to capture the screen.
Use the Mouse Wheel to change the thickness of your tool.
Use ctrl+c to save the picture to the clipboard.
-Use ctrl+s to save the picture to the set location.</source>
+Use ctrl+s to save the picture to the set location.
+Use ctrl+d open capture window mode.</source>
<translatorcomment>按 Enter 键捕捉屏幕。
使用鼠标滚轮来改变绘画工具的宽度。
使用ctrl+c将图片保存到剪贴板。
@@ -164,7 +165,8 @@ Use ctrl+s to save the picture to the set location.</source>
<translation>按 Enter 键捕捉屏幕。
使用鼠标滚轮来改变绘画工具的宽度。
使用ctrl+c将图片保存到剪贴板。
-使用ctrl+s将图片保存至设定位置。</translation>
+使用ctrl+s将图片保存至设定位置。
+使用ctrl+d打开窗口捕获模式。</translation>
</message>
<message>
<location filename="../src/widgets/capture/capturewidget.cpp" line="1009"/>
--
2.33.0