From ad76dd0e3359ad27a2d0124c790e17a04a237c9d Mon Sep 17 00:00:00 2001 From: XMuli Date: Sun, 8 May 2022 23:14:51 +0800 Subject: [PATCH] feat: linux window auto-detect get rectangle --- ExIntelDete/CMakeLists.txt | 63 +++++++++++++++++++++++ ExIntelDete/main.cpp | 101 +++++++++++++++++++++++++++++++++++++ ExIntelDete/widget.cpp | 11 ++++ ExIntelDete/widget.h | 14 +++++ TestHotKey/main.cpp | 2 +- TestHotKey/tray.cpp | 2 +- TestHotKey/widget.h | 2 +- 7 files changed, 192 insertions(+), 3 deletions(-) create mode 100644 ExIntelDete/CMakeLists.txt create mode 100644 ExIntelDete/main.cpp create mode 100644 ExIntelDete/widget.cpp create mode 100644 ExIntelDete/widget.h diff --git a/ExIntelDete/CMakeLists.txt b/ExIntelDete/CMakeLists.txt new file mode 100644 index 0000000..e4b2bac --- /dev/null +++ b/ExIntelDete/CMakeLists.txt @@ -0,0 +1,63 @@ +cmake_minimum_required(VERSION 3.5) + +project(ExIntelDete VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# QtCreator supports the following variables for Android, which are identical to qmake Android variables. +# Check https://doc.qt.io/qt/deployment-android.html for more information. +# They need to be set before the find_package( ...) calls below. + +#if(ANDROID) +# set(ANDROID_PACKAGE_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/android") +# if (ANDROID_ABI STREQUAL "armeabi-v7a") +# set(ANDROID_EXTRA_LIBS +# ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libcrypto.so +# ${CMAKE_CURRENT_SOURCE_DIR}/path/to/libssl.so) +# endif() +#endif() + +find_package(QT NAMES Qt6 Qt5 COMPONENTS Widgets REQUIRED) +find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Widgets REQUIRED) + +set(PROJECT_SOURCES + main.cpp + widget.cpp + widget.h +) + +if(${QT_VERSION_MAJOR} GREATER_EQUAL 6) + qt_add_executable(ExIntelDete + MANUAL_FINALIZATION + ${PROJECT_SOURCES} + ) +else() + if(ANDROID) + add_library(ExIntelDete SHARED + ${PROJECT_SOURCES} + ) + else() + add_executable(ExIntelDete + ${PROJECT_SOURCES} + ) + endif() +endif() + +target_link_libraries(ExIntelDete PRIVATE Qt${QT_VERSION_MAJOR}::Widgets X11) # add X11 + +set_target_properties(ExIntelDete PROPERTIES + MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com + MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION} + MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} +) + +if(QT_VERSION_MAJOR EQUAL 6) + qt_finalize_executable(ExIntelDete) +endif() diff --git a/ExIntelDete/main.cpp b/ExIntelDete/main.cpp new file mode 100644 index 0000000..9c85498 --- /dev/null +++ b/ExIntelDete/main.cpp @@ -0,0 +1,101 @@ +#include "widget.h" + +#include +#include +#include + + +#include +#include + +// X11 一种可能性是添加 QTextStream 包含该错误出现的位置。 + +// 至于 X11 相关的错误,请尝试将 X11 包含在 Qt 包含之后。 +#include +#include +#include +#include + +// https://www.jianshu.com/p/c906fbe1ad00 +// https://stackoverflow.com/questions/1201179/how-to-identify-top-level-x11-windows-using-xlib +// https://www.cnblogs.com/alalazy/p/12323089.html +class WindowsMatchingPid +{ +public: + WindowsMatchingPid(Display *display, Window wRoot, unsigned long pid) + : _display(display) + , _pid(pid) + { + _atomPID = XInternAtom(display, "_NET_WM_PID", True); + if(_atomPID == None) + { + return; + } + + search(wRoot); + } + + const QList result() const { return _result; } + +private: + unsigned long _pid; + Atom _atomPID; + Display *_display; + QList _result; + + void search(Window w) + { + Atom type; + int format; + unsigned long nItems; + unsigned long bytesAfter; + unsigned char *propPID = 0; + if(Success == XGetWindowProperty(_display, w, _atomPID, 0, 1, False, XA_CARDINAL, + &type, &format, &nItems, &bytesAfter, &propPID)) + { + if(propPID != 0) + { + if(_pid == *((unsigned long *)propPID)) + _result.append(w); + XFree(propPID); + } + } + + Window wRoot; + Window wParent; + Window *wChild; + unsigned nChildren; + if(0 != XQueryTree(_display, w, &wRoot, &wParent, &wChild, &nChildren)) + { + for(unsigned i = 0; i < nChildren; i++) + search(wChild[i]); + } + } +}; + + +int main(int argc, char *argv[]) +{ + QApplication a(argc, argv); +// Widget w; +// w.show(); + + QList m_pformList; + + int pid = getpid(); + Display *display = XOpenDisplay(0); + WindowsMatchingPid match(display, XDefaultRootWindow(display), pid); + const QList result = match.result(); + for(int i=0; iisWindow()&&win->isVisible()){ + m_pformList.append((QObject*)win); + } + } + + XCloseDisplay(display); + + return a.exec(); +} diff --git a/ExIntelDete/widget.cpp b/ExIntelDete/widget.cpp new file mode 100644 index 0000000..7350ff4 --- /dev/null +++ b/ExIntelDete/widget.cpp @@ -0,0 +1,11 @@ +#include "widget.h" + +Widget::Widget(QWidget *parent) + : QWidget(parent) +{ +} + +Widget::~Widget() +{ +} + diff --git a/ExIntelDete/widget.h b/ExIntelDete/widget.h new file mode 100644 index 0000000..47b6270 --- /dev/null +++ b/ExIntelDete/widget.h @@ -0,0 +1,14 @@ +#ifndef WIDGET_H +#define WIDGET_H + +#include + +class Widget : public QWidget +{ + Q_OBJECT + +public: + Widget(QWidget *parent = nullptr); + ~Widget(); +}; +#endif // WIDGET_H diff --git a/TestHotKey/main.cpp b/TestHotKey/main.cpp index 6285fe3..e20a0ff 100644 --- a/TestHotKey/main.cpp +++ b/TestHotKey/main.cpp @@ -4,7 +4,7 @@ * Author: XMuli xmulitech@gmail.com * * GitHub: https://github.com/XMuli - * Blogs: https://ifmet.cn + * Blog: https://ifmet.cn * CSDN: https://blog.csdn.net/qq_33154343 */ #include "widget.h" diff --git a/TestHotKey/tray.cpp b/TestHotKey/tray.cpp index 29bbb49..ca848bc 100644 --- a/TestHotKey/tray.cpp +++ b/TestHotKey/tray.cpp @@ -4,7 +4,7 @@ * Author: XMuli xmulitech@gmail.com * * GitHub: https://github.com/XMuli - * Blogs: https://ifmet.cn + * Blog: https://ifmet.cn * CSDN: https://blog.csdn.net/qq_33154343 */ #include "tray.h" diff --git a/TestHotKey/widget.h b/TestHotKey/widget.h index 1397be8..eab67e8 100644 --- a/TestHotKey/widget.h +++ b/TestHotKey/widget.h @@ -4,7 +4,7 @@ * Author: XMuli xmulitech@gmail.com * * GitHub: https://github.com/XMuli - * Blogs: https://ifmet.cn + * Blog: https://ifmet.cn * CSDN: https://blog.csdn.net/qq_33154343 */ #ifndef WIDGET_H