mirror of
https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git
synced 2024-12-25 15:41:34 +08:00
Some code cleanup, adjustments to match ADS coding style
This commit is contained in:
parent
533d174abc
commit
04aecb3693
@ -83,7 +83,8 @@ static void updateDockAreaFocusStyle(CDockAreaWidget* DockArea, bool Focused)
|
|||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
static void updateFloatingWidgetFocusStyle(CFloatingDockContainer* FloatingWidget, bool Focused)
|
static void updateFloatingWidgetFocusStyle(CFloatingDockContainer* FloatingWidget, bool Focused)
|
||||||
{
|
{
|
||||||
if(FloatingWidget->hasNativeTitleBar()){
|
if (FloatingWidget->hasNativeTitleBar())
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
auto TitleBar = qobject_cast<CFloatingWidgetTitleBar*>(FloatingWidget->titleBarWidget());
|
auto TitleBar = qobject_cast<CFloatingWidgetTitleBar*>(FloatingWidget->titleBarWidget());
|
||||||
|
@ -493,45 +493,62 @@ CDockManager::~CDockManager()
|
|||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
bool CDockManager::eventFilter(QObject *obj, QEvent *e){
|
bool CDockManager::eventFilter(QObject *obj, QEvent *e)
|
||||||
|
{
|
||||||
// Emulate Qt:Tool behaviour.
|
// Emulate Qt:Tool behaviour.
|
||||||
// Required because on some WMs Tool windows can't be maximized.
|
// Required because on some WMs Tool windows can't be maximized.
|
||||||
|
|
||||||
// Window always on top of the MainWindow.
|
// Window always on top of the MainWindow.
|
||||||
if(e->type() == QEvent::WindowActivate){
|
if (e->type() == QEvent::WindowActivate)
|
||||||
for(auto _window : floatingWidgets()){
|
{
|
||||||
if(!_window->isVisible() || window()->isMinimized()){
|
for (auto _window : floatingWidgets())
|
||||||
|
{
|
||||||
|
if (!_window->isVisible() || window()->isMinimized())
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// setWindowFlags(Qt::WindowStaysOnTopHint) will hide the window and thus requires a show call.
|
// setWindowFlags(Qt::WindowStaysOnTopHint) will hide the window and thus requires a show call.
|
||||||
// This then leads to flickering and a nasty endless loop (also buggy behaviour on Ubuntu).
|
// This then leads to flickering and a nasty endless loop (also buggy behaviour on Ubuntu).
|
||||||
// So we just do it ourself.
|
// So we just do it ourself.
|
||||||
internal::xcb_update_prop(true, _window->window()->winId(), "_NET_WM_STATE", "_NET_WM_STATE_ABOVE", "_NET_WM_STATE_STAYS_ON_TOP");
|
internal::xcb_update_prop(true, _window->window()->winId(),
|
||||||
|
"_NET_WM_STATE", "_NET_WM_STATE_ABOVE", "_NET_WM_STATE_STAYS_ON_TOP");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(e->type() == QEvent::WindowDeactivate){
|
else if (e->type() == QEvent::WindowDeactivate)
|
||||||
for(auto _window : floatingWidgets()){
|
{
|
||||||
if(!_window->isVisible() || window()->isMinimized()){
|
for (auto _window : floatingWidgets())
|
||||||
|
{
|
||||||
|
if (!_window->isVisible() || window()->isMinimized())
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
internal::xcb_update_prop(false, _window->window()->winId(), "_NET_WM_STATE", "_NET_WM_STATE_ABOVE", "_NET_WM_STATE_STAYS_ON_TOP");
|
internal::xcb_update_prop(false, _window->window()->winId(),
|
||||||
|
"_NET_WM_STATE", "_NET_WM_STATE_ABOVE", "_NET_WM_STATE_STAYS_ON_TOP");
|
||||||
_window->raise();
|
_window->raise();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync minimize with MainWindow
|
// Sync minimize with MainWindow
|
||||||
if(e->type() == QEvent::WindowStateChange){
|
if (e->type() == QEvent::WindowStateChange)
|
||||||
for(auto _window : floatingWidgets()){
|
{
|
||||||
if(! _window->isVisible()){
|
for (auto _window : floatingWidgets())
|
||||||
|
{
|
||||||
|
if (! _window->isVisible())
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if(window()->isMinimized()){
|
|
||||||
|
if (window()->isMinimized())
|
||||||
|
{
|
||||||
_window->showMinimized();
|
_window->showMinimized();
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_window->setWindowState(_window->windowState() & (~Qt::WindowMinimized));
|
_window->setWindowState(_window->windowState() & (~Qt::WindowMinimized));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!window()->isMinimized()){
|
if (!window()->isMinimized())
|
||||||
|
{
|
||||||
QApplication::setActiveWindow(window());
|
QApplication::setActiveWindow(window());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -411,7 +411,8 @@ struct FloatingDockContainerPrivate
|
|||||||
void setWindowTitle(const QString &Text)
|
void setWindowTitle(const QString &Text)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
if(TitleBar){
|
if (TitleBar)
|
||||||
|
{
|
||||||
TitleBar->setTitle(Text);
|
TitleBar->setTitle(Text);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -610,24 +611,40 @@ CFloatingDockContainer::CFloatingDockContainer(CDockManager *DockManager) :
|
|||||||
QDockWidget::setFloating(true);
|
QDockWidget::setFloating(true);
|
||||||
QDockWidget::setFeatures(QDockWidget::AllDockWidgetFeatures);
|
QDockWidget::setFeatures(QDockWidget::AllDockWidgetFeatures);
|
||||||
|
|
||||||
// KDE doesn't seem to fire MoveEvents while moving windows, so for now no native titlebar for everything using KWin.
|
bool native_window = true;
|
||||||
QString window_manager = internal::windowManager().toUpper().split(" ")[0];
|
|
||||||
bool native_window = window_manager != "KWIN";
|
|
||||||
// FloatingContainerForce*TitleBar is overwritten by the "ADS_UseNativeTitle" environment variable if set.
|
// FloatingContainerForce*TitleBar is overwritten by the "ADS_UseNativeTitle" environment variable if set.
|
||||||
auto env = qgetenv("ADS_UseNativeTitle").toUpper();
|
auto env = qgetenv("ADS_UseNativeTitle").toUpper();
|
||||||
if (env == "1"){
|
if (env == "1")
|
||||||
|
{
|
||||||
native_window = true;
|
native_window = true;
|
||||||
} else if (env == "0"){
|
}
|
||||||
native_window = false;
|
else if (env == "0")
|
||||||
} else if ( DockManager->testConfigFlag( CDockManager::FloatingContainerForceNativeTitleBar )){
|
{
|
||||||
native_window = true;
|
|
||||||
} else if ( DockManager->testConfigFlag( CDockManager::FloatingContainerForceCustomTitleBar )){
|
|
||||||
native_window = false;
|
native_window = false;
|
||||||
}
|
}
|
||||||
if(native_window){
|
else if (DockManager->testConfigFlag(CDockManager::FloatingContainerForceNativeTitleBar))
|
||||||
|
{
|
||||||
|
native_window = true;
|
||||||
|
}
|
||||||
|
else if (DockManager->testConfigFlag(CDockManager::FloatingContainerForceCustomTitleBar))
|
||||||
|
{
|
||||||
|
native_window = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// KDE doesn't seem to fire MoveEvents while moving windows, so for now no native titlebar for everything using KWin.
|
||||||
|
QString window_manager = internal::windowManager().toUpper().split(" ")[0];
|
||||||
|
bool native_window = window_manager != "KWIN";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (native_window)
|
||||||
|
{
|
||||||
setTitleBarWidget(new QWidget());
|
setTitleBarWidget(new QWidget());
|
||||||
setWindowFlags(Qt::Window | Qt::WindowMaximizeButtonHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);
|
setWindowFlags(Qt::Window | Qt::WindowMaximizeButtonHint | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
d->TitleBar = new CFloatingWidgetTitleBar(this);
|
d->TitleBar = new CFloatingWidgetTitleBar(this);
|
||||||
setTitleBarWidget(d->TitleBar);
|
setTitleBarWidget(d->TitleBar);
|
||||||
setWindowFlags(Qt::Window | Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint);
|
setWindowFlags(Qt::Window | Qt::WindowMinMaxButtonsHint | Qt::FramelessWindowHint);
|
||||||
@ -705,7 +722,8 @@ void CFloatingDockContainer::changeEvent(QEvent *event)
|
|||||||
d->zOrderIndex = ++zOrderCounter;
|
d->zOrderIndex = ++zOrderCounter;
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
if(d->DraggingState == DraggingFloatingWidget){
|
if (d->DraggingState == DraggingFloatingWidget)
|
||||||
|
{
|
||||||
d->titleMouseReleaseEvent();
|
d->titleMouseReleaseEvent();
|
||||||
d->DraggingState = DraggingInactive;
|
d->DraggingState = DraggingInactive;
|
||||||
}
|
}
|
||||||
@ -848,20 +866,13 @@ void CFloatingDockContainer::showEvent(QShowEvent *event)
|
|||||||
void CFloatingDockContainer::startFloating(const QPoint &DragStartMousePos,
|
void CFloatingDockContainer::startFloating(const QPoint &DragStartMousePos,
|
||||||
const QSize &Size, eDragState DragState, QWidget *MouseEventHandler)
|
const QSize &Size, eDragState DragState, QWidget *MouseEventHandler)
|
||||||
{
|
{
|
||||||
#ifndef Q_OS_LINUX
|
|
||||||
Q_UNUSED(MouseEventHandler)
|
|
||||||
#endif
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
if (!isMaximized()) {
|
if (!isMaximized())
|
||||||
|
{
|
||||||
resize(Size);
|
resize(Size);
|
||||||
d->DragStartMousePosition = DragStartMousePos;
|
d->DragStartMousePosition = DragStartMousePos;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
resize(Size);
|
|
||||||
d->DragStartMousePosition = DragStartMousePos;
|
|
||||||
#endif
|
|
||||||
d->setState(DragState);
|
d->setState(DragState);
|
||||||
#ifdef Q_OS_LINUX
|
|
||||||
if (DraggingFloatingWidget == DragState)
|
if (DraggingFloatingWidget == DragState)
|
||||||
{
|
{
|
||||||
d->MouseEventHandler = MouseEventHandler;
|
d->MouseEventHandler = MouseEventHandler;
|
||||||
@ -870,15 +881,20 @@ void CFloatingDockContainer::startFloating(const QPoint &DragStartMousePos,
|
|||||||
d->MouseEventHandler->grabMouse();
|
d->MouseEventHandler->grabMouse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#ifdef Q_OS_LINUX
|
if (!isMaximized())
|
||||||
if (!isMaximized()) {
|
{
|
||||||
moveFloating();
|
moveFloating();
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
moveFloating();
|
|
||||||
#endif
|
|
||||||
show();
|
show();
|
||||||
|
#else
|
||||||
|
Q_UNUSED(MouseEventHandler)
|
||||||
|
resize(Size);
|
||||||
|
d->DragStartMousePosition = DragStartMousePos;
|
||||||
|
d->setState(DragState);
|
||||||
|
moveFloating();
|
||||||
|
show();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
@ -988,7 +1004,8 @@ bool CFloatingDockContainer::restoreState(CDockingStateReader &Stream,
|
|||||||
}
|
}
|
||||||
onDockAreasAddedOrRemoved();
|
onDockAreasAddedOrRemoved();
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
if(d->TitleBar){
|
if(d->TitleBar)
|
||||||
|
{
|
||||||
d->TitleBar->setMaximizedIcon(windowState() == Qt::WindowMaximized);
|
d->TitleBar->setMaximizedIcon(windowState() == Qt::WindowMaximized);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1134,15 +1151,21 @@ void CFloatingDockContainer::moveEvent(QMoveEvent *event)
|
|||||||
|
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
|
//============================================================================
|
||||||
void CFloatingDockContainer::onMaximizeRequest()
|
void CFloatingDockContainer::onMaximizeRequest()
|
||||||
{
|
{
|
||||||
if(windowState() == Qt::WindowMaximized){
|
if (windowState() == Qt::WindowMaximized)
|
||||||
|
{
|
||||||
showNormal();
|
showNormal();
|
||||||
}else{
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
showMaximized();
|
showMaximized();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
void CFloatingDockContainer::showNormal(bool fixGeometry)
|
void CFloatingDockContainer::showNormal(bool fixGeometry)
|
||||||
{
|
{
|
||||||
if (windowState() == Qt::WindowMaximized)
|
if (windowState() == Qt::WindowMaximized)
|
||||||
@ -1154,45 +1177,65 @@ void CFloatingDockContainer::showNormal(bool fixGeometry)
|
|||||||
setGeometry(oldNormal);
|
setGeometry(oldNormal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(d->TitleBar){
|
if(d->TitleBar)
|
||||||
|
{
|
||||||
d->TitleBar->setMaximizedIcon(false);
|
d->TitleBar->setMaximizedIcon(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
void CFloatingDockContainer::showMaximized()
|
void CFloatingDockContainer::showMaximized()
|
||||||
{
|
{
|
||||||
Super::showMaximized();
|
Super::showMaximized();
|
||||||
if(d->TitleBar){
|
if (d->TitleBar)
|
||||||
|
{
|
||||||
d->TitleBar->setMaximizedIcon(true);
|
d->TitleBar->setMaximizedIcon(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
bool CFloatingDockContainer::isMaximized() const
|
bool CFloatingDockContainer::isMaximized() const
|
||||||
{
|
{
|
||||||
return windowState() == Qt::WindowMaximized;
|
return windowState() == Qt::WindowMaximized;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFloatingDockContainer::show(){
|
|
||||||
|
//============================================================================
|
||||||
|
void CFloatingDockContainer::show()
|
||||||
|
{
|
||||||
// Prevent this window from showing in the taskbar and pager (alt+tab)
|
// Prevent this window from showing in the taskbar and pager (alt+tab)
|
||||||
internal::xcb_add_prop(true, winId(), "_NET_WM_STATE", "_NET_WM_STATE_SKIP_TASKBAR");
|
internal::xcb_add_prop(true, winId(), "_NET_WM_STATE", "_NET_WM_STATE_SKIP_TASKBAR");
|
||||||
internal::xcb_add_prop(true, winId(), "_NET_WM_STATE", "_NET_WM_STATE_SKIP_PAGER");
|
internal::xcb_add_prop(true, winId(), "_NET_WM_STATE", "_NET_WM_STATE_SKIP_PAGER");
|
||||||
Super::show();
|
Super::show();
|
||||||
}
|
}
|
||||||
void CFloatingDockContainer::resizeEvent(QResizeEvent *event){
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
|
void CFloatingDockContainer::resizeEvent(QResizeEvent *event)
|
||||||
|
{
|
||||||
d->IsResizing = true;
|
d->IsResizing = true;
|
||||||
Super::resizeEvent(event);
|
Super::resizeEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFloatingDockContainer::moveEvent(QMoveEvent *event){
|
|
||||||
|
//============================================================================
|
||||||
|
void CFloatingDockContainer::moveEvent(QMoveEvent *event)
|
||||||
|
{
|
||||||
Super::moveEvent(event);
|
Super::moveEvent(event);
|
||||||
if(!d->IsResizing && event->spontaneous()){
|
if (!d->IsResizing && event->spontaneous())
|
||||||
|
{
|
||||||
d->DraggingState = DraggingFloatingWidget;
|
d->DraggingState = DraggingFloatingWidget;
|
||||||
d->updateDropOverlays(QCursor::pos());
|
d->updateDropOverlays(QCursor::pos());
|
||||||
}
|
}
|
||||||
d->IsResizing = false;
|
d->IsResizing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CFloatingDockContainer::hasNativeTitleBar(){
|
|
||||||
|
//============================================================================
|
||||||
|
bool CFloatingDockContainer::hasNativeTitleBar()
|
||||||
|
{
|
||||||
return d->TitleBar == nullptr;
|
return d->TitleBar == nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -284,6 +284,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
void show();
|
void show();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the floating widget has a native titlebar or false if
|
||||||
|
* the floating widget has a QWidget based title bar
|
||||||
|
*/
|
||||||
bool hasNativeTitleBar();
|
bool hasNativeTitleBar();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -53,33 +53,44 @@ namespace ads
|
|||||||
namespace internal
|
namespace internal
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
static QString _window_manager;
|
static QString _window_manager;
|
||||||
static QHash<QString, xcb_atom_t> _xcb_atom_cache;
|
static QHash<QString, xcb_atom_t> _xcb_atom_cache;
|
||||||
|
|
||||||
xcb_atom_t xcb_get_atom(const char *name){
|
|
||||||
if (!QX11Info::isPlatformX11()){
|
//============================================================================
|
||||||
|
xcb_atom_t xcb_get_atom(const char *name)
|
||||||
|
{
|
||||||
|
if (!QX11Info::isPlatformX11())
|
||||||
|
{
|
||||||
return XCB_ATOM_NONE;
|
return XCB_ATOM_NONE;
|
||||||
}
|
}
|
||||||
auto key = QString(name);
|
auto key = QString(name);
|
||||||
if(_xcb_atom_cache.contains(key)){
|
if(_xcb_atom_cache.contains(key))
|
||||||
|
{
|
||||||
return _xcb_atom_cache[key];
|
return _xcb_atom_cache[key];
|
||||||
}
|
}
|
||||||
xcb_connection_t *connection = QX11Info::connection();
|
xcb_connection_t *connection = QX11Info::connection();
|
||||||
xcb_intern_atom_cookie_t request = xcb_intern_atom(connection, 1, strlen(name), name);
|
xcb_intern_atom_cookie_t request = xcb_intern_atom(connection, 1, strlen(name), name);
|
||||||
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, request, NULL);
|
xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(connection, request, NULL);
|
||||||
if(!reply){
|
if (!reply)
|
||||||
|
{
|
||||||
return XCB_ATOM_NONE;
|
return XCB_ATOM_NONE;
|
||||||
}
|
}
|
||||||
xcb_atom_t atom = reply->atom;
|
xcb_atom_t atom = reply->atom;
|
||||||
if(atom == XCB_ATOM_NONE){
|
if(atom == XCB_ATOM_NONE)
|
||||||
|
{
|
||||||
ADS_PRINT("Unknown Atom response from XServer: " << name);
|
ADS_PRINT("Unknown Atom response from XServer: " << name);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_xcb_atom_cache.insert(key, atom);
|
_xcb_atom_cache.insert(key, atom);
|
||||||
}
|
}
|
||||||
free(reply);
|
free(reply);
|
||||||
return atom;
|
return atom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
void xcb_update_prop(bool set, WId window, const char *type, const char *prop, const char *prop2)
|
void xcb_update_prop(bool set, WId window, const char *type, const char *prop, const char *prop2)
|
||||||
{
|
{
|
||||||
auto connection = QX11Info::connection();
|
auto connection = QX11Info::connection();
|
||||||
@ -103,18 +114,24 @@ void xcb_update_prop(bool set, WId window, const char *type, const char *prop, c
|
|||||||
xcb_flush(connection);
|
xcb_flush(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
xcb_get_property_reply_t* _xcb_get_props(WId window, const char *type, unsigned int atom_type){
|
|
||||||
if (!QX11Info::isPlatformX11()){
|
//============================================================================
|
||||||
|
xcb_get_property_reply_t* _xcb_get_props(WId window, const char *type, unsigned int atom_type)
|
||||||
|
{
|
||||||
|
if (!QX11Info::isPlatformX11())
|
||||||
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
xcb_connection_t *connection = QX11Info::connection();
|
xcb_connection_t *connection = QX11Info::connection();
|
||||||
xcb_atom_t type_atom = xcb_get_atom(type);
|
xcb_atom_t type_atom = xcb_get_atom(type);
|
||||||
if (type_atom == XCB_ATOM_NONE){
|
if (type_atom == XCB_ATOM_NONE)
|
||||||
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
xcb_get_property_cookie_t request = xcb_get_property_unchecked(connection, 0, window, type_atom, atom_type, 0, 1024);
|
xcb_get_property_cookie_t request = xcb_get_property_unchecked(connection, 0, window, type_atom, atom_type, 0, 1024);
|
||||||
xcb_get_property_reply_t *reply = xcb_get_property_reply(connection, request, nullptr);
|
xcb_get_property_reply_t *reply = xcb_get_property_reply(connection, request, nullptr);
|
||||||
if(reply && reply->type != atom_type){
|
if(reply && reply->type != atom_type)
|
||||||
|
{
|
||||||
ADS_PRINT("ATOM TYPE MISMATCH (" << type <<"). Expected: " << atom_type << " but got " << reply->type);
|
ADS_PRINT("ATOM TYPE MISMATCH (" << type <<"). Expected: " << atom_type << " but got " << reply->type);
|
||||||
free(reply);
|
free(reply);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -122,10 +139,14 @@ xcb_get_property_reply_t* _xcb_get_props(WId window, const char *type, unsigned
|
|||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void xcb_get_prop_list(WId window, const char *type, QVector<T> &ret, unsigned int atom_type){
|
void xcb_get_prop_list(WId window, const char *type, QVector<T> &ret, unsigned int atom_type)
|
||||||
|
{
|
||||||
xcb_get_property_reply_t *reply = _xcb_get_props(window, type, atom_type);
|
xcb_get_property_reply_t *reply = _xcb_get_props(window, type, atom_type);
|
||||||
if (reply && reply->format == 32 && reply->type == atom_type && reply->value_len > 0) {
|
if (reply && reply->format == 32 && reply->type == atom_type && reply->value_len > 0)
|
||||||
|
{
|
||||||
const xcb_atom_t *data = static_cast<const T *>(xcb_get_property_value(reply));
|
const xcb_atom_t *data = static_cast<const T *>(xcb_get_property_value(reply));
|
||||||
ret.resize(reply->value_len);
|
ret.resize(reply->value_len);
|
||||||
memcpy((void *)&ret.first(), (void *)data, reply->value_len * sizeof(T));
|
memcpy((void *)&ret.first(), (void *)data, reply->value_len * sizeof(T));
|
||||||
@ -133,13 +154,18 @@ void xcb_get_prop_list(WId window, const char *type, QVector<T> &ret, unsigned i
|
|||||||
free(reply);
|
free(reply);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString xcb_get_prop_string(WId window, const char *type){
|
|
||||||
|
//============================================================================
|
||||||
|
QString xcb_get_prop_string(WId window, const char *type)
|
||||||
|
{
|
||||||
QString ret;
|
QString ret;
|
||||||
// try utf8 first
|
// try utf8 first
|
||||||
xcb_atom_t utf_atom = xcb_get_atom("UTF8_STRING");
|
xcb_atom_t utf_atom = xcb_get_atom("UTF8_STRING");
|
||||||
if(utf_atom != XCB_ATOM_NONE){
|
if(utf_atom != XCB_ATOM_NONE)
|
||||||
|
{
|
||||||
xcb_get_property_reply_t *reply = _xcb_get_props(window, type, utf_atom);
|
xcb_get_property_reply_t *reply = _xcb_get_props(window, type, utf_atom);
|
||||||
if (reply && reply->format == 8 && reply->type == utf_atom) {
|
if (reply && reply->format == 8 && reply->type == utf_atom)
|
||||||
|
{
|
||||||
const char *value = reinterpret_cast<const char *>(xcb_get_property_value(reply));
|
const char *value = reinterpret_cast<const char *>(xcb_get_property_value(reply));
|
||||||
ret = QString::fromUtf8(value, xcb_get_property_value_length(reply));
|
ret = QString::fromUtf8(value, xcb_get_property_value_length(reply));
|
||||||
free(reply);
|
free(reply);
|
||||||
@ -149,7 +175,8 @@ QString xcb_get_prop_string(WId window, const char *type){
|
|||||||
}
|
}
|
||||||
// Fall back to XCB_ATOM_STRING
|
// Fall back to XCB_ATOM_STRING
|
||||||
xcb_get_property_reply_t *reply = _xcb_get_props(window, type, XCB_ATOM_STRING);
|
xcb_get_property_reply_t *reply = _xcb_get_props(window, type, XCB_ATOM_STRING);
|
||||||
if (reply && reply->format == 8 && reply->type == XCB_ATOM_STRING) {
|
if (reply && reply->format == 8 && reply->type == XCB_ATOM_STRING)
|
||||||
|
{
|
||||||
const char *value = reinterpret_cast<const char *>(xcb_get_property_value(reply));
|
const char *value = reinterpret_cast<const char *>(xcb_get_property_value(reply));
|
||||||
ret = QString::fromLatin1(value, xcb_get_property_value_length(reply));
|
ret = QString::fromLatin1(value, xcb_get_property_value_length(reply));
|
||||||
}
|
}
|
||||||
@ -157,12 +184,16 @@ QString xcb_get_prop_string(WId window, const char *type){
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool xcb_dump_props(WId window, const char *type){
|
|
||||||
|
//============================================================================
|
||||||
|
bool xcb_dump_props(WId window, const char *type)
|
||||||
|
{
|
||||||
QVector<xcb_atom_t> atoms;
|
QVector<xcb_atom_t> atoms;
|
||||||
xcb_get_prop_list(window, type, atoms, XCB_ATOM_ATOM);
|
xcb_get_prop_list(window, type, atoms, XCB_ATOM_ATOM);
|
||||||
qDebug() << "\n\n!!!" << type << " - " << atoms.length();
|
qDebug() << "\n\n!!!" << type << " - " << atoms.length();
|
||||||
xcb_connection_t *connection = QX11Info::connection();
|
xcb_connection_t *connection = QX11Info::connection();
|
||||||
for(auto atom : atoms){
|
for (auto atom : atoms)
|
||||||
|
{
|
||||||
auto foo = xcb_get_atom_name(connection, atom);
|
auto foo = xcb_get_atom_name(connection, atom);
|
||||||
auto bar = xcb_get_atom_name_reply(connection, foo, nullptr);
|
auto bar = xcb_get_atom_name_reply(connection, foo, nullptr);
|
||||||
qDebug() << "\t" << xcb_get_atom_name_name(bar);
|
qDebug() << "\t" << xcb_get_atom_name_name(bar);
|
||||||
@ -171,21 +202,29 @@ bool xcb_dump_props(WId window, const char *type){
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void xcb_add_prop(bool state, WId window, const char *type, const char *prop){
|
|
||||||
if (!QX11Info::isPlatformX11()){
|
//============================================================================
|
||||||
|
void xcb_add_prop(bool state, WId window, const char *type, const char *prop)
|
||||||
|
{
|
||||||
|
if (!QX11Info::isPlatformX11())
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
xcb_atom_t prop_atom = xcb_get_atom(prop);
|
xcb_atom_t prop_atom = xcb_get_atom(prop);
|
||||||
xcb_atom_t type_atom = xcb_get_atom(type);
|
xcb_atom_t type_atom = xcb_get_atom(type);
|
||||||
if(prop_atom == XCB_ATOM_NONE || type_atom == XCB_ATOM_NONE){
|
if (prop_atom == XCB_ATOM_NONE || type_atom == XCB_ATOM_NONE)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QVector<xcb_atom_t> atoms;
|
QVector<xcb_atom_t> atoms;
|
||||||
xcb_get_prop_list(window, type, atoms, XCB_ATOM_ATOM);
|
xcb_get_prop_list(window, type, atoms, XCB_ATOM_ATOM);
|
||||||
int index = atoms.indexOf(prop_atom);
|
int index = atoms.indexOf(prop_atom);
|
||||||
if(state && index == -1){
|
if (state && index == -1)
|
||||||
|
{
|
||||||
atoms.push_back(prop_atom);
|
atoms.push_back(prop_atom);
|
||||||
} else if(!state && index >= 0){
|
}
|
||||||
|
else if (!state && index >= 0)
|
||||||
|
{
|
||||||
atoms.remove(index);
|
atoms.remove(index);
|
||||||
}
|
}
|
||||||
xcb_connection_t *connection = QX11Info::connection();
|
xcb_connection_t *connection = QX11Info::connection();
|
||||||
@ -193,15 +232,20 @@ void xcb_add_prop(bool state, WId window, const char *type, const char *prop){
|
|||||||
xcb_flush(connection);
|
xcb_flush(connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString detectWindowManagerX11(){
|
|
||||||
|
//============================================================================
|
||||||
|
QString detectWindowManagerX11()
|
||||||
|
{
|
||||||
// Tries to detect the windowmanager via X11.
|
// Tries to detect the windowmanager via X11.
|
||||||
// See: https://specifications.freedesktop.org/wm-spec/1.3/ar01s03.html#idm46018259946000
|
// See: https://specifications.freedesktop.org/wm-spec/1.3/ar01s03.html#idm46018259946000
|
||||||
if (!QX11Info::isPlatformX11()){
|
if (!QX11Info::isPlatformX11())
|
||||||
|
{
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
}
|
}
|
||||||
xcb_connection_t *connection = QX11Info::connection();
|
xcb_connection_t *connection = QX11Info::connection();
|
||||||
xcb_screen_t *first_screen = xcb_setup_roots_iterator (xcb_get_setup (connection)).data;
|
xcb_screen_t *first_screen = xcb_setup_roots_iterator (xcb_get_setup (connection)).data;
|
||||||
if(!first_screen){
|
if(!first_screen)
|
||||||
|
{
|
||||||
ADS_PRINT("No screen found via XCB.");
|
ADS_PRINT("No screen found via XCB.");
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
}
|
}
|
||||||
@ -210,26 +254,32 @@ QString detectWindowManagerX11(){
|
|||||||
xcb_window_t support_win = 0;
|
xcb_window_t support_win = 0;
|
||||||
QVector<xcb_window_t> sup_windows;
|
QVector<xcb_window_t> sup_windows;
|
||||||
xcb_get_prop_list(root, "_NET_SUPPORTING_WM_CHECK", sup_windows, XCB_ATOM_WINDOW);
|
xcb_get_prop_list(root, "_NET_SUPPORTING_WM_CHECK", sup_windows, XCB_ATOM_WINDOW);
|
||||||
if(sup_windows.length() == 0){
|
if(sup_windows.length() == 0)
|
||||||
|
{
|
||||||
// This doesn't seem to be in use anymore, but wmctrl does the same so lets play safe.
|
// This doesn't seem to be in use anymore, but wmctrl does the same so lets play safe.
|
||||||
// Both XCB_ATOM_CARDINAL and XCB_ATOM_WINDOW break down to a uint32_t, so reusing sup_windows should be fine.
|
// Both XCB_ATOM_CARDINAL and XCB_ATOM_WINDOW break down to a uint32_t, so reusing sup_windows should be fine.
|
||||||
xcb_get_prop_list(root, "_WIN_SUPPORTING_WM_CHECK", sup_windows, XCB_ATOM_CARDINAL);
|
xcb_get_prop_list(root, "_WIN_SUPPORTING_WM_CHECK", sup_windows, XCB_ATOM_CARDINAL);
|
||||||
}
|
}
|
||||||
if(sup_windows.length() == 0){
|
if(sup_windows.length() == 0)
|
||||||
|
{
|
||||||
ADS_PRINT("Failed to get the supporting window on non EWMH comform WM.");
|
ADS_PRINT("Failed to get the supporting window on non EWMH comform WM.");
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
}
|
}
|
||||||
support_win = sup_windows[0];
|
support_win = sup_windows[0];
|
||||||
QString ret = xcb_get_prop_string(support_win, "_NET_WM_NAME");
|
QString ret = xcb_get_prop_string(support_win, "_NET_WM_NAME");
|
||||||
if(ret.length() == 0){
|
if(ret.length() == 0)
|
||||||
|
{
|
||||||
ADS_PRINT("Empty WM name occured.");
|
ADS_PRINT("Empty WM name occured.");
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString windowManager(){
|
//============================================================================
|
||||||
if(_window_manager.length() == 0){
|
QString windowManager()
|
||||||
|
{
|
||||||
|
if(_window_manager.length() == 0)
|
||||||
|
{
|
||||||
_window_manager = detectWindowManagerX11();
|
_window_manager = detectWindowManagerX11();
|
||||||
}
|
}
|
||||||
return _window_manager;
|
return _window_manager;
|
||||||
|
@ -135,30 +135,30 @@ static const char* const ClosedProperty = "close";
|
|||||||
static const char* const DirtyProperty = "dirty";
|
static const char* const DirtyProperty = "dirty";
|
||||||
|
|
||||||
#ifdef Q_OS_LINUX
|
#ifdef Q_OS_LINUX
|
||||||
// Utils to directly communicate with the X server
|
// Utils to directly communicate with the X server
|
||||||
/**
|
/**
|
||||||
* Get atom from cache or request it from the XServer.
|
* Get atom from cache or request it from the XServer.
|
||||||
*/
|
*/
|
||||||
xcb_atom_t xcb_get_atom(const char *name);
|
xcb_atom_t xcb_get_atom(const char *name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a property to a window. Only works on "hidden" windows.
|
* Add a property to a window. Only works on "hidden" windows.
|
||||||
*/
|
*/
|
||||||
void xcb_add_prop(bool state, WId window, const char *type, const char *prop);
|
void xcb_add_prop(bool state, WId window, const char *type, const char *prop);
|
||||||
/**
|
/**
|
||||||
* Updates up to two window properties. Can be set on a visible window.
|
* Updates up to two window properties. Can be set on a visible window.
|
||||||
*/
|
*/
|
||||||
void xcb_update_prop(bool set, WId window, const char *type, const char *prop, const char *prop2 = nullptr);
|
void xcb_update_prop(bool set, WId window, const char *type, const char *prop, const char *prop2 = nullptr);
|
||||||
/**
|
/**
|
||||||
* Only for debugging purposes.
|
* Only for debugging purposes.
|
||||||
*/
|
*/
|
||||||
bool xcb_dump_props(WId window, const char *type);
|
bool xcb_dump_props(WId window, const char *type);
|
||||||
/**
|
/**
|
||||||
* Gets the active window manager from the X11 Server.
|
* Gets the active window manager from the X11 Server.
|
||||||
* Requires a EWMH conform window manager (Allmost all common used ones are).
|
* Requires a EWMH conform window manager (Allmost all common used ones are).
|
||||||
* Returns "UNKNOWN" otherwise.
|
* Returns "UNKNOWN" otherwise.
|
||||||
*/
|
*/
|
||||||
QString windowManager();
|
QString windowManager();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,6 +154,7 @@ void CFloatingWidgetTitleBar::mousePressEvent(QMouseEvent *ev)
|
|||||||
Super::mousePressEvent(ev);
|
Super::mousePressEvent(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
void CFloatingWidgetTitleBar::mouseReleaseEvent(QMouseEvent *ev)
|
void CFloatingWidgetTitleBar::mouseReleaseEvent(QMouseEvent *ev)
|
||||||
{
|
{
|
||||||
@ -165,6 +166,7 @@ void CFloatingWidgetTitleBar::mouseReleaseEvent(QMouseEvent *ev)
|
|||||||
Super::mouseReleaseEvent(ev);
|
Super::mouseReleaseEvent(ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//============================================================================
|
//============================================================================
|
||||||
void CFloatingWidgetTitleBar::mouseMoveEvent(QMouseEvent *ev)
|
void CFloatingWidgetTitleBar::mouseMoveEvent(QMouseEvent *ev)
|
||||||
{
|
{
|
||||||
@ -178,12 +180,10 @@ void CFloatingWidgetTitleBar::mouseMoveEvent(QMouseEvent *ev)
|
|||||||
// move floating window
|
// move floating window
|
||||||
if (DraggingFloatingWidget == d->DragState)
|
if (DraggingFloatingWidget == d->DragState)
|
||||||
{
|
{
|
||||||
#ifdef Q_OS_LINUX
|
|
||||||
if(d->FloatingWidget->isMaximized())
|
if(d->FloatingWidget->isMaximized())
|
||||||
{
|
{
|
||||||
d->FloatingWidget->showNormal(true);
|
d->FloatingWidget->showNormal(true);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
d->FloatingWidget->moveFloating();
|
d->FloatingWidget->moveFloating();
|
||||||
Super::mouseMoveEvent(ev);
|
Super::mouseMoveEvent(ev);
|
||||||
return;
|
return;
|
||||||
@ -211,6 +211,8 @@ void CFloatingWidgetTitleBar::updateStyle()
|
|||||||
internal::repolishStyle(this, internal::RepolishDirectChildren);
|
internal::repolishStyle(this, internal::RepolishDirectChildren);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
void CFloatingWidgetTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
|
void CFloatingWidgetTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
|
||||||
{
|
{
|
||||||
if (event->buttons() & Qt::LeftButton)
|
if (event->buttons() & Qt::LeftButton)
|
||||||
@ -224,6 +226,8 @@ void CFloatingWidgetTitleBar::mouseDoubleClickEvent(QMouseEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//============================================================================
|
||||||
void CFloatingWidgetTitleBar::setMaximizedIcon(bool maximized)
|
void CFloatingWidgetTitleBar::setMaximizedIcon(bool maximized)
|
||||||
{
|
{
|
||||||
if (maximized)
|
if (maximized)
|
||||||
|
Loading…
Reference in New Issue
Block a user