Compare commits

..

No commits in common. "e376c57cdad465085836660bd7779501473a393c" and "3e0dc851c4327052ab4c07c2c9a0b88215fb6bc7" have entirely different histories.

13 changed files with 49 additions and 286 deletions

View File

@ -348,10 +348,6 @@ namespace LibGUI
if (m_window_focus_event_callback) if (m_window_focus_event_callback)
m_window_focus_event_callback(TRY_OR_BREAK(EventPacket::WindowFocusEvent::deserialize(packet_data.span())).event); m_window_focus_event_callback(TRY_OR_BREAK(EventPacket::WindowFocusEvent::deserialize(packet_data.span())).event);
break; break;
case PacketType::WindowFullscreenEvent:
if (m_window_fullscreen_event_callback)
m_window_fullscreen_event_callback(TRY_OR_BREAK(EventPacket::WindowFullscreenEvent::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);

View File

@ -7,6 +7,7 @@
#include <LibInput/KeyEvent.h> #include <LibInput/KeyEvent.h>
#include <LibInput/MouseEvent.h> #include <LibInput/MouseEvent.h>
#include <cstdint>
#include <sys/socket.h> #include <sys/socket.h>
#define FOR_EACH_0(macro) #define FOR_EACH_0(macro)
@ -218,7 +219,6 @@ namespace LibGUI
ResizeWindowEvent, ResizeWindowEvent,
WindowShownEvent, WindowShownEvent,
WindowFocusEvent, WindowFocusEvent,
WindowFullscreenEvent,
KeyEvent, KeyEvent,
MouseButtonEvent, MouseButtonEvent,
MouseMoveEvent, MouseMoveEvent,
@ -345,14 +345,6 @@ namespace LibGUI
event_t, event event_t, event
); );
DEFINE_PACKET_EXTRA(
WindowFullscreenEvent,
struct event_t {
bool fullscreen;
},
event_t, event
);
DEFINE_PACKET_EXTRA( DEFINE_PACKET_EXTRA(
KeyEvent, KeyEvent,
using event_t = LibInput::KeyEvent, using event_t = LibInput::KeyEvent,

View File

@ -2,6 +2,7 @@
#include <BAN/StringView.h> #include <BAN/StringView.h>
#include <cstdint>
#include <stdint.h> #include <stdint.h>
namespace LibFont { class Font; } namespace LibFont { class Font; }

View File

@ -77,7 +77,6 @@ namespace LibGUI
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; } void set_window_shown_event_callback(BAN::Function<void(EventPacket::WindowShownEvent::event_t)> callback) { m_window_shown_event_callback = callback; }
void set_window_focus_event_callback(BAN::Function<void(EventPacket::WindowFocusEvent::event_t)> callback) { m_window_focus_event_callback = callback; } void set_window_focus_event_callback(BAN::Function<void(EventPacket::WindowFocusEvent::event_t)> callback) { m_window_focus_event_callback = callback; }
void set_window_fullscreen_event_callback(BAN::Function<void(EventPacket::WindowFullscreenEvent::event_t)> callback) { m_window_fullscreen_event_callback = callback; }
int server_fd() const { return m_server_fd; } int server_fd() const { return m_server_fd; }
@ -113,7 +112,6 @@ namespace LibGUI
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::WindowShownEvent::event_t)> m_window_shown_event_callback;
BAN::Function<void(EventPacket::WindowFocusEvent::event_t)> m_window_focus_event_callback; BAN::Function<void(EventPacket::WindowFocusEvent::event_t)> m_window_focus_event_callback;
BAN::Function<void(EventPacket::WindowFullscreenEvent::event_t)> m_window_fullscreen_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;

View File

@ -94,7 +94,7 @@ void WindowServer::on_window_create(int fd, const LibGUI::WindowPacket::WindowCr
window_popper.disable(); window_popper.disable();
if (packet.attributes.shown && packet.attributes.focusable && m_state == State::Normal) if (packet.attributes.shown && packet.attributes.focusable)
set_focused_window(window); set_focused_window(window);
else if (m_client_windows.size() > 1) else if (m_client_windows.size() > 1)
BAN::swap(m_client_windows[m_client_windows.size() - 1], m_client_windows[m_client_windows.size() - 2]); BAN::swap(m_client_windows[m_client_windows.size() - 1], m_client_windows[m_client_windows.size() - 2]);
@ -177,14 +177,8 @@ void WindowServer::on_window_set_attributes(int fd, const LibGUI::WindowPacket::
if ((!packet.attributes.focusable || !packet.attributes.shown) && m_focused_window == target_window) if ((!packet.attributes.focusable || !packet.attributes.shown) && m_focused_window == target_window)
{ {
if (m_state == State::Fullscreen && m_focused_window->get_attributes().resizable)
{
if (!resize_window(m_focused_window, m_non_full_screen_rect.width, m_non_full_screen_rect.height))
return;
m_focused_window->set_position({ m_non_full_screen_rect.x, m_non_full_screen_rect.y });
}
m_focused_window = nullptr; m_focused_window = nullptr;
if (m_state == State::Moving || m_state == State::Resizing)
m_state = State::Normal; 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--)
{ {
@ -208,7 +202,7 @@ void WindowServer::on_window_set_attributes(int fd, const LibGUI::WindowPacket::
if (auto ret = event_packet.send_serialized(target_window->client_fd()); ret.is_error()) if (auto ret = event_packet.send_serialized(target_window->client_fd()); ret.is_error())
dwarnln("could not send window shown event: {}", ret.error()); dwarnln("could not send window shown event: {}", ret.error());
if (packet.attributes.focusable && packet.attributes.shown && m_state == State::Normal) if (packet.attributes.focusable && packet.attributes.shown)
set_focused_window(target_window); set_focused_window(target_window);
} }
@ -308,13 +302,6 @@ void WindowServer::on_window_set_fullscreen(int fd, const LibGUI::WindowPacket::
return; return;
m_focused_window->set_position({ m_non_full_screen_rect.x, m_non_full_screen_rect.y }); m_focused_window->set_position({ m_non_full_screen_rect.x, m_non_full_screen_rect.y });
} }
auto event_packet = LibGUI::EventPacket::WindowFullscreenEvent {
.event = { .fullscreen = false }
};
if (auto ret = event_packet.send_serialized(m_focused_window->client_fd()); ret.is_error())
dwarnln("could not send window fullscreen event: {}", ret.error());
m_state = State::Normal; m_state = State::Normal;
invalidate(m_framebuffer.area()); invalidate(m_framebuffer.area());
return; return;
@ -344,12 +331,6 @@ void WindowServer::on_window_set_fullscreen(int fd, const LibGUI::WindowPacket::
m_non_full_screen_rect = old_area; m_non_full_screen_rect = old_area;
} }
auto event_packet = LibGUI::EventPacket::WindowFullscreenEvent {
.event = { .fullscreen = true }
};
if (auto ret = event_packet.send_serialized(target_window->client_fd()); ret.is_error())
dwarnln("could not send window fullscreen event: {}", ret.error());
m_state = State::Fullscreen; m_state = State::Fullscreen;
set_focused_window(target_window); set_focused_window(target_window);
invalidate(m_framebuffer.area()); invalidate(m_framebuffer.area());
@ -505,12 +486,6 @@ void WindowServer::on_key_event(LibInput::KeyEvent event)
m_state = State::Fullscreen; m_state = State::Fullscreen;
} }
auto event_packet = LibGUI::EventPacket::WindowFullscreenEvent {
.event = { .fullscreen = (m_state == State::Fullscreen) }
};
if (auto ret = event_packet.send_serialized(m_focused_window->client_fd()); ret.is_error())
dwarnln("could not send window fullscreen event: {}", ret.error());
invalidate(m_framebuffer.area()); invalidate(m_framebuffer.area());
return; return;
} }

View File

@ -8,7 +8,6 @@
#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>
@ -821,55 +820,6 @@ 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 = g_atoms_name_to_id["WM_PROTOCOLS"_sv];
static CARD32 WM_DELETE_WINDOW = g_atoms_name_to_id["WM_DELETE_WINDOW"_sv];
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]
{
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];
@ -1135,107 +1085,6 @@ 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 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];
auto window_it = g_objects.find(wid);
if (window_it == g_objects.end() || window_it->value->type != Object::Type::Window)
return;
auto& window = window_it->value->object.get<Object::Window>();
window.fullscreen = is_fullscreen;
auto it = window.properties.find(_NET_WM_STATE);
if (it == window.properties.end())
it = MUST(window.properties.emplace(_NET_WM_STATE));
auto& _net_wm_state = it->value;
if (_net_wm_state.type != XA_ATOM || _net_wm_state.format != 32)
_net_wm_state = {};
_net_wm_state.type = XA_ATOM;
_net_wm_state.format = 32;
for (size_t i = 0; i + 4 <= _net_wm_state.data.size(); i += 4)
{
const auto atom = *reinterpret_cast<const CARD32*>(_net_wm_state.data.data() + i);
if (atom != _NET_WM_STATE_FULLSCREEN)
continue;
_net_wm_state.data.remove(i);
_net_wm_state.data.remove(i);
_net_wm_state.data.remove(i);
_net_wm_state.data.remove(i);
i -= 4;
}
if (is_fullscreen)
{
const size_t atom_count = _net_wm_state.data.size() / 4;
MUST(_net_wm_state.data.resize(_net_wm_state.data.size() + 4));
reinterpret_cast<CARD32*>(_net_wm_state.data.data())[atom_count] = _NET_WM_STATE_FULLSCREEN;
}
if (window.event_mask & PropertyChangeMask)
{
xEvent event = { .u = {
.property = {
.window = wid,
.atom = _NET_WM_STATE,
.time = static_cast<CARD32>(time(nullptr)),
.state = PropertyNewValue,
}
}};
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 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];
ASSERT(event.u.u.type == ClientMessage);
const auto type = event.u.clientMessage.u.l.type;
const auto action = event.u.clientMessage.u.l.longs0;
const auto field = event.u.clientMessage.u.l.longs1;
if (type != _NET_WM_STATE || field != _NET_WM_STATE_FULLSCREEN)
return;
auto window_it = g_objects.find(event.u.clientMessage.window);
if (window_it == g_objects.end() || window_it->value->type != Object::Type::Window)
return;
auto& window = window_it->value->object.get<Object::Window>();
if (!window.window.has<BAN::UniqPtr<LibGUI::Window>>())
return;
auto& gui_window = window.window.get<BAN::UniqPtr<LibGUI::Window>>();
switch (action)
{
case 0:
gui_window->set_fullscreen(false);
break;
case 1:
gui_window->set_fullscreen(true);
break;
case 2:
gui_window->set_fullscreen(!window.fullscreen);
break;
}
}
BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet) BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
{ {
const uint8_t opcode = packet[0]; const uint8_t opcode = packet[0];
@ -1393,18 +1242,13 @@ 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([&client_info, wid] { gui_window_ptr->set_close_window_event_callback([]{});
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);
}); });
gui_window_ptr->set_window_focus_event_callback([&client_info, wid](auto event) { gui_window_ptr->set_window_focus_event_callback([&client_info, wid](auto event) {
on_window_focus_event(client_info, wid, event.focused); on_window_focus_event(client_info, wid, event.focused);
}); });
gui_window_ptr->set_window_fullscreen_event_callback([&client_info, wid](auto event) {
on_window_fullscreen_event(client_info, wid, event.fullscreen);
});
gui_window_ptr->set_mouse_move_event_callback([&client_info, wid](auto event) { gui_window_ptr->set_mouse_move_event_callback([&client_info, wid](auto event) {
on_mouse_move_event(client_info, wid, event.x, event.y); on_mouse_move_event(client_info, wid, event.x, event.y);
}); });
@ -2292,34 +2136,9 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
dprintln(" destination: {}", request.destination); dprintln(" destination: {}", request.destination);
dprintln(" eventMask: {}", request.eventMask); dprintln(" eventMask: {}", request.eventMask);
WINDOW wid = request.destination; auto event = request.event;
if (wid == PointerWindow || wid == InputFocus) event.u.u.sequenceNumber = client_info.sequence;
wid = s_focus_window; TRY(encode(client_info.output_buffer, event));
(void)TRY_REF(get_window(client_info, wid, X_SendEvent));
Client* target_client = nullptr;
for (auto& [_, thingy] : g_epoll_thingies)
{
if (thingy.type != EpollThingy::Type::Client)
continue;
auto& other_client = thingy.value.get<Client>();
if (!other_client.objects.contains(wid))
continue;
target_client = &other_client;
break;
}
// FIXME: propagate, event masks
if (target_client)
{
request.event.u.u.sequenceNumber = target_client->sequence;
TRY(encode(target_client->output_buffer, request.event));
}
if (request.destination == g_root.windowId && request.event.u.u.type == ClientMessage)
on_root_client_message(request.event);
break; break;
} }

View File

@ -33,12 +33,6 @@ banan_link_library(xbanan libdeflate)
banan_link_library(xbanan libgui) banan_link_library(xbanan libgui)
banan_link_library(xbanan libinput) banan_link_library(xbanan libinput)
target_compile_options(xbanan PRIVATE -Wall -Wextra) target_compile_options(xbanan PRIVATE -Wall -Wextra -Wno-sign-compare -Wno-missing-field-initializers)
target_compile_options(xbanan PRIVATE
-Wno-sign-compare
-Wno-missing-field-initializers
-Wno-unused-variable
-Wno-unused-but-set-variable
)
install(TARGETS xbanan OPTIONAL) install(TARGETS xbanan OPTIONAL)

View File

@ -62,7 +62,6 @@ struct Object
{ {
bool mapped { false }; bool mapped { false };
bool focused { false }; bool focused { false };
bool fullscreen { false };
uint8_t depth { 0 }; uint8_t depth { 0 };
int32_t x { 0 }; int32_t x { 0 };
int32_t y { 0 }; int32_t y { 0 };

View File

@ -180,8 +180,8 @@ int main()
} }
#define APPEND_ATOM(name) do { \ #define APPEND_ATOM(name) do { \
MUST(g_atoms_id_to_name.insert(name, #name##_sv.substring(3))); \ MUST(g_atoms_id_to_name.insert(name, #name##_sv)); \
MUST(g_atoms_name_to_id.insert(#name##_sv.substring(3), name)); \ MUST(g_atoms_name_to_id.insert(#name##_sv, name)); \
} while (0) } while (0)
APPEND_ATOM(XA_PRIMARY); APPEND_ATOM(XA_PRIMARY);
APPEND_ATOM(XA_SECONDARY); APPEND_ATOM(XA_SECONDARY);
@ -253,17 +253,6 @@ int main()
APPEND_ATOM(XA_WM_TRANSIENT_FOR); APPEND_ATOM(XA_WM_TRANSIENT_FOR);
#undef APPEND_ATOM #undef APPEND_ATOM
#define APPEND_ATOM_CUSTOM(name) do { \
const CARD32 atom = g_atom_value++; \
MUST(g_atoms_id_to_name.insert(atom, #name##_sv)); \
MUST(g_atoms_name_to_id.insert(#name##_sv, atom)); \
} while (0)
APPEND_ATOM_CUSTOM(WM_PROTOCOLS);
APPEND_ATOM_CUSTOM(WM_DELETE_WINDOW);
APPEND_ATOM_CUSTOM(_NET_WM_STATE);
APPEND_ATOM_CUSTOM(_NET_WM_STATE_FULLSCREEN);
#undef APPEND_ATOM_CUSTOM
MUST(initialize_keymap()); MUST(initialize_keymap());
printf("xbanan started\n"); printf("xbanan started\n");