Compare commits
4 Commits
aa70815f5f
...
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 (;;)
|
||||
{
|
||||
if (wid == g_root.windowId)
|
||||
return;
|
||||
|
||||
auto& object = *g_objects[wid];
|
||||
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 const CARD32 WM_CLASS = g_atoms_name_to_id["WM_CLASS"_sv];
|
||||
|
||||
auto& object = *g_objects[wid];
|
||||
ASSERT(object.type == Object::Type::Window);
|
||||
|
||||
auto& window = object.object.get<Object::Window>();
|
||||
if (window.mapped)
|
||||
return {};
|
||||
window.mapped = true;
|
||||
|
||||
if (window.parent == g_root.windowId)
|
||||
{
|
||||
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);
|
||||
window.platform_window = TRY(g_platform_ops.create_window(
|
||||
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)
|
||||
pixel = window.background;
|
||||
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));
|
||||
|
||||
int32_t root_x, root_y;
|
||||
int32_t event_x, event_y;
|
||||
root_x = event_x = window.cursor_x;
|
||||
root_y = event_y = window.cursor_y;
|
||||
|
||||
const auto child_wid = find_child_window(wid, event_x, event_y);
|
||||
WINDOW child_wid { None };
|
||||
for (auto wid_ : window.children)
|
||||
{
|
||||
const auto& child_window = g_objects[wid_]->object.get<Object::Window>();
|
||||
if (!child_window.hovered)
|
||||
continue;
|
||||
child_wid = wid_;
|
||||
break;
|
||||
}
|
||||
|
||||
xQueryPointerReply reply {
|
||||
.type = X_Reply,
|
||||
@@ -1945,11 +1958,11 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
.sequenceNumber = client_info.sequence,
|
||||
.length = 0,
|
||||
.root = g_root.windowId,
|
||||
.child = static_cast<CARD32>(child_wid == wid ? None : child_wid),
|
||||
.rootX = static_cast<INT16>(root_x),
|
||||
.rootY = static_cast<INT16>(root_y),
|
||||
.winX = static_cast<INT16>(event_x),
|
||||
.winY = static_cast<INT16>(event_y),
|
||||
.child = static_cast<CARD32>(child_wid),
|
||||
.rootX = static_cast<INT16>(window.cursor_x), // FIXME
|
||||
.rootY = static_cast<INT16>(window.cursor_y), // FIXME
|
||||
.winX = static_cast<INT16>(window.cursor_x),
|
||||
.winY = static_cast<INT16>(window.cursor_y),
|
||||
.mask = static_cast<KeyButMask>(g_keymask | g_butmask),
|
||||
};
|
||||
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;
|
||||
for (const auto wid : new_child_path)
|
||||
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)
|
||||
@@ -464,24 +479,17 @@ void on_mouse_move_event(WINDOW wid, int32_t x, int32_t 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);
|
||||
auto& old_window = it->value->object.get<Object::Window>();
|
||||
|
||||
send_enter_and_leave_events(old_wid, old_window.cursor_x, old_window.cursor_y, wid, x, y);
|
||||
|
||||
old_wid = wid;
|
||||
send_enter_and_leave_events(s_current_top_level_window, old_window.cursor_x, old_window.cursor_y, wid, x, y);
|
||||
}
|
||||
|
||||
s_current_top_level_window = wid;
|
||||
|
||||
update_cursor_position_recursive(wid, x, y);
|
||||
|
||||
// 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_focus_event(WINDOW wid, bool focused);
|
||||
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_button_event(WINDOW wid, uint8_t xbutton, bool pressed);
|
||||
|
||||
@@ -215,6 +215,9 @@ static void sdl2_poll_events(void*)
|
||||
case SDL_WINDOWEVENT_RESTORED:
|
||||
on_window_fullscreen_event(window.wid, false);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_LEAVE:
|
||||
on_window_leave_event(window.wid);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -290,6 +290,18 @@ int main()
|
||||
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)
|
||||
{
|
||||
auto it = g_objects.find(id);
|
||||
@@ -304,14 +316,13 @@ int main()
|
||||
case Object::Type::Pixmap:
|
||||
case Object::Type::GraphicsContext:
|
||||
case Object::Type::Font:
|
||||
case Object::Type::Window:
|
||||
break;
|
||||
case Object::Type::Window:
|
||||
ASSERT_NOT_REACHED();
|
||||
case Object::Type::Extension:
|
||||
{
|
||||
auto& extension = object.object.get<Object::Extension>();
|
||||
extension.destructor(extension);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_objects.remove(it);
|
||||
|
||||
Reference in New Issue
Block a user