LibGUI/WindowServer: Implement window showing/hiding
This commit is contained in:
parent
bbb490b24f
commit
83069e433f
|
@ -295,6 +295,10 @@ namespace LibGUI
|
||||||
m_resize_window_event_callback();
|
m_resize_window_event_callback();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case PacketType::WindowShownEvent:
|
||||||
|
if (m_window_shown_event_callback)
|
||||||
|
m_window_shown_event_callback(TRY_OR_BREAK(EventPacket::WindowShownEvent::deserialize(packet_data.span())).event);
|
||||||
|
break;
|
||||||
case PacketType::KeyEvent:
|
case PacketType::KeyEvent:
|
||||||
if (m_key_event_callback)
|
if (m_key_event_callback)
|
||||||
m_key_event_callback(TRY_OR_BREAK(EventPacket::KeyEvent::deserialize(packet_data.span())).event);
|
m_key_event_callback(TRY_OR_BREAK(EventPacket::KeyEvent::deserialize(packet_data.span())).event);
|
||||||
|
|
|
@ -172,6 +172,7 @@ namespace LibGUI
|
||||||
DestroyWindowEvent,
|
DestroyWindowEvent,
|
||||||
CloseWindowEvent,
|
CloseWindowEvent,
|
||||||
ResizeWindowEvent,
|
ResizeWindowEvent,
|
||||||
|
WindowShownEvent,
|
||||||
KeyEvent,
|
KeyEvent,
|
||||||
MouseButtonEvent,
|
MouseButtonEvent,
|
||||||
MouseMoveEvent,
|
MouseMoveEvent,
|
||||||
|
@ -189,6 +190,7 @@ namespace LibGUI
|
||||||
bool rounded_corners;
|
bool rounded_corners;
|
||||||
bool alpha_channel;
|
bool alpha_channel;
|
||||||
bool resizable;
|
bool resizable;
|
||||||
|
bool shown;
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_PACKET(
|
DEFINE_PACKET(
|
||||||
|
@ -271,6 +273,14 @@ namespace LibGUI
|
||||||
long, smo_key
|
long, smo_key
|
||||||
);
|
);
|
||||||
|
|
||||||
|
DEFINE_PACKET_EXTRA(
|
||||||
|
WindowShownEvent,
|
||||||
|
struct event_t {
|
||||||
|
bool shown;
|
||||||
|
},
|
||||||
|
event_t, event
|
||||||
|
);
|
||||||
|
|
||||||
DEFINE_PACKET_EXTRA(
|
DEFINE_PACKET_EXTRA(
|
||||||
KeyEvent,
|
KeyEvent,
|
||||||
using event_t = LibInput::KeyEvent,
|
using event_t = LibInput::KeyEvent,
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace LibGUI
|
||||||
.rounded_corners = true,
|
.rounded_corners = true,
|
||||||
.alpha_channel = false,
|
.alpha_channel = false,
|
||||||
.resizable = false,
|
.resizable = false,
|
||||||
|
.shown = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -66,6 +67,7 @@ namespace LibGUI
|
||||||
void set_mouse_button_event_callback(BAN::Function<void(EventPacket::MouseButtonEvent::event_t)> callback) { m_mouse_button_event_callback = callback; }
|
void set_mouse_button_event_callback(BAN::Function<void(EventPacket::MouseButtonEvent::event_t)> callback) { m_mouse_button_event_callback = callback; }
|
||||||
void set_mouse_move_event_callback(BAN::Function<void(EventPacket::MouseMoveEvent::event_t)> callback) { m_mouse_move_event_callback = callback; }
|
void set_mouse_move_event_callback(BAN::Function<void(EventPacket::MouseMoveEvent::event_t)> callback) { m_mouse_move_event_callback = callback; }
|
||||||
void set_mouse_scroll_event_callback(BAN::Function<void(EventPacket::MouseScrollEvent::event_t)> callback) { m_mouse_scroll_event_callback = callback; }
|
void set_mouse_scroll_event_callback(BAN::Function<void(EventPacket::MouseScrollEvent::event_t)> callback) { m_mouse_scroll_event_callback = callback; }
|
||||||
|
void set_window_shown_event_callback(BAN::Function<void(EventPacket::WindowShownEvent::event_t)> callback) { m_window_shown_event_callback = callback; }
|
||||||
|
|
||||||
int server_fd() const { return m_server_fd; }
|
int server_fd() const { return m_server_fd; }
|
||||||
|
|
||||||
|
@ -96,6 +98,7 @@ namespace LibGUI
|
||||||
BAN::Function<void()> m_socket_error_callback;
|
BAN::Function<void()> m_socket_error_callback;
|
||||||
BAN::Function<void()> m_close_window_event_callback;
|
BAN::Function<void()> m_close_window_event_callback;
|
||||||
BAN::Function<void()> m_resize_window_event_callback;
|
BAN::Function<void()> m_resize_window_event_callback;
|
||||||
|
BAN::Function<void(EventPacket::WindowShownEvent::event_t)> m_window_shown_event_callback;
|
||||||
BAN::Function<void(EventPacket::KeyEvent::event_t)> m_key_event_callback;
|
BAN::Function<void(EventPacket::KeyEvent::event_t)> m_key_event_callback;
|
||||||
BAN::Function<void(EventPacket::MouseButtonEvent::event_t)> m_mouse_button_event_callback;
|
BAN::Function<void(EventPacket::MouseButtonEvent::event_t)> m_mouse_button_event_callback;
|
||||||
BAN::Function<void(EventPacket::MouseMoveEvent::event_t)> m_mouse_move_event_callback;
|
BAN::Function<void(EventPacket::MouseMoveEvent::event_t)> m_mouse_move_event_callback;
|
||||||
|
|
|
@ -108,21 +108,16 @@ void WindowServer::on_window_invalidate(int fd, const LibGUI::WindowPacket::Wind
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<Window> target_window;
|
auto target_window = find_window_with_fd(fd);
|
||||||
for (auto& window : m_client_windows)
|
|
||||||
{
|
|
||||||
if (window->client_fd() != fd)
|
|
||||||
continue;
|
|
||||||
target_window = window;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!target_window)
|
if (!target_window)
|
||||||
{
|
{
|
||||||
dwarnln("client tried to invalidate window while not owning a window");
|
dwarnln("client tried to invalidate window while not owning a window");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!target_window->get_attributes().shown)
|
||||||
|
return;
|
||||||
|
|
||||||
invalidate({
|
invalidate({
|
||||||
target_window->client_x() + static_cast<int32_t>(packet.x),
|
target_window->client_x() + static_cast<int32_t>(packet.x),
|
||||||
target_window->client_y() + static_cast<int32_t>(packet.y),
|
target_window->client_y() + static_cast<int32_t>(packet.y),
|
||||||
|
@ -140,15 +135,7 @@ void WindowServer::on_window_set_position(int fd, const LibGUI::WindowPacket::Wi
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<Window> target_window;
|
auto target_window = find_window_with_fd(fd);
|
||||||
for (auto& window : m_client_windows)
|
|
||||||
{
|
|
||||||
if (window->client_fd() != fd)
|
|
||||||
continue;
|
|
||||||
target_window = window;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!target_window)
|
if (!target_window)
|
||||||
{
|
{
|
||||||
dwarnln("client tried to set window position while not owning a window");
|
dwarnln("client tried to set window position while not owning a window");
|
||||||
|
@ -160,44 +147,56 @@ void WindowServer::on_window_set_position(int fd, const LibGUI::WindowPacket::Wi
|
||||||
.x = packet.x,
|
.x = packet.x,
|
||||||
.y = packet.y,
|
.y = packet.y,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!target_window->get_attributes().shown)
|
||||||
|
return;
|
||||||
|
|
||||||
const auto new_client_area = target_window->full_area();
|
const auto new_client_area = target_window->full_area();
|
||||||
invalidate(new_client_area.get_bounding_box(old_client_area));
|
invalidate(new_client_area.get_bounding_box(old_client_area));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowServer::on_window_set_attributes(int fd, const LibGUI::WindowPacket::WindowSetAttributes& packet)
|
void WindowServer::on_window_set_attributes(int fd, const LibGUI::WindowPacket::WindowSetAttributes& packet)
|
||||||
{
|
{
|
||||||
BAN::RefPtr<Window> target_window;
|
auto target_window = find_window_with_fd(fd);
|
||||||
for (auto& window : m_client_windows)
|
|
||||||
{
|
|
||||||
if (window->client_fd() != fd)
|
|
||||||
continue;
|
|
||||||
target_window = window;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!target_window)
|
if (!target_window)
|
||||||
{
|
{
|
||||||
dwarnln("client tried to set window attributes while not owning a window");
|
dwarnln("client tried to set window attributes while not owning a window");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool send_shown_event = target_window->get_attributes().shown != packet.attributes.shown;
|
||||||
|
|
||||||
const auto old_client_area = target_window->full_area();
|
const auto old_client_area = target_window->full_area();
|
||||||
target_window->set_attributes(packet.attributes);
|
target_window->set_attributes(packet.attributes);
|
||||||
const auto new_client_area = target_window->full_area();
|
const auto new_client_area = target_window->full_area();
|
||||||
invalidate(new_client_area.get_bounding_box(old_client_area));
|
invalidate(new_client_area.get_bounding_box(old_client_area));
|
||||||
|
|
||||||
if (!packet.attributes.focusable && m_focused_window == target_window)
|
if ((!packet.attributes.focusable || !packet.attributes.shown) && m_focused_window == target_window)
|
||||||
{
|
{
|
||||||
m_focused_window = nullptr;
|
m_focused_window = nullptr;
|
||||||
|
if (m_state == State::Moving || m_state == State::Resizing)
|
||||||
|
m_state = State::Normal;
|
||||||
for (size_t i = m_client_windows.size(); i > 0; i--)
|
for (size_t i = m_client_windows.size(); i > 0; i--)
|
||||||
{
|
{
|
||||||
if (auto& window = m_client_windows[i - 1]; window->get_attributes().focusable)
|
auto& window = m_client_windows[i - 1];
|
||||||
|
if (auto attributes = window->get_attributes(); attributes.focusable && attributes.shown)
|
||||||
{
|
{
|
||||||
set_focused_window(window);
|
set_focused_window(window);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!send_shown_event)
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto event_packet = LibGUI::EventPacket::WindowShownEvent {
|
||||||
|
.event = {
|
||||||
|
.shown = target_window->get_attributes().shown,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
if (auto ret = event_packet.send_serialized(target_window->client_fd()); ret.is_error())
|
||||||
|
dwarnln("could not send window shown event: {}", ret.error());
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowServer::on_window_set_mouse_capture(int fd, const LibGUI::WindowPacket::WindowSetMouseCapture& packet)
|
void WindowServer::on_window_set_mouse_capture(int fd, const LibGUI::WindowPacket::WindowSetMouseCapture& packet)
|
||||||
|
@ -210,20 +209,17 @@ void WindowServer::on_window_set_mouse_capture(int fd, const LibGUI::WindowPacke
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefPtr<Window> target_window;
|
auto target_window = find_window_with_fd(fd);
|
||||||
for (auto& window : m_client_windows)
|
|
||||||
{
|
|
||||||
if (window->client_fd() != fd)
|
|
||||||
continue;
|
|
||||||
target_window = window;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!target_window)
|
if (!target_window)
|
||||||
{
|
{
|
||||||
dwarnln("client tried to set mouse capture while not owning a window");
|
dwarnln("client tried to set mouse capture while not owning a window");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!target_window->get_attributes().shown)
|
||||||
|
{
|
||||||
|
dwarnln("client tried to set mouse capture while hidden window");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (packet.captured == m_is_mouse_captured)
|
if (packet.captured == m_is_mouse_captured)
|
||||||
return;
|
return;
|
||||||
|
@ -235,15 +231,7 @@ void WindowServer::on_window_set_mouse_capture(int fd, const LibGUI::WindowPacke
|
||||||
|
|
||||||
void WindowServer::on_window_set_size(int fd, const LibGUI::WindowPacket::WindowSetSize& packet)
|
void WindowServer::on_window_set_size(int fd, const LibGUI::WindowPacket::WindowSetSize& packet)
|
||||||
{
|
{
|
||||||
BAN::RefPtr<Window> target_window;
|
auto target_window = find_window_with_fd(fd);
|
||||||
for (auto& window : m_client_windows)
|
|
||||||
{
|
|
||||||
if (window->client_fd() != fd)
|
|
||||||
continue;
|
|
||||||
target_window = window;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!target_window)
|
if (!target_window)
|
||||||
{
|
{
|
||||||
dwarnln("client tried to set window size while not owning a window");
|
dwarnln("client tried to set window size while not owning a window");
|
||||||
|
@ -258,20 +246,15 @@ void WindowServer::on_window_set_size(int fd, const LibGUI::WindowPacket::Window
|
||||||
if (!resize_window(target_window, width, height))
|
if (!resize_window(target_window, width, height))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (!target_window->get_attributes().shown)
|
||||||
|
return;
|
||||||
|
|
||||||
invalidate(target_window->full_area().get_bounding_box(old_area));
|
invalidate(target_window->full_area().get_bounding_box(old_area));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowServer::on_window_set_min_size(int fd, const LibGUI::WindowPacket::WindowSetMinSize& packet)
|
void WindowServer::on_window_set_min_size(int fd, const LibGUI::WindowPacket::WindowSetMinSize& packet)
|
||||||
{
|
{
|
||||||
BAN::RefPtr<Window> target_window;
|
auto target_window = find_window_with_fd(fd);
|
||||||
for (auto& window : m_client_windows)
|
|
||||||
{
|
|
||||||
if (window->client_fd() != fd)
|
|
||||||
continue;
|
|
||||||
target_window = window;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!target_window)
|
if (!target_window)
|
||||||
{
|
{
|
||||||
dwarnln("client tried to set window min size while not owning a window");
|
dwarnln("client tried to set window min size while not owning a window");
|
||||||
|
@ -284,15 +267,7 @@ void WindowServer::on_window_set_min_size(int fd, const LibGUI::WindowPacket::Wi
|
||||||
|
|
||||||
void WindowServer::on_window_set_max_size(int fd, const LibGUI::WindowPacket::WindowSetMaxSize& packet)
|
void WindowServer::on_window_set_max_size(int fd, const LibGUI::WindowPacket::WindowSetMaxSize& packet)
|
||||||
{
|
{
|
||||||
BAN::RefPtr<Window> target_window;
|
auto target_window = find_window_with_fd(fd);
|
||||||
for (auto& window : m_client_windows)
|
|
||||||
{
|
|
||||||
if (window->client_fd() != fd)
|
|
||||||
continue;
|
|
||||||
target_window = window;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!target_window)
|
if (!target_window)
|
||||||
{
|
{
|
||||||
dwarnln("client tried to set window max size while not owning a window");
|
dwarnln("client tried to set window max size while not owning a window");
|
||||||
|
@ -328,20 +303,17 @@ void WindowServer::on_window_set_fullscreen(int fd, const LibGUI::WindowPacket::
|
||||||
if (!packet.fullscreen)
|
if (!packet.fullscreen)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BAN::RefPtr<Window> target_window;
|
auto target_window = find_window_with_fd(fd);
|
||||||
for (auto& window : m_client_windows)
|
|
||||||
{
|
|
||||||
if (window->client_fd() != fd)
|
|
||||||
continue;
|
|
||||||
target_window = window;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!target_window)
|
if (!target_window)
|
||||||
{
|
{
|
||||||
dwarnln("client tried to set window fullscreen while not owning a window");
|
dwarnln("client tried to set window fullscreen while not owning a window");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!target_window->get_attributes().shown)
|
||||||
|
{
|
||||||
|
dwarnln("client tried to set a hidden window fullscreen");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (target_window->get_attributes().resizable)
|
if (target_window->get_attributes().resizable)
|
||||||
{
|
{
|
||||||
|
@ -359,15 +331,7 @@ void WindowServer::on_window_set_fullscreen(int fd, const LibGUI::WindowPacket::
|
||||||
|
|
||||||
void WindowServer::on_window_set_title(int fd, const LibGUI::WindowPacket::WindowSetTitle& packet)
|
void WindowServer::on_window_set_title(int fd, const LibGUI::WindowPacket::WindowSetTitle& packet)
|
||||||
{
|
{
|
||||||
BAN::RefPtr<Window> target_window;
|
auto target_window = find_window_with_fd(fd);
|
||||||
for (auto& window : m_client_windows)
|
|
||||||
{
|
|
||||||
if (window->client_fd() != fd)
|
|
||||||
continue;
|
|
||||||
target_window = window;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!target_window)
|
if (!target_window)
|
||||||
{
|
{
|
||||||
dwarnln("client tried to set window title while not owning a window");
|
dwarnln("client tried to set window title while not owning a window");
|
||||||
|
@ -380,6 +344,9 @@ void WindowServer::on_window_set_title(int fd, const LibGUI::WindowPacket::Windo
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!target_window->get_attributes().shown)
|
||||||
|
return;
|
||||||
|
|
||||||
invalidate(target_window->title_bar_area());
|
invalidate(target_window->title_bar_area());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,7 +475,7 @@ void WindowServer::on_mouse_button(LibInput::MouseButtonEvent event)
|
||||||
if (!event.pressed)
|
if (!event.pressed)
|
||||||
target_window = m_mouse_button_windows[button_idx];
|
target_window = m_mouse_button_windows[button_idx];
|
||||||
for (size_t i = m_client_windows.size(); i > 0 && !target_window; i--)
|
for (size_t i = m_client_windows.size(); i > 0 && !target_window; i--)
|
||||||
if (m_client_windows[i - 1]->full_area().contains(m_cursor))
|
if (m_client_windows[i - 1]->full_area().contains(m_cursor) && m_client_windows[i - 1]->get_attributes().shown)
|
||||||
target_window = m_client_windows[i - 1];
|
target_window = m_client_windows[i - 1];
|
||||||
|
|
||||||
switch (m_state)
|
switch (m_state)
|
||||||
|
@ -652,6 +619,8 @@ void WindowServer::on_mouse_move(LibInput::MouseMoveEvent event)
|
||||||
// TODO: Really no need to loop over every window
|
// TODO: Really no need to loop over every window
|
||||||
for (auto& window : m_client_windows)
|
for (auto& window : m_client_windows)
|
||||||
{
|
{
|
||||||
|
if (!window->get_attributes().shown)
|
||||||
|
continue;
|
||||||
auto title_bar = window->title_bar_area();
|
auto title_bar = window->title_bar_area();
|
||||||
if (title_bar.get_overlap(old_cursor).has_value() || title_bar.get_overlap(new_cursor).has_value())
|
if (title_bar.get_overlap(old_cursor).has_value() || title_bar.get_overlap(new_cursor).has_value())
|
||||||
invalidate(title_bar);
|
invalidate(title_bar);
|
||||||
|
@ -895,6 +864,8 @@ void WindowServer::invalidate(Rectangle area)
|
||||||
for (auto& pwindow : m_client_windows)
|
for (auto& pwindow : m_client_windows)
|
||||||
{
|
{
|
||||||
auto& window = *pwindow;
|
auto& window = *pwindow;
|
||||||
|
if (!window.get_attributes().shown)
|
||||||
|
continue;
|
||||||
|
|
||||||
const Rectangle fast_areas[] {
|
const Rectangle fast_areas[] {
|
||||||
{
|
{
|
||||||
|
@ -1269,6 +1240,17 @@ Rectangle WindowServer::resize_area(Position cursor) const
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::RefPtr<Window> WindowServer::find_window_with_fd(int fd)
|
||||||
|
{
|
||||||
|
for (auto window : m_client_windows)
|
||||||
|
{
|
||||||
|
if (window->client_fd() != fd)
|
||||||
|
continue;
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
bool WindowServer::resize_window(BAN::RefPtr<Window> window, uint32_t width, uint32_t height) const
|
bool WindowServer::resize_window(BAN::RefPtr<Window> window, uint32_t width, uint32_t height) const
|
||||||
{
|
{
|
||||||
if (auto ret = window->resize(width, height); ret.is_error())
|
if (auto ret = window->resize(width, height); ret.is_error())
|
||||||
|
|
|
@ -66,6 +66,8 @@ private:
|
||||||
|
|
||||||
bool resize_window(BAN::RefPtr<Window> window, uint32_t width, uint32_t height) const;
|
bool resize_window(BAN::RefPtr<Window> window, uint32_t width, uint32_t height) const;
|
||||||
|
|
||||||
|
BAN::RefPtr<Window> find_window_with_fd(int fd);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct RangeList
|
struct RangeList
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue