Support WM_CLOSE_WINDOW
This commit is contained in:
parent
20f105f56c
commit
85bb292a31
|
|
@ -8,6 +8,7 @@
|
||||||
#include "Utils.h"
|
#include "Utils.h"
|
||||||
|
|
||||||
#include <X11/X.h>
|
#include <X11/X.h>
|
||||||
|
#include <X11/Xatom.h>
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/epoll.h>
|
#include <sys/epoll.h>
|
||||||
|
|
@ -820,6 +821,72 @@ static void send_exposure_recursive(Client& client_info, WINDOW wid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void on_window_close_event(Client& client_info, WINDOW wid)
|
||||||
|
{
|
||||||
|
static CARD32 WM_PROTOCOLS = None;
|
||||||
|
static CARD32 WM_DELETE_WINDOW = None;
|
||||||
|
|
||||||
|
if (WM_PROTOCOLS == None)
|
||||||
|
{
|
||||||
|
auto it = g_atoms_name_to_id.find("WM_PROTOCOLS"_sv);
|
||||||
|
if (it != g_atoms_name_to_id.end())
|
||||||
|
WM_PROTOCOLS = it->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WM_DELETE_WINDOW == None)
|
||||||
|
{
|
||||||
|
auto it = g_atoms_name_to_id.find("WM_DELETE_WINDOW"_sv);
|
||||||
|
if (it != g_atoms_name_to_id.end())
|
||||||
|
WM_DELETE_WINDOW = it->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& object = *g_objects[wid];
|
||||||
|
ASSERT(object.type == Object::Type::Window);
|
||||||
|
auto& window = object.object.get<Object::Window>();
|
||||||
|
|
||||||
|
const bool supports_wm_delete_winow =
|
||||||
|
[&window]
|
||||||
|
{
|
||||||
|
if (WM_PROTOCOLS == None || WM_DELETE_WINDOW == None)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto wm_protocols_it = window.properties.find(WM_PROTOCOLS);
|
||||||
|
if (wm_protocols_it == window.properties.end())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto& wm_protocols = wm_protocols_it->value;
|
||||||
|
if (wm_protocols.type != XA_ATOM || wm_protocols.format != 32)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto atoms = BAN::ConstByteSpan(wm_protocols.data.span()).as_span<const CARD32>();
|
||||||
|
for (auto atom : atoms)
|
||||||
|
if (atom == WM_DELETE_WINDOW)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}();
|
||||||
|
|
||||||
|
if (!supports_wm_delete_winow)
|
||||||
|
MUST(destroy_window(client_info, wid));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xEvent event { .u = {
|
||||||
|
.clientMessage = {
|
||||||
|
.window = wid,
|
||||||
|
.u = { .l = {
|
||||||
|
.type = WM_PROTOCOLS,
|
||||||
|
.longs0 = static_cast<INT32>(WM_DELETE_WINDOW),
|
||||||
|
.longs1 = static_cast<INT32>(time(nullptr)),
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
event.u.u.type = ClientMessage;
|
||||||
|
event.u.u.detail = 32;
|
||||||
|
event.u.u.sequenceNumber = client_info.sequence;
|
||||||
|
MUST(encode(client_info.output_buffer, event));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void on_window_resize_event(Client& client_info, WINDOW wid)
|
static void on_window_resize_event(Client& client_info, WINDOW wid)
|
||||||
{
|
{
|
||||||
auto& object = *g_objects[wid];
|
auto& object = *g_objects[wid];
|
||||||
|
|
@ -1242,7 +1309,9 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
if (gui_window_ptr)
|
if (gui_window_ptr)
|
||||||
{
|
{
|
||||||
const WINDOW wid = request.wid;
|
const WINDOW wid = request.wid;
|
||||||
gui_window_ptr->set_close_window_event_callback([]{});
|
gui_window_ptr->set_close_window_event_callback([&client_info, wid] {
|
||||||
|
on_window_close_event(client_info, wid);
|
||||||
|
});
|
||||||
gui_window_ptr->set_resize_window_event_callback([&client_info, wid]() {
|
gui_window_ptr->set_resize_window_event_callback([&client_info, wid]() {
|
||||||
on_window_resize_event(client_info, wid);
|
on_window_resize_event(client_info, wid);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue