forked from quickshell/quickshell
hyprland/focus_grab: add HyprlandFocusGrab
This commit is contained in:
parent
e7cfb5cf37
commit
87a884ca36
15 changed files with 607 additions and 0 deletions
131
src/wayland/hyprland/focus_grab/qml.cpp
Normal file
131
src/wayland/hyprland/focus_grab/qml.cpp
Normal file
|
@ -0,0 +1,131 @@
|
|||
#include "qml.hpp"
|
||||
#include <utility>
|
||||
|
||||
#include <qlist.h>
|
||||
#include <qlogging.h>
|
||||
#include <qobject.h>
|
||||
#include <qqmllist.h>
|
||||
#include <qtmetamacros.h>
|
||||
#include <qwindow.h>
|
||||
|
||||
#include "../../../core/proxywindow.hpp"
|
||||
#include "../../../core/windowinterface.hpp"
|
||||
#include "grab.hpp"
|
||||
#include "manager.hpp"
|
||||
|
||||
namespace qs::hyprland {
|
||||
using focus_grab::FocusGrab;
|
||||
using focus_grab::FocusGrabManager;
|
||||
|
||||
void HyprlandFocusGrab::componentComplete() { this->tryActivate(); }
|
||||
|
||||
bool HyprlandFocusGrab::isActive() const { return this->grab != nullptr && this->grab->isActive(); }
|
||||
|
||||
void HyprlandFocusGrab::setActive(bool active) {
|
||||
if (active == this->targetActive) return;
|
||||
this->targetActive = active;
|
||||
|
||||
if (!active) {
|
||||
delete this->grab;
|
||||
this->grab = nullptr;
|
||||
emit this->activeChanged();
|
||||
} else {
|
||||
this->tryActivate();
|
||||
}
|
||||
}
|
||||
|
||||
QObjectList HyprlandFocusGrab::windows() const { return this->windowObjects; }
|
||||
|
||||
void HyprlandFocusGrab::setWindows(QObjectList windows) {
|
||||
if (windows == this->windowObjects) return;
|
||||
this->windowObjects = std::move(windows);
|
||||
this->syncWindows();
|
||||
emit this->windowsChanged();
|
||||
}
|
||||
|
||||
void HyprlandFocusGrab::onGrabActivated() { emit this->activeChanged(); }
|
||||
|
||||
void HyprlandFocusGrab::onGrabCleared() {
|
||||
emit this->cleared();
|
||||
this->setActive(false);
|
||||
}
|
||||
|
||||
void HyprlandFocusGrab::onProxyConnected() {
|
||||
if (this->grab != nullptr) {
|
||||
this->grab->addWindow(qobject_cast<ProxyWindowBase*>(this->sender())->backingWindow());
|
||||
this->grab->sync();
|
||||
}
|
||||
}
|
||||
|
||||
void HyprlandFocusGrab::tryActivate() {
|
||||
if (!this->targetActive || this->isActive()) return;
|
||||
|
||||
auto* manager = FocusGrabManager::instance();
|
||||
if (!manager->isActive()) {
|
||||
qWarning() << "The active compositor does not support the hyprland_focus_grab_v1 protocol. "
|
||||
"HyprlandFocusGrab will not work.";
|
||||
qWarning() << "** Learn why $XDG_CURRENT_DESKTOP sucks and download a better compositor "
|
||||
"today at https://hyprland.org";
|
||||
return;
|
||||
}
|
||||
|
||||
this->grab = manager->createGrab();
|
||||
this->grab->setParent(this);
|
||||
QObject::connect(this->grab, &FocusGrab::activated, this, &HyprlandFocusGrab::onGrabActivated);
|
||||
QObject::connect(this->grab, &FocusGrab::cleared, this, &HyprlandFocusGrab::onGrabCleared);
|
||||
|
||||
for (auto* proxy: this->trackedProxies) {
|
||||
if (proxy->backingWindow() != nullptr) {
|
||||
this->grab->addWindow(proxy->backingWindow());
|
||||
}
|
||||
}
|
||||
|
||||
this->grab->sync();
|
||||
}
|
||||
|
||||
void HyprlandFocusGrab::syncWindows() {
|
||||
auto newProxy = QList<ProxyWindowBase*>();
|
||||
for (auto* windowObject: this->windowObjects) {
|
||||
auto* proxyWindow = qobject_cast<ProxyWindowBase*>(windowObject);
|
||||
|
||||
if (proxyWindow == nullptr) {
|
||||
if (auto* iface = qobject_cast<WindowInterface*>(windowObject)) {
|
||||
proxyWindow = iface->proxyWindow();
|
||||
}
|
||||
}
|
||||
|
||||
if (proxyWindow != nullptr) {
|
||||
newProxy.push_back(proxyWindow);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto* oldWindow: this->trackedProxies) {
|
||||
if (!newProxy.contains(oldWindow)) {
|
||||
QObject::disconnect(oldWindow, nullptr, this, nullptr);
|
||||
|
||||
if (this->grab != nullptr && oldWindow->backingWindow() != nullptr) {
|
||||
this->grab->removeWindow(oldWindow->backingWindow());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto* newProxy: newProxy) {
|
||||
if (!this->trackedProxies.contains(newProxy)) {
|
||||
QObject::connect(
|
||||
newProxy,
|
||||
&ProxyWindowBase::windowConnected,
|
||||
this,
|
||||
&HyprlandFocusGrab::onProxyConnected
|
||||
);
|
||||
|
||||
if (this->grab != nullptr && newProxy->backingWindow() != nullptr) {
|
||||
this->grab->addWindow(newProxy->backingWindow());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this->trackedProxies = newProxy;
|
||||
if (this->grab != nullptr) this->grab->sync();
|
||||
}
|
||||
|
||||
} // namespace qs::hyprland
|
Loading…
Add table
Add a link
Reference in a new issue