Compare commits
4 Commits
main
...
16d57d0194
| Author | SHA1 | Date | |
|---|---|---|---|
| 16d57d0194 | |||
| f1a0738d13 | |||
| b81ff29e00 | |||
| 0dc88d09bf |
@@ -374,6 +374,9 @@ void invalidate_window(WINDOW wid, int32_t x, int32_t y, int32_t w, int32_t h)
|
|||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
if (wid == g_root.windowId)
|
||||||
|
return;
|
||||||
|
|
||||||
auto& object = *g_objects[wid];
|
auto& object = *g_objects[wid];
|
||||||
ASSERT(object.type == Object::Type::Window);
|
ASSERT(object.type == Object::Type::Window);
|
||||||
|
|
||||||
@@ -506,17 +509,26 @@ transitient_for_done:
|
|||||||
|
|
||||||
static BAN::ErrorOr<void> map_window(Client& client_info, WINDOW wid)
|
static BAN::ErrorOr<void> map_window(Client& client_info, WINDOW wid)
|
||||||
{
|
{
|
||||||
|
static const CARD32 WM_CLASS = g_atoms_name_to_id["WM_CLASS"_sv];
|
||||||
|
|
||||||
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.mapped)
|
if (window.mapped)
|
||||||
return {};
|
return {};
|
||||||
|
window.mapped = true;
|
||||||
|
|
||||||
if (window.parent == g_root.windowId)
|
if (window.parent == g_root.windowId)
|
||||||
{
|
{
|
||||||
ASSERT(!window.platform_window);
|
ASSERT(!window.platform_window);
|
||||||
|
|
||||||
|
// NOTE: This is not perfect but seems to work.
|
||||||
|
// This is used to not display "dummy" event windows
|
||||||
|
// that should not be visible.
|
||||||
|
if (!window.properties.contains(WM_CLASS))
|
||||||
|
return {};
|
||||||
|
|
||||||
auto info = get_plaform_window_info(window);
|
auto info = get_plaform_window_info(window);
|
||||||
window.platform_window = TRY(g_platform_ops.create_window(
|
window.platform_window = TRY(g_platform_ops.create_window(
|
||||||
info.transient_for,
|
info.transient_for,
|
||||||
@@ -529,8 +541,6 @@ static BAN::ErrorOr<void> map_window(Client& client_info, WINDOW wid)
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
window.mapped = true;
|
|
||||||
|
|
||||||
for (auto& pixel : window.pixels)
|
for (auto& pixel : window.pixels)
|
||||||
pixel = window.background;
|
pixel = window.background;
|
||||||
invalidate_window(wid, 0, 0, window.width, window.height);
|
invalidate_window(wid, 0, 0, window.width, window.height);
|
||||||
@@ -1932,12 +1942,15 @@ 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));
|
||||||
|
|
||||||
int32_t root_x, root_y;
|
WINDOW child_wid { None };
|
||||||
int32_t event_x, event_y;
|
for (auto wid_ : window.children)
|
||||||
root_x = event_x = window.cursor_x;
|
{
|
||||||
root_y = event_y = window.cursor_y;
|
const auto& child_window = g_objects[wid_]->object.get<Object::Window>();
|
||||||
|
if (!child_window.hovered)
|
||||||
const auto child_wid = find_child_window(wid, event_x, event_y);
|
continue;
|
||||||
|
child_wid = wid_;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
xQueryPointerReply reply {
|
xQueryPointerReply reply {
|
||||||
.type = X_Reply,
|
.type = X_Reply,
|
||||||
@@ -1945,11 +1958,11 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
|||||||
.sequenceNumber = client_info.sequence,
|
.sequenceNumber = client_info.sequence,
|
||||||
.length = 0,
|
.length = 0,
|
||||||
.root = g_root.windowId,
|
.root = g_root.windowId,
|
||||||
.child = static_cast<CARD32>(child_wid == wid ? None : child_wid),
|
.child = static_cast<CARD32>(child_wid),
|
||||||
.rootX = static_cast<INT16>(root_x),
|
.rootX = static_cast<INT16>(window.cursor_x), // FIXME
|
||||||
.rootY = static_cast<INT16>(root_y),
|
.rootY = static_cast<INT16>(window.cursor_y), // FIXME
|
||||||
.winX = static_cast<INT16>(event_x),
|
.winX = static_cast<INT16>(window.cursor_x),
|
||||||
.winY = static_cast<INT16>(event_y),
|
.winY = static_cast<INT16>(window.cursor_y),
|
||||||
.mask = static_cast<KeyButMask>(g_keymask | g_butmask),
|
.mask = static_cast<KeyButMask>(g_keymask | g_butmask),
|
||||||
};
|
};
|
||||||
TRY(encode(client_info.output_buffer, reply));
|
TRY(encode(client_info.output_buffer, reply));
|
||||||
|
|||||||
@@ -453,7 +453,22 @@ static void send_enter_and_leave_events(WINDOW old_wid, int32_t old_x, int32_t o
|
|||||||
g_objects[wid]->object.get<Object::Window>().hovered = false;
|
g_objects[wid]->object.get<Object::Window>().hovered = false;
|
||||||
for (const auto wid : new_child_path)
|
for (const auto wid : new_child_path)
|
||||||
g_objects[wid]->object.get<Object::Window>().hovered = true;
|
g_objects[wid]->object.get<Object::Window>().hovered = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WINDOW s_current_top_level_window = None;
|
||||||
|
|
||||||
|
void on_window_leave_event(WINDOW wid)
|
||||||
|
{
|
||||||
|
if (s_current_top_level_window != wid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto& object = *g_objects[wid];
|
||||||
|
ASSERT(object.type == Object::Type::Window);
|
||||||
|
auto& window = object.object.get<Object::Window>();
|
||||||
|
|
||||||
|
send_enter_and_leave_events(wid, window.cursor_x, window.cursor_y, wid, -1, -1);
|
||||||
|
|
||||||
|
s_current_top_level_window = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
void on_mouse_move_event(WINDOW wid, int32_t x, int32_t y)
|
void on_mouse_move_event(WINDOW wid, int32_t x, int32_t y)
|
||||||
@@ -464,24 +479,17 @@ void on_mouse_move_event(WINDOW wid, int32_t x, int32_t y)
|
|||||||
|
|
||||||
update_cursor(wid, x, y);
|
update_cursor(wid, x, y);
|
||||||
|
|
||||||
|
if (auto it = g_objects.find(s_current_top_level_window); it == g_objects.end())
|
||||||
|
send_enter_and_leave_events(wid, -1, -1, wid, x, y);
|
||||||
|
else
|
||||||
{
|
{
|
||||||
static WINDOW old_wid = g_root.windowId;
|
|
||||||
|
|
||||||
auto it = g_objects.find(old_wid);
|
|
||||||
if (it == g_objects.end())
|
|
||||||
{
|
|
||||||
old_wid = g_root.windowId;
|
|
||||||
it = g_objects.find(g_root.windowId);
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT(it->value->type == Object::Type::Window);
|
ASSERT(it->value->type == Object::Type::Window);
|
||||||
auto& old_window = it->value->object.get<Object::Window>();
|
auto& old_window = it->value->object.get<Object::Window>();
|
||||||
|
send_enter_and_leave_events(s_current_top_level_window, old_window.cursor_x, old_window.cursor_y, wid, x, y);
|
||||||
send_enter_and_leave_events(old_wid, old_window.cursor_x, old_window.cursor_y, wid, x, y);
|
|
||||||
|
|
||||||
old_wid = wid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s_current_top_level_window = wid;
|
||||||
|
|
||||||
update_cursor_position_recursive(wid, x, y);
|
update_cursor_position_recursive(wid, x, y);
|
||||||
|
|
||||||
// TODO: optimize with PointerMotionHint
|
// TODO: optimize with PointerMotionHint
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ void on_window_close_event(WINDOW wid);
|
|||||||
void on_window_resize_event(WINDOW wid, uint32_t width, uint32_t height);
|
void on_window_resize_event(WINDOW wid, uint32_t width, uint32_t height);
|
||||||
void on_window_focus_event(WINDOW wid, bool focused);
|
void on_window_focus_event(WINDOW wid, bool focused);
|
||||||
void on_window_fullscreen_event(WINDOW wid, bool is_fullscreen);
|
void on_window_fullscreen_event(WINDOW wid, bool is_fullscreen);
|
||||||
|
void on_window_leave_event(WINDOW wid);
|
||||||
|
|
||||||
void on_mouse_move_event(WINDOW wid, int32_t x, int32_t y);
|
void on_mouse_move_event(WINDOW wid, int32_t x, int32_t y);
|
||||||
void on_mouse_button_event(WINDOW wid, uint8_t xbutton, bool pressed);
|
void on_mouse_button_event(WINDOW wid, uint8_t xbutton, bool pressed);
|
||||||
|
|||||||
@@ -215,6 +215,9 @@ static void sdl2_poll_events(void*)
|
|||||||
case SDL_WINDOWEVENT_RESTORED:
|
case SDL_WINDOWEVENT_RESTORED:
|
||||||
on_window_fullscreen_event(window.wid, false);
|
on_window_fullscreen_event(window.wid, false);
|
||||||
break;
|
break;
|
||||||
|
case SDL_WINDOWEVENT_LEAVE:
|
||||||
|
on_window_leave_event(window.wid);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -290,6 +290,18 @@ int main()
|
|||||||
window.event_masks.remove(&client_info);
|
window.event_masks.remove(&client_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto it = client_info.objects.begin(); it != client_info.objects.end();)
|
||||||
|
{
|
||||||
|
auto obj_it = g_objects.find(*it);
|
||||||
|
if (obj_it == g_objects.end() || obj_it->value->type != Object::Type::Window)
|
||||||
|
it++;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
(void)destroy_window(client_info, *it);
|
||||||
|
it = client_info.objects.begin();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (auto id : client_info.objects)
|
for (auto id : client_info.objects)
|
||||||
{
|
{
|
||||||
auto it = g_objects.find(id);
|
auto it = g_objects.find(id);
|
||||||
@@ -304,14 +316,13 @@ int main()
|
|||||||
case Object::Type::Pixmap:
|
case Object::Type::Pixmap:
|
||||||
case Object::Type::GraphicsContext:
|
case Object::Type::GraphicsContext:
|
||||||
case Object::Type::Font:
|
case Object::Type::Font:
|
||||||
case Object::Type::Window:
|
|
||||||
break;
|
break;
|
||||||
|
case Object::Type::Window:
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
case Object::Type::Extension:
|
case Object::Type::Extension:
|
||||||
{
|
|
||||||
auto& extension = object.object.get<Object::Extension>();
|
auto& extension = object.object.get<Object::Extension>();
|
||||||
extension.destructor(extension);
|
extension.destructor(extension);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
g_objects.remove(it);
|
g_objects.remove(it);
|
||||||
|
|||||||
Reference in New Issue
Block a user