mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
132 lines
2.7 KiB
C++
132 lines
2.7 KiB
C++
#include <CtrlCore/CtrlCore.h>
|
|
|
|
#ifdef GUI_GTK
|
|
|
|
namespace Upp {
|
|
|
|
#define LLOG(x) // DLOG(x)
|
|
|
|
Ptr<Ctrl> Ctrl::grabwindow;
|
|
Ptr<Ctrl> Ctrl::grabpopup;
|
|
|
|
#if GTK_CHECK_VERSION(3, 20, 0)
|
|
GdkSeat *Ctrl::GetSeat()
|
|
{
|
|
return gdk_display_get_default_seat(gdk_display_get_default());
|
|
}
|
|
#endif
|
|
|
|
GdkDevice *Ctrl::GetMouseDevice()
|
|
{
|
|
#if GTK_CHECK_VERSION(3, 20, 0)
|
|
return gdk_seat_get_pointer(GetSeat());
|
|
#else
|
|
return gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gdk_display_get_default()));
|
|
#endif
|
|
}
|
|
|
|
// (*) it is not really possible to do system-wide grab as there is conflict with csd
|
|
// so we depend on gtk doing automatic grab when mouse is down
|
|
|
|
bool Ctrl::MouseIsGrabbed()
|
|
{
|
|
if(grabwindow && grabwindow->top && grabwindow->utop->csd) // (*)
|
|
return true;
|
|
return gdk_display_device_is_grabbed(gdk_display_get_default(), GetMouseDevice());
|
|
}
|
|
|
|
bool Ctrl::GrabMouse()
|
|
{
|
|
if(top && utop->csd) // (*)
|
|
return true;
|
|
return
|
|
#if GTK_CHECK_VERSION(3, 20, 0)
|
|
gdk_seat_grab(GetSeat(), gdk(), GDK_SEAT_CAPABILITY_ALL_POINTING, true, NULL, NULL, NULL, 0)
|
|
#else
|
|
gdk_device_grab(GetMouseDevice(), gdk(), GDK_OWNERSHIP_APPLICATION, true, (GdkEventMask)0, NULL, GDK_CURRENT_TIME)
|
|
#endif
|
|
== GDK_GRAB_SUCCESS;
|
|
}
|
|
|
|
void Ctrl::UngrabMouse()
|
|
{
|
|
if(grabwindow && grabwindow->top && grabwindow->utop->csd) // (*)
|
|
return;
|
|
#if GTK_CHECK_VERSION(3, 20, 0)
|
|
gdk_seat_ungrab(GetSeat());
|
|
#else
|
|
gdk_device_ungrab(GetMouseDevice(), GDK_CURRENT_TIME);
|
|
#endif
|
|
}
|
|
|
|
void Ctrl::StopGrabPopup()
|
|
{
|
|
if(grabpopup && MouseIsGrabbed()) {
|
|
UngrabMouse();
|
|
grabpopup = NULL;
|
|
}
|
|
}
|
|
|
|
void Ctrl::StartGrabPopup()
|
|
{
|
|
if(activePopup.GetCount() && !grabpopup) {
|
|
Ctrl *w = activePopup[0];
|
|
if(w && w->IsOpen()) {
|
|
ReleaseWndCapture0();
|
|
// NOTE: On Wayland GrabMouse() is broken and shouldn't be used.
|
|
if(IsWayland() || w->GrabMouse()) {
|
|
grabpopup = w;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
bool Ctrl::SetWndCapture()
|
|
{
|
|
GuiLock __;
|
|
ASSERT(IsMainThread());
|
|
LLOG("SetWndCapture " << Name());
|
|
if(!IsOpen())
|
|
return false;
|
|
StopGrabPopup();
|
|
ReleaseWndCapture();
|
|
if(GrabMouse()) {
|
|
grabwindow = this;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Ctrl::ReleaseWndCapture0()
|
|
{
|
|
GuiLock __;
|
|
ASSERT(IsMainThread());
|
|
if(grabwindow) {
|
|
UngrabMouse();
|
|
grabwindow = NULL;
|
|
StartGrabPopup();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool Ctrl::ReleaseWndCapture()
|
|
{
|
|
return ReleaseWndCapture0();
|
|
}
|
|
|
|
bool Ctrl::HasWndCapture() const
|
|
{
|
|
GuiLock __;
|
|
return this == grabwindow && grabwindow->IsOpen() && MouseIsGrabbed();
|
|
}
|
|
|
|
void Ctrl::CaptureSync()
|
|
{
|
|
if(grabwindow && grabwindow->IsOpen() && !MouseIsGrabbed() && !grabwindow->GrabMouse())
|
|
grabwindow = NULL;
|
|
}
|
|
|
|
};
|
|
|
|
#endif
|