Implement per-client event masks
This allows multiple clients to listen for events on the same window. Mostly used for listening events on the root window
This commit is contained in:
parent
e376c57cda
commit
61f8b2fa66
391
xbanan/Base.cpp
391
xbanan/Base.cpp
|
|
@ -159,6 +159,27 @@ static const char* s_opcode_to_name[] {
|
||||||
[X_NoOperation] = "X_NoOperation",
|
[X_NoOperation] = "X_NoOperation",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
uint32_t Object::Window::full_event_mask() const
|
||||||
|
{
|
||||||
|
uint32_t full_event_mask = 0;
|
||||||
|
for (auto [_, event_mask] : event_masks)
|
||||||
|
full_event_mask |= event_mask;
|
||||||
|
return full_event_mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<void> Object::Window::send_event(xEvent xevent, uint32_t xmask)
|
||||||
|
{
|
||||||
|
for (auto [client, event_mask] : event_masks)
|
||||||
|
{
|
||||||
|
if (!(event_mask & xmask))
|
||||||
|
continue;
|
||||||
|
xevent.u.u.sequenceNumber = client->sequence;
|
||||||
|
TRY(encode(client->output_buffer, xevent));
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> setup_client_conneciton(Client& client_info, const xConnClientPrefix& client_prefix)
|
BAN::ErrorOr<void> setup_client_conneciton(Client& client_info, const xConnClientPrefix& client_prefix)
|
||||||
{
|
{
|
||||||
dprintln("Connection Setup");
|
dprintln("Connection Setup");
|
||||||
|
|
@ -251,18 +272,14 @@ static BAN::ErrorOr<void> send_visibility_events_recursively(Client& client_info
|
||||||
|
|
||||||
if (window.c_class == InputOutput)
|
if (window.c_class == InputOutput)
|
||||||
{
|
{
|
||||||
if (window.event_mask & VisibilityChangeMask)
|
xEvent event = { .u = {
|
||||||
{
|
.visibility = {
|
||||||
xEvent event = { .u = {
|
.window = wid,
|
||||||
.visibility = {
|
.state = static_cast<CARD8>(visible ? 0 : 2),
|
||||||
.window = wid,
|
}
|
||||||
.state = static_cast<CARD8>(visible ? 0 : 2),
|
}};
|
||||||
}
|
event.u.u.type = VisibilityNotify;
|
||||||
}};
|
TRY(window.send_event(event, VisibilityChangeMask));
|
||||||
event.u.u.type = VisibilityNotify;
|
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
|
||||||
TRY(encode(client_info.output_buffer, event));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto child_wid : window.children)
|
for (auto child_wid : window.children)
|
||||||
|
|
@ -413,7 +430,6 @@ static BAN::ErrorOr<void> map_window(Client& client_info, WINDOW wid)
|
||||||
gui_window->invalidate();
|
gui_window->invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.event_mask & StructureNotifyMask)
|
|
||||||
{
|
{
|
||||||
xEvent event = { .u = {
|
xEvent event = { .u = {
|
||||||
.mapNotify = {
|
.mapNotify = {
|
||||||
|
|
@ -423,15 +439,13 @@ static BAN::ErrorOr<void> map_window(Client& client_info, WINDOW wid)
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
event.u.u.type = MapNotify;
|
event.u.u.type = MapNotify;
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
TRY(window.send_event(event, StructureNotifyMask));
|
||||||
TRY(encode(client_info.output_buffer, event));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& parent_object = *g_objects[window.parent];
|
auto& parent_object = *g_objects[window.parent];
|
||||||
ASSERT(parent_object.type == Object::Type::Window);
|
ASSERT(parent_object.type == Object::Type::Window);
|
||||||
|
|
||||||
auto& parent_window = parent_object.object.get<Object::Window>();
|
auto& parent_window = parent_object.object.get<Object::Window>();
|
||||||
if (parent_window.event_mask & SubstructureNotifyMask)
|
|
||||||
{
|
{
|
||||||
xEvent event = { .u = {
|
xEvent event = { .u = {
|
||||||
.mapNotify = {
|
.mapNotify = {
|
||||||
|
|
@ -441,14 +455,12 @@ static BAN::ErrorOr<void> map_window(Client& client_info, WINDOW wid)
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
event.u.u.type = MapNotify;
|
event.u.u.type = MapNotify;
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
TRY(parent_window.send_event(event, SubstructureNotifyMask));
|
||||||
TRY(encode(client_info.output_buffer, event));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_visible(window.parent))
|
if (is_visible(window.parent))
|
||||||
TRY(send_visibility_events_recursively(client_info, wid, true));
|
TRY(send_visibility_events_recursively(client_info, wid, true));
|
||||||
|
|
||||||
if (window.event_mask & ExposureMask)
|
|
||||||
{
|
{
|
||||||
xEvent event = { .u = {
|
xEvent event = { .u = {
|
||||||
.expose = {
|
.expose = {
|
||||||
|
|
@ -460,8 +472,7 @@ static BAN::ErrorOr<void> map_window(Client& client_info, WINDOW wid)
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
event.u.u.type = Expose;
|
event.u.u.type = Expose;
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
TRY(window.send_event(event, ExposureMask));
|
||||||
TRY(encode(client_info.output_buffer, event));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
|
@ -489,7 +500,6 @@ static BAN::ErrorOr<void> unmap_window(Client& client_info, WINDOW wid)
|
||||||
if (is_visible(window.parent))
|
if (is_visible(window.parent))
|
||||||
TRY(send_visibility_events_recursively(client_info, wid, false));
|
TRY(send_visibility_events_recursively(client_info, wid, false));
|
||||||
|
|
||||||
if (window.event_mask & StructureNotifyMask)
|
|
||||||
{
|
{
|
||||||
xEvent event = { .u = {
|
xEvent event = { .u = {
|
||||||
.unmapNotify = {
|
.unmapNotify = {
|
||||||
|
|
@ -499,15 +509,13 @@ static BAN::ErrorOr<void> unmap_window(Client& client_info, WINDOW wid)
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
event.u.u.type = UnmapNotify;
|
event.u.u.type = UnmapNotify;
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
TRY(window.send_event(event, StructureNotifyMask));
|
||||||
TRY(encode(client_info.output_buffer, event));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& parent_object = *g_objects[window.parent];
|
auto& parent_object = *g_objects[window.parent];
|
||||||
ASSERT(parent_object.type == Object::Type::Window);
|
ASSERT(parent_object.type == Object::Type::Window);
|
||||||
|
|
||||||
auto& parent_window = parent_object.object.get<Object::Window>();
|
auto& parent_window = parent_object.object.get<Object::Window>();
|
||||||
if (parent_window.event_mask & SubstructureNotifyMask)
|
|
||||||
{
|
{
|
||||||
xEvent event = { .u = {
|
xEvent event = { .u = {
|
||||||
.unmapNotify = {
|
.unmapNotify = {
|
||||||
|
|
@ -517,8 +525,7 @@ static BAN::ErrorOr<void> unmap_window(Client& client_info, WINDOW wid)
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
event.u.u.type = UnmapNotify;
|
event.u.u.type = UnmapNotify;
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
TRY(parent_window.send_event(event, SubstructureNotifyMask));
|
||||||
TRY(encode(client_info.output_buffer, event));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
|
|
@ -536,7 +543,6 @@ static BAN::ErrorOr<void> destroy_window(Client& client_info, WINDOW wid)
|
||||||
for (auto child_wid : window.children)
|
for (auto child_wid : window.children)
|
||||||
TRY(destroy_window(client_info, child_wid));
|
TRY(destroy_window(client_info, child_wid));
|
||||||
|
|
||||||
if (window.event_mask & StructureNotifyMask)
|
|
||||||
{
|
{
|
||||||
xEvent event = { .u = {
|
xEvent event = { .u = {
|
||||||
.destroyNotify = {
|
.destroyNotify = {
|
||||||
|
|
@ -545,15 +551,13 @@ static BAN::ErrorOr<void> destroy_window(Client& client_info, WINDOW wid)
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
event.u.u.type = DestroyNotify;
|
event.u.u.type = DestroyNotify;
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
TRY(window.send_event(event, StructureNotifyMask));
|
||||||
TRY(encode(client_info.output_buffer, event));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& parent_object = *g_objects[window.parent];
|
auto& parent_object = *g_objects[window.parent];
|
||||||
ASSERT(parent_object.type == Object::Type::Window);
|
ASSERT(parent_object.type == Object::Type::Window);
|
||||||
|
|
||||||
auto& parent_window = parent_object.object.get<Object::Window>();
|
auto& parent_window = parent_object.object.get<Object::Window>();
|
||||||
if (parent_window.event_mask & SubstructureNotifyMask)
|
|
||||||
{
|
{
|
||||||
xEvent event = { .u = {
|
xEvent event = { .u = {
|
||||||
.destroyNotify = {
|
.destroyNotify = {
|
||||||
|
|
@ -562,8 +566,7 @@ static BAN::ErrorOr<void> destroy_window(Client& client_info, WINDOW wid)
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
event.u.u.type = DestroyNotify;
|
event.u.u.type = DestroyNotify;
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
TRY(parent_window.send_event(event, SubstructureNotifyMask));
|
||||||
TRY(encode(client_info.output_buffer, event));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < parent_window.children.size(); i++)
|
for (size_t i = 0; i < parent_window.children.size(); i++)
|
||||||
|
|
@ -669,7 +672,7 @@ static BAN::Vector<WINDOW> get_path_to_child(WINDOW wid, int32_t x, int32_t y)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_enter_and_leave_events(Client& client_info, WINDOW wid, int32_t old_x, int32_t old_y, int32_t new_x, int32_t new_y)
|
static void send_enter_and_leave_events(WINDOW wid, int32_t old_x, int32_t old_y, int32_t new_x, int32_t new_y)
|
||||||
{
|
{
|
||||||
// FIXME: correct event_x and event_y values in events
|
// FIXME: correct event_x and event_y values in events
|
||||||
|
|
||||||
|
|
@ -722,10 +725,8 @@ static void send_enter_and_leave_events(Client& client_info, WINDOW wid, int32_t
|
||||||
auto& object = *g_objects[wid];
|
auto& object = *g_objects[wid];
|
||||||
ASSERT(object.type == Object::Type::Window);
|
ASSERT(object.type == Object::Type::Window);
|
||||||
auto& window = object.object.get<Object::Window>();
|
auto& window = object.object.get<Object::Window>();
|
||||||
if (!(window.event_mask & LeaveWindowMask))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
xEvent xevent { .u = {
|
xEvent event { .u = {
|
||||||
.enterLeave = {
|
.enterLeave = {
|
||||||
.time = static_cast<CARD32>(time(nullptr)),
|
.time = static_cast<CARD32>(time(nullptr)),
|
||||||
.root = g_root.windowId,
|
.root = g_root.windowId,
|
||||||
|
|
@ -740,10 +741,9 @@ static void send_enter_and_leave_events(Client& client_info, WINDOW wid, int32_t
|
||||||
.flags = get_flags(wid),
|
.flags = get_flags(wid),
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
xevent.u.u.type = LeaveNotify,
|
event.u.u.type = LeaveNotify,
|
||||||
xevent.u.u.detail = detail;
|
event.u.u.detail = detail;
|
||||||
xevent.u.u.sequenceNumber = client_info.sequence;
|
MUST(window.send_event(event, LeaveWindowMask));
|
||||||
MUST(encode(client_info.output_buffer, xevent));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < enter_events; i++)
|
for (size_t i = 0; i < enter_events; i++)
|
||||||
|
|
@ -765,10 +765,8 @@ static void send_enter_and_leave_events(Client& client_info, WINDOW wid, int32_t
|
||||||
auto& object = *g_objects[wid];
|
auto& object = *g_objects[wid];
|
||||||
ASSERT(object.type == Object::Type::Window);
|
ASSERT(object.type == Object::Type::Window);
|
||||||
auto& window = object.object.get<Object::Window>();
|
auto& window = object.object.get<Object::Window>();
|
||||||
if (!(window.event_mask & EnterWindowMask))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
xEvent xevent { .u = {
|
xEvent event { .u = {
|
||||||
.enterLeave = {
|
.enterLeave = {
|
||||||
.time = static_cast<CARD32>(time(nullptr)),
|
.time = static_cast<CARD32>(time(nullptr)),
|
||||||
.root = g_root.windowId,
|
.root = g_root.windowId,
|
||||||
|
|
@ -783,14 +781,13 @@ static void send_enter_and_leave_events(Client& client_info, WINDOW wid, int32_t
|
||||||
.flags = get_flags(wid),
|
.flags = get_flags(wid),
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
xevent.u.u.type = EnterNotify,
|
event.u.u.type = EnterNotify,
|
||||||
xevent.u.u.detail = detail;
|
event.u.u.detail = detail;
|
||||||
xevent.u.u.sequenceNumber = client_info.sequence;
|
MUST(window.send_event(event, EnterWindowMask));
|
||||||
MUST(encode(client_info.output_buffer, xevent));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_exposure_recursive(Client& client_info, WINDOW wid)
|
static void send_exposure_recursive(WINDOW wid)
|
||||||
{
|
{
|
||||||
auto& object = *g_objects[wid];
|
auto& object = *g_objects[wid];
|
||||||
ASSERT(object.type == Object::Type::Window);
|
ASSERT(object.type == Object::Type::Window);
|
||||||
|
|
@ -800,25 +797,21 @@ static void send_exposure_recursive(Client& client_info, WINDOW wid)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (auto child_wid : window.children)
|
for (auto child_wid : window.children)
|
||||||
send_exposure_recursive(client_info, child_wid);
|
send_exposure_recursive(child_wid);
|
||||||
|
|
||||||
window.texture().clear();
|
window.texture().clear();
|
||||||
|
|
||||||
if (window.event_mask & ExposureMask)
|
xEvent event = { .u = {
|
||||||
{
|
.expose = {
|
||||||
xEvent event = { .u = {
|
.window = wid,
|
||||||
.expose = {
|
.x = 0,
|
||||||
.window = wid,
|
.y = 0,
|
||||||
.x = 0,
|
.width = static_cast<CARD16>(window.texture().width()),
|
||||||
.y = 0,
|
.height = static_cast<CARD16>(window.texture().height()),
|
||||||
.width = static_cast<CARD16>(window.texture().width()),
|
}
|
||||||
.height = static_cast<CARD16>(window.texture().height()),
|
}};
|
||||||
}
|
event.u.u.type = Expose;
|
||||||
}};
|
MUST(window.send_event(event, ExposureMask));
|
||||||
event.u.u.type = Expose;
|
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
|
||||||
MUST(encode(client_info.output_buffer, event));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_window_close_event(Client& client_info, WINDOW wid)
|
static void on_window_close_event(Client& client_info, WINDOW wid)
|
||||||
|
|
@ -870,13 +863,12 @@ static void on_window_close_event(Client& client_info, WINDOW wid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_window_resize_event(Client& client_info, WINDOW wid)
|
static void on_window_resize_event(WINDOW wid)
|
||||||
{
|
{
|
||||||
auto& object = *g_objects[wid];
|
auto& object = *g_objects[wid];
|
||||||
ASSERT(object.type == Object::Type::Window);
|
ASSERT(object.type == Object::Type::Window);
|
||||||
|
|
||||||
auto& window = object.object.get<Object::Window>();
|
auto& window = object.object.get<Object::Window>();
|
||||||
if (window.event_mask & StructureNotifyMask)
|
|
||||||
{
|
{
|
||||||
xEvent event = { .u = {
|
xEvent event = { .u = {
|
||||||
.configureNotify = {
|
.configureNotify = {
|
||||||
|
|
@ -892,15 +884,13 @@ static void on_window_resize_event(Client& client_info, WINDOW wid)
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
event.u.u.type = ConfigureNotify;
|
event.u.u.type = ConfigureNotify;
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
MUST(window.send_event(event, StructureNotifyMask));
|
||||||
MUST(encode(client_info.output_buffer, event));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& parent_object = *g_objects[window.parent];
|
auto& parent_object = *g_objects[window.parent];
|
||||||
ASSERT(parent_object.type == Object::Type::Window);
|
ASSERT(parent_object.type == Object::Type::Window);
|
||||||
|
|
||||||
auto& parent_window = parent_object.object.get<Object::Window>();
|
auto& parent_window = parent_object.object.get<Object::Window>();
|
||||||
if (parent_window.event_mask & SubstructureNotifyMask)
|
|
||||||
{
|
{
|
||||||
xEvent event = { .u = {
|
xEvent event = { .u = {
|
||||||
.configureNotify = {
|
.configureNotify = {
|
||||||
|
|
@ -916,16 +906,15 @@ static void on_window_resize_event(Client& client_info, WINDOW wid)
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
event.u.u.type = ConfigureNotify;
|
event.u.u.type = ConfigureNotify;
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
MUST(parent_window.send_event(event, SubstructureNotifyMask));
|
||||||
MUST(encode(client_info.output_buffer, event));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
send_exposure_recursive(client_info, wid);
|
send_exposure_recursive(wid);
|
||||||
|
|
||||||
invalidate_window(wid, 0, 0, window.texture().width(), window.texture().height());
|
invalidate_window(wid, 0, 0, window.texture().width(), window.texture().height());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_window_focus_event(Client& client_info, WINDOW wid, bool focused)
|
static void on_window_focus_event(WINDOW wid, bool focused)
|
||||||
{
|
{
|
||||||
if (focused)
|
if (focused)
|
||||||
s_focus_window = wid;
|
s_focus_window = wid;
|
||||||
|
|
@ -939,24 +928,20 @@ static void on_window_focus_event(Client& client_info, WINDOW wid, bool focused)
|
||||||
|
|
||||||
window.focused = focused;
|
window.focused = focused;
|
||||||
|
|
||||||
if (!(window.event_mask & FocusChangeMask))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// FIXME: handle childs
|
// FIXME: handle childs
|
||||||
|
|
||||||
xEvent xevent { .u = {
|
xEvent event { .u = {
|
||||||
.focus = {
|
.focus = {
|
||||||
.window = wid,
|
.window = wid,
|
||||||
.mode = NotifyNormal,
|
.mode = NotifyNormal,
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
xevent.u.u.type = focused ? FocusIn : FocusOut,
|
event.u.u.type = focused ? FocusIn : FocusOut,
|
||||||
xevent.u.u.detail = NotifyNonlinear;
|
event.u.u.detail = NotifyNonlinear;
|
||||||
xevent.u.u.sequenceNumber = client_info.sequence;
|
MUST(window.send_event(event, FocusChangeMask));
|
||||||
MUST(encode(client_info.output_buffer, xevent));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_key_button_pointer_event(Client& client_info, WINDOW root_wid, BYTE detail, uint32_t event_mask, BYTE event_type)
|
static void send_key_button_pointer_event(WINDOW root_wid, BYTE detail, uint32_t event_mask, BYTE event_type)
|
||||||
{
|
{
|
||||||
int32_t root_x, root_y;
|
int32_t root_x, root_y;
|
||||||
int32_t event_x, event_y;
|
int32_t event_x, event_y;
|
||||||
|
|
@ -977,7 +962,7 @@ static void send_key_button_pointer_event(Client& client_info, WINDOW root_wid,
|
||||||
auto& object = *g_objects[wid];
|
auto& object = *g_objects[wid];
|
||||||
ASSERT(object.type == Object::Type::Window);
|
ASSERT(object.type == Object::Type::Window);
|
||||||
auto& window = object.object.get<Object::Window>();
|
auto& window = object.object.get<Object::Window>();
|
||||||
if (window.event_mask & event_mask)
|
if (window.full_event_mask() & event_mask)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
event_x += window.x;
|
event_x += window.x;
|
||||||
|
|
@ -992,7 +977,11 @@ static void send_key_button_pointer_event(Client& client_info, WINDOW root_wid,
|
||||||
wid = root_wid;
|
wid = root_wid;
|
||||||
}
|
}
|
||||||
|
|
||||||
xEvent xevent { .u = {
|
auto& object = *g_objects[wid];
|
||||||
|
ASSERT(object.type == Object::Type::Window);
|
||||||
|
auto& window = object.object.get<Object::Window>();
|
||||||
|
|
||||||
|
xEvent event { .u = {
|
||||||
.keyButtonPointer = {
|
.keyButtonPointer = {
|
||||||
.time = static_cast<CARD32>(time(nullptr)),
|
.time = static_cast<CARD32>(time(nullptr)),
|
||||||
.root = g_root.windowId,
|
.root = g_root.windowId,
|
||||||
|
|
@ -1006,10 +995,9 @@ static void send_key_button_pointer_event(Client& client_info, WINDOW root_wid,
|
||||||
.sameScreen = xTrue,
|
.sameScreen = xTrue,
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
xevent.u.u.type = event_type,
|
event.u.u.type = event_type,
|
||||||
xevent.u.u.detail = detail;
|
event.u.u.detail = detail;
|
||||||
xevent.u.u.sequenceNumber = client_info.sequence;
|
MUST(window.send_event(event, event_mask));
|
||||||
MUST(encode(client_info.output_buffer, xevent));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_cursor_position_recursive(WINDOW wid, int32_t new_x, int32_t new_y)
|
static void update_cursor_position_recursive(WINDOW wid, int32_t new_x, int32_t new_y)
|
||||||
|
|
@ -1049,7 +1037,7 @@ static void update_cursor(WINDOW wid, int32_t old_x, int32_t old_y, int32_t new_
|
||||||
gui_window->set_cursor(cursor.width, cursor.height, cursor.pixels.span(), cursor.origin_x, cursor.origin_y);
|
gui_window->set_cursor(cursor.width, cursor.height, cursor.pixels.span(), cursor.origin_x, cursor.origin_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_mouse_move_event(Client& client_info, WINDOW wid, int32_t x, int32_t y)
|
static void on_mouse_move_event(WINDOW wid, int32_t x, int32_t y)
|
||||||
{
|
{
|
||||||
auto& object = *g_objects[wid];
|
auto& object = *g_objects[wid];
|
||||||
ASSERT(object.type == Object::Type::Window);
|
ASSERT(object.type == Object::Type::Window);
|
||||||
|
|
@ -1057,7 +1045,7 @@ static void on_mouse_move_event(Client& client_info, WINDOW wid, int32_t x, int3
|
||||||
|
|
||||||
update_cursor(wid, window.cursor_x, window.cursor_y, x, y);
|
update_cursor(wid, window.cursor_x, window.cursor_y, x, y);
|
||||||
|
|
||||||
send_enter_and_leave_events(client_info, wid, window.cursor_x, window.cursor_y, x, y);
|
send_enter_and_leave_events(wid, window.cursor_x, window.cursor_y, x, y);
|
||||||
|
|
||||||
update_cursor_position_recursive(wid, x, y);
|
update_cursor_position_recursive(wid, x, y);
|
||||||
|
|
||||||
|
|
@ -1069,10 +1057,10 @@ static void on_mouse_move_event(Client& client_info, WINDOW wid, int32_t x, int3
|
||||||
if (s_butmask & Button3Mask) event_mask |= Button3MotionMask;
|
if (s_butmask & Button3Mask) event_mask |= Button3MotionMask;
|
||||||
if (s_butmask & Button4Mask) event_mask |= Button4MotionMask;
|
if (s_butmask & Button4Mask) event_mask |= Button4MotionMask;
|
||||||
if (s_butmask & Button5Mask) event_mask |= Button5MotionMask;
|
if (s_butmask & Button5Mask) event_mask |= Button5MotionMask;
|
||||||
send_key_button_pointer_event(client_info, wid, NotifyNormal, event_mask, MotionNotify);
|
send_key_button_pointer_event(wid, NotifyNormal, event_mask, MotionNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_mouse_button_event(Client& client_info, WINDOW wid, uint8_t xbutton, bool pressed)
|
static void on_mouse_button_event(WINDOW wid, uint8_t xbutton, bool pressed)
|
||||||
{
|
{
|
||||||
uint16_t mask = 0;
|
uint16_t mask = 0;
|
||||||
switch (xbutton)
|
switch (xbutton)
|
||||||
|
|
@ -1090,7 +1078,6 @@ static void on_mouse_button_event(Client& client_info, WINDOW wid, uint8_t xbutt
|
||||||
s_butmask &= ~mask;
|
s_butmask &= ~mask;
|
||||||
|
|
||||||
send_key_button_pointer_event(
|
send_key_button_pointer_event(
|
||||||
client_info,
|
|
||||||
wid,
|
wid,
|
||||||
xbutton,
|
xbutton,
|
||||||
pressed ? ButtonPressMask : ButtonReleaseMask,
|
pressed ? ButtonPressMask : ButtonReleaseMask,
|
||||||
|
|
@ -1098,7 +1085,7 @@ static void on_mouse_button_event(Client& client_info, WINDOW wid, uint8_t xbutt
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_key_event(Client& client_info, WINDOW wid, LibGUI::EventPacket::KeyEvent::event_t event)
|
static void on_key_event(WINDOW wid, LibGUI::EventPacket::KeyEvent::event_t event)
|
||||||
{
|
{
|
||||||
const uint8_t xkeycode = event.scancode + g_keymap_min_keycode;
|
const uint8_t xkeycode = event.scancode + g_keymap_min_keycode;
|
||||||
if (xkeycode < g_keymap_min_keycode)
|
if (xkeycode < g_keymap_min_keycode)
|
||||||
|
|
@ -1127,7 +1114,6 @@ static void on_key_event(Client& client_info, WINDOW wid, LibGUI::EventPacket::K
|
||||||
s_keymask |= Mod1Mask;
|
s_keymask |= Mod1Mask;
|
||||||
|
|
||||||
send_key_button_pointer_event(
|
send_key_button_pointer_event(
|
||||||
client_info,
|
|
||||||
wid,
|
wid,
|
||||||
xkeycode,
|
xkeycode,
|
||||||
event.pressed() ? KeyPressMask : KeyReleaseMask,
|
event.pressed() ? KeyPressMask : KeyReleaseMask,
|
||||||
|
|
@ -1135,7 +1121,7 @@ static void on_key_event(Client& client_info, WINDOW wid, LibGUI::EventPacket::K
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_window_fullscreen_event(Client& client_info, WINDOW wid, bool is_fullscreen)
|
static void on_window_fullscreen_event(WINDOW wid, bool is_fullscreen)
|
||||||
{
|
{
|
||||||
static CARD32 _NET_WM_STATE = g_atoms_name_to_id["_NET_WM_STATE"_sv];
|
static CARD32 _NET_WM_STATE = g_atoms_name_to_id["_NET_WM_STATE"_sv];
|
||||||
static CARD32 _NET_WM_STATE_FULLSCREEN = g_atoms_name_to_id["_NET_WM_STATE_FULLSCREEN"_sv];
|
static CARD32 _NET_WM_STATE_FULLSCREEN = g_atoms_name_to_id["_NET_WM_STATE_FULLSCREEN"_sv];
|
||||||
|
|
@ -1178,26 +1164,16 @@ static void on_window_fullscreen_event(Client& client_info, WINDOW wid, bool is_
|
||||||
reinterpret_cast<CARD32*>(_net_wm_state.data.data())[atom_count] = _NET_WM_STATE_FULLSCREEN;
|
reinterpret_cast<CARD32*>(_net_wm_state.data.data())[atom_count] = _NET_WM_STATE_FULLSCREEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.event_mask & PropertyChangeMask)
|
xEvent event = { .u = {
|
||||||
{
|
.property = {
|
||||||
xEvent event = { .u = {
|
.window = wid,
|
||||||
.property = {
|
.atom = _NET_WM_STATE,
|
||||||
.window = wid,
|
.time = static_cast<CARD32>(time(nullptr)),
|
||||||
.atom = _NET_WM_STATE,
|
.state = PropertyNewValue,
|
||||||
.time = static_cast<CARD32>(time(nullptr)),
|
}
|
||||||
.state = PropertyNewValue,
|
}};
|
||||||
}
|
event.u.u.type = PropertyNotify;
|
||||||
}};
|
MUST(window.send_event(event, PropertyChangeMask));
|
||||||
event.u.u.type = PropertyNotify;
|
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
|
||||||
MUST(encode(client_info.output_buffer, event));
|
|
||||||
|
|
||||||
dwarnln("sent fullscreen {} to {}", is_fullscreen, wid);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dwarnln("did not send fullscreen {} to {}", is_fullscreen, wid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void on_root_client_message(const xEvent& event)
|
static void on_root_client_message(const xEvent& event)
|
||||||
|
|
@ -1373,7 +1349,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
TRY(parent_window.children.push_back(request.wid));
|
TRY(parent_window.children.push_back(request.wid));
|
||||||
|
|
||||||
TRY(client_info.objects.insert(request.wid));
|
TRY(client_info.objects.insert(request.wid));
|
||||||
TRY(g_objects.insert(
|
auto object_it = TRY(g_objects.insert(
|
||||||
request.wid,
|
request.wid,
|
||||||
TRY(BAN::UniqPtr<Object>::create(Object {
|
TRY(BAN::UniqPtr<Object>::create(Object {
|
||||||
.type = Object::Type::Window,
|
.type = Object::Type::Window,
|
||||||
|
|
@ -1381,7 +1357,6 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
.depth = request.depth,
|
.depth = request.depth,
|
||||||
.x = request.x,
|
.x = request.x,
|
||||||
.y = request.y,
|
.y = request.y,
|
||||||
.event_mask = event_mask,
|
|
||||||
.parent = request.parent,
|
.parent = request.parent,
|
||||||
.cursor = cursor_id,
|
.cursor = cursor_id,
|
||||||
.c_class = request.c_class == CopyFromParent ? parent_window.c_class : request.c_class,
|
.c_class = request.c_class == CopyFromParent ? parent_window.c_class : request.c_class,
|
||||||
|
|
@ -1389,6 +1364,8 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
},
|
},
|
||||||
}))
|
}))
|
||||||
));
|
));
|
||||||
|
if (event_mask != 0)
|
||||||
|
TRY(object_it->value->object.get<Object::Window>().event_masks.insert(&client_info, event_mask));
|
||||||
|
|
||||||
if (gui_window_ptr)
|
if (gui_window_ptr)
|
||||||
{
|
{
|
||||||
|
|
@ -1396,17 +1373,17 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
gui_window_ptr->set_close_window_event_callback([&client_info, wid] {
|
gui_window_ptr->set_close_window_event_callback([&client_info, wid] {
|
||||||
on_window_close_event(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([wid]() {
|
||||||
on_window_resize_event(client_info, wid);
|
on_window_resize_event(wid);
|
||||||
});
|
});
|
||||||
gui_window_ptr->set_window_focus_event_callback([&client_info, wid](auto event) {
|
gui_window_ptr->set_window_focus_event_callback([wid](auto event) {
|
||||||
on_window_focus_event(client_info, wid, event.focused);
|
on_window_focus_event(wid, event.focused);
|
||||||
});
|
});
|
||||||
gui_window_ptr->set_window_fullscreen_event_callback([&client_info, wid](auto event) {
|
gui_window_ptr->set_window_fullscreen_event_callback([wid](auto event) {
|
||||||
on_window_fullscreen_event(client_info, wid, event.fullscreen);
|
on_window_fullscreen_event(wid, event.fullscreen);
|
||||||
});
|
});
|
||||||
gui_window_ptr->set_mouse_move_event_callback([&client_info, wid](auto event) {
|
gui_window_ptr->set_mouse_move_event_callback([wid](auto event) {
|
||||||
on_mouse_move_event(client_info, wid, event.x, event.y);
|
on_mouse_move_event(wid, event.x, event.y);
|
||||||
});
|
});
|
||||||
gui_window_ptr->set_mouse_button_event_callback([&client_info, wid](auto event) {
|
gui_window_ptr->set_mouse_button_event_callback([&client_info, wid](auto event) {
|
||||||
uint8_t xbutton = 0;
|
uint8_t xbutton = 0;
|
||||||
|
|
@ -1419,35 +1396,31 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
case LibInput::MouseButton::Extra2: xbutton = 9; break;
|
case LibInput::MouseButton::Extra2: xbutton = 9; break;
|
||||||
}
|
}
|
||||||
if (xbutton)
|
if (xbutton)
|
||||||
on_mouse_button_event(client_info, wid, xbutton, event.pressed);
|
on_mouse_button_event(wid, xbutton, event.pressed);
|
||||||
});
|
});
|
||||||
gui_window_ptr->set_mouse_scroll_event_callback([&client_info, wid](auto event) {
|
gui_window_ptr->set_mouse_scroll_event_callback([wid](auto event) {
|
||||||
on_mouse_button_event(client_info, wid, event.scroll > 0 ? 4 : 5, true);
|
on_mouse_button_event(wid, event.scroll > 0 ? 4 : 5, true);
|
||||||
on_mouse_button_event(client_info, wid, event.scroll > 0 ? 4 : 5, false);
|
on_mouse_button_event(wid, event.scroll > 0 ? 4 : 5, false);
|
||||||
});
|
});
|
||||||
gui_window_ptr->set_key_event_callback([&client_info, wid](auto event) {
|
gui_window_ptr->set_key_event_callback([wid](auto event) {
|
||||||
on_key_event(client_info, wid, event);
|
on_key_event(wid, event);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parent_window.event_mask & SubstructureNotifyMask)
|
xEvent event = { .u = {
|
||||||
{
|
.createNotify = {
|
||||||
xEvent event = { .u = {
|
.parent = request.parent,
|
||||||
.createNotify = {
|
.window = request.wid,
|
||||||
.parent = request.parent,
|
.x = request.x,
|
||||||
.window = request.wid,
|
.y = request.y,
|
||||||
.x = request.x,
|
.width = request.width,
|
||||||
.y = request.y,
|
.height = request.height,
|
||||||
.width = request.width,
|
.borderWidth = request.borderWidth,
|
||||||
.height = request.height,
|
.override = false,
|
||||||
.borderWidth = request.borderWidth,
|
}
|
||||||
.override = false,
|
}};
|
||||||
}
|
event.u.u.type = CreateNotify;
|
||||||
}};
|
TRY(parent_window.send_event(event, SubstructureNotifyMask));
|
||||||
event.u.u.type = CreateNotify;
|
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
|
||||||
TRY(encode(client_info.output_buffer, event));
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1482,7 +1455,10 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
background = value;
|
background = value;
|
||||||
break;
|
break;
|
||||||
case 11:
|
case 11:
|
||||||
window.event_mask = value;
|
if (value != 0)
|
||||||
|
TRY(window.event_masks.emplace_or_assign(&client_info, value));
|
||||||
|
else
|
||||||
|
window.event_masks.remove(&client_info);
|
||||||
break;
|
break;
|
||||||
case 14:
|
case 14:
|
||||||
cursor_id = value;
|
cursor_id = value;
|
||||||
|
|
@ -1522,6 +1498,10 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
|
|
||||||
const auto& window = TRY_REF(get_window(client_info, wid, opcode));
|
const auto& window = TRY_REF(get_window(client_info, wid, opcode));
|
||||||
|
|
||||||
|
uint32_t my_event_mask = 0;
|
||||||
|
if (auto it = window.event_masks.find(&client_info); it != window.event_masks.end())
|
||||||
|
my_event_mask = it->value;
|
||||||
|
|
||||||
xGetWindowAttributesReply reply {
|
xGetWindowAttributesReply reply {
|
||||||
.type = X_Reply,
|
.type = X_Reply,
|
||||||
.backingStore = 0,
|
.backingStore = 0,
|
||||||
|
|
@ -1538,8 +1518,8 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
.mapState = static_cast<CARD8>(is_visible(wid) ? 2 : window.mapped),
|
.mapState = static_cast<CARD8>(is_visible(wid) ? 2 : window.mapped),
|
||||||
.override = 0,
|
.override = 0,
|
||||||
.colormap = 0,
|
.colormap = 0,
|
||||||
.allEventMasks = window.event_mask,
|
.allEventMasks = window.full_event_mask(),
|
||||||
.yourEventMask = window.event_mask,
|
.yourEventMask = my_event_mask,
|
||||||
.doNotPropagateMask = 0,
|
.doNotPropagateMask = 0,
|
||||||
};
|
};
|
||||||
TRY(encode(client_info.output_buffer, reply));
|
TRY(encode(client_info.output_buffer, reply));
|
||||||
|
|
@ -1597,7 +1577,6 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
if (was_mapped)
|
if (was_mapped)
|
||||||
TRY(map_window(client_info, wid));
|
TRY(map_window(client_info, wid));
|
||||||
|
|
||||||
if (old_parent.event_mask & SubstructureNotifyMask)
|
|
||||||
{
|
{
|
||||||
xEvent event = { .u = {
|
xEvent event = { .u = {
|
||||||
.reparent = {
|
.reparent = {
|
||||||
|
|
@ -1610,11 +1589,9 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
event.u.u.type = ReparentNotify;
|
event.u.u.type = ReparentNotify;
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
TRY(old_parent.send_event(event, SubstructureNotifyMask));
|
||||||
TRY(encode(client_info.output_buffer, event));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (new_parent.event_mask & SubstructureNotifyMask)
|
|
||||||
{
|
{
|
||||||
xEvent event = { .u = {
|
xEvent event = { .u = {
|
||||||
.reparent = {
|
.reparent = {
|
||||||
|
|
@ -1627,8 +1604,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
event.u.u.type = ReparentNotify;
|
event.u.u.type = ReparentNotify;
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
TRY(new_parent.send_event(event, SubstructureNotifyMask));
|
||||||
TRY(encode(client_info.output_buffer, event));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -1720,9 +1696,6 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
case 3:
|
case 3:
|
||||||
new_height = value;
|
new_height = value;
|
||||||
break;
|
break;
|
||||||
case 11:
|
|
||||||
window.event_mask = value;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
dprintln(" {4h}: {4h}", 1 << i, value);
|
dprintln(" {4h}: {4h}", 1 << i, value);
|
||||||
break;
|
break;
|
||||||
|
|
@ -1762,7 +1735,6 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
|
|
||||||
invalidate_window(request.window, min_x, min_y, max_x - min_x, max_y + min_y);
|
invalidate_window(request.window, min_x, min_y, max_x - min_x, max_y + min_y);
|
||||||
|
|
||||||
if (window.event_mask & StructureNotifyMask)
|
|
||||||
{
|
{
|
||||||
xEvent event = { .u = {
|
xEvent event = { .u = {
|
||||||
.configureNotify = {
|
.configureNotify = {
|
||||||
|
|
@ -1778,15 +1750,13 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
event.u.u.type = ConfigureNotify;
|
event.u.u.type = ConfigureNotify;
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
TRY(window.send_event(event, StructureNotifyMask));
|
||||||
TRY(encode(client_info.output_buffer, event));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& parent_object = *g_objects[window.parent];
|
auto& parent_object = *g_objects[window.parent];
|
||||||
ASSERT(parent_object.type == Object::Type::Window);
|
ASSERT(parent_object.type == Object::Type::Window);
|
||||||
|
|
||||||
auto& parent_window = parent_object.object.get<Object::Window>();
|
auto& parent_window = parent_object.object.get<Object::Window>();
|
||||||
if (parent_window.event_mask & SubstructureNotifyMask)
|
|
||||||
{
|
{
|
||||||
xEvent event = { .u = {
|
xEvent event = { .u = {
|
||||||
.configureNotify = {
|
.configureNotify = {
|
||||||
|
|
@ -1802,8 +1772,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
}
|
}
|
||||||
}};
|
}};
|
||||||
event.u.u.type = ConfigureNotify;
|
event.u.u.type = ConfigureNotify;
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
TRY(parent_window.send_event(event, SubstructureNotifyMask));
|
||||||
TRY(encode(client_info.output_buffer, event));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
@ -2019,20 +1988,16 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.event_mask & PropertyChangeMask)
|
xEvent event = { .u = {
|
||||||
{
|
.property = {
|
||||||
xEvent event = { .u = {
|
.window = request.window,
|
||||||
.property = {
|
.atom = request.property,
|
||||||
.window = request.window,
|
.time = static_cast<CARD32>(time(nullptr)),
|
||||||
.atom = request.property,
|
.state = PropertyNewValue,
|
||||||
.time = static_cast<CARD32>(time(nullptr)),
|
}
|
||||||
.state = PropertyNewValue,
|
}};
|
||||||
}
|
event.u.u.type = PropertyNotify;
|
||||||
}};
|
TRY(window.send_event(event, PropertyChangeMask));
|
||||||
event.u.u.type = PropertyNotify;
|
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
|
||||||
TRY(encode(client_info.output_buffer, event));
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -2052,20 +2017,16 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
|
|
||||||
window.properties.remove(it);
|
window.properties.remove(it);
|
||||||
|
|
||||||
if (window.event_mask & PropertyChangeMask)
|
xEvent event = { .u = {
|
||||||
{
|
.property = {
|
||||||
xEvent event = { .u = {
|
.window = request.window,
|
||||||
.property = {
|
.atom = request.property,
|
||||||
.window = request.window,
|
.time = static_cast<CARD32>(time(nullptr)),
|
||||||
.atom = request.property,
|
.state = PropertyDelete,
|
||||||
.time = static_cast<CARD32>(time(nullptr)),
|
}
|
||||||
.state = PropertyDelete,
|
}};
|
||||||
}
|
event.u.u.type = PropertyNotify;
|
||||||
}};
|
TRY(window.send_event(event, PropertyChangeMask));
|
||||||
event.u.u.type = PropertyNotify;
|
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
|
||||||
TRY(encode(client_info.output_buffer, event));
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -2138,20 +2099,16 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
{
|
{
|
||||||
window.properties.remove(it);
|
window.properties.remove(it);
|
||||||
|
|
||||||
if (window.event_mask & PropertyChangeMask)
|
xEvent event = { .u = {
|
||||||
{
|
.property = {
|
||||||
xEvent event = { .u = {
|
.window = request.window,
|
||||||
.property = {
|
.atom = request.property,
|
||||||
.window = request.window,
|
.time = static_cast<CARD32>(time(nullptr)),
|
||||||
.atom = request.property,
|
.state = PropertyDelete,
|
||||||
.time = static_cast<CARD32>(time(nullptr)),
|
}
|
||||||
.state = PropertyDelete,
|
}};
|
||||||
}
|
event.u.u.type = PropertyNotify;
|
||||||
}};
|
TRY(window.send_event(event, PropertyChangeMask));
|
||||||
event.u.u.type = PropertyNotify;
|
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
|
||||||
TRY(encode(client_info.output_buffer, event));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,6 @@ struct Object
|
||||||
int32_t y { 0 };
|
int32_t y { 0 };
|
||||||
int32_t cursor_x { -1 };
|
int32_t cursor_x { -1 };
|
||||||
int32_t cursor_y { -1 };
|
int32_t cursor_y { -1 };
|
||||||
uint32_t event_mask { 0 };
|
|
||||||
WINDOW parent;
|
WINDOW parent;
|
||||||
CURSOR cursor;
|
CURSOR cursor;
|
||||||
CARD16 c_class;
|
CARD16 c_class;
|
||||||
|
|
@ -78,6 +77,8 @@ struct Object
|
||||||
LibGUI::Texture
|
LibGUI::Texture
|
||||||
> window;
|
> window;
|
||||||
|
|
||||||
|
BAN::HashMap<Client*, uint32_t> event_masks;
|
||||||
|
|
||||||
BAN::HashMap<ATOM, Property> properties;
|
BAN::HashMap<ATOM, Property> properties;
|
||||||
|
|
||||||
LibGUI::Texture& texture()
|
LibGUI::Texture& texture()
|
||||||
|
|
@ -97,6 +98,9 @@ struct Object
|
||||||
return window.get<BAN::UniqPtr<LibGUI::Window>>()->texture();
|
return window.get<BAN::UniqPtr<LibGUI::Window>>()->texture();
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t full_event_mask() const;
|
||||||
|
BAN::ErrorOr<void> send_event(xEvent event, uint32_t event_mask);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Pixmap
|
struct Pixmap
|
||||||
|
|
|
||||||
|
|
@ -277,6 +277,16 @@ int main()
|
||||||
|
|
||||||
dprintln("client {} disconnected", client_fd);
|
dprintln("client {} disconnected", client_fd);
|
||||||
|
|
||||||
|
// FIXME: store selected events on client so we dont
|
||||||
|
// have to loop over all objects
|
||||||
|
for (auto& [_, object] : g_objects)
|
||||||
|
{
|
||||||
|
if (object->type != Object::Type::Window)
|
||||||
|
continue;
|
||||||
|
auto& window = object->object.get<Object::Window>();
|
||||||
|
window.event_masks.remove(&client_info);
|
||||||
|
}
|
||||||
|
|
||||||
for (auto id : client_info.objects)
|
for (auto id : client_info.objects)
|
||||||
{
|
{
|
||||||
auto it = g_objects.find(id);
|
auto it = g_objects.find(id);
|
||||||
|
|
@ -332,7 +342,8 @@ int main()
|
||||||
MUST(BAN::UniqPtr<Object>::create(Object {
|
MUST(BAN::UniqPtr<Object>::create(Object {
|
||||||
.type = Object::Type::Window,
|
.type = Object::Type::Window,
|
||||||
.object = Object::Window {
|
.object = Object::Window {
|
||||||
.event_mask = 0,
|
.mapped = true,
|
||||||
|
.parent = None,
|
||||||
.c_class = InputOutput,
|
.c_class = InputOutput,
|
||||||
.window = {},
|
.window = {},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue