Compare commits
7 Commits
3e0dc851c4
...
e376c57cda
| Author | SHA1 | Date |
|---|---|---|
|
|
e376c57cda | |
|
|
561aaecc3f | |
|
|
4886e71452 | |
|
|
710b896a84 | |
|
|
8c2fea9edf | |
|
|
85bb292a31 | |
|
|
20f105f56c |
|
|
@ -348,6 +348,10 @@ 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);
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@
|
||||||
#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)
|
||||||
|
|
@ -219,6 +218,7 @@ namespace LibGUI
|
||||||
ResizeWindowEvent,
|
ResizeWindowEvent,
|
||||||
WindowShownEvent,
|
WindowShownEvent,
|
||||||
WindowFocusEvent,
|
WindowFocusEvent,
|
||||||
|
WindowFullscreenEvent,
|
||||||
KeyEvent,
|
KeyEvent,
|
||||||
MouseButtonEvent,
|
MouseButtonEvent,
|
||||||
MouseMoveEvent,
|
MouseMoveEvent,
|
||||||
|
|
@ -345,6 +345,14 @@ 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,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include <BAN/StringView.h>
|
#include <BAN/StringView.h>
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
namespace LibFont { class Font; }
|
namespace LibFont { class Font; }
|
||||||
|
|
|
||||||
|
|
@ -68,15 +68,16 @@ namespace LibGUI
|
||||||
void wait_events();
|
void wait_events();
|
||||||
void poll_events();
|
void poll_events();
|
||||||
|
|
||||||
void set_socket_error_callback(BAN::Function<void()> callback) { m_socket_error_callback = callback; }
|
void set_socket_error_callback(BAN::Function<void()> callback) { m_socket_error_callback = callback; }
|
||||||
void set_close_window_event_callback(BAN::Function<void()> callback) { m_close_window_event_callback = callback; }
|
void set_close_window_event_callback(BAN::Function<void()> callback) { m_close_window_event_callback = callback; }
|
||||||
void set_resize_window_event_callback(BAN::Function<void()> callback) { m_resize_window_event_callback = callback; }
|
void set_resize_window_event_callback(BAN::Function<void()> callback) { m_resize_window_event_callback = callback; }
|
||||||
void set_key_event_callback(BAN::Function<void(EventPacket::KeyEvent::event_t)> callback) { m_key_event_callback = callback; }
|
void set_key_event_callback(BAN::Function<void(EventPacket::KeyEvent::event_t)> callback) { m_key_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_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; }
|
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; }
|
||||||
|
|
||||||
|
|
@ -107,15 +108,16 @@ namespace LibGUI
|
||||||
Texture m_texture;
|
Texture m_texture;
|
||||||
BAN::RefPtr<Widget::Widget> m_root_widget;
|
BAN::RefPtr<Widget::Widget> m_root_widget;
|
||||||
|
|
||||||
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::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::KeyEvent::event_t)> m_key_event_callback;
|
BAN::Function<void(EventPacket::WindowFullscreenEvent::event_t)> m_window_fullscreen_event_callback;
|
||||||
BAN::Function<void(EventPacket::MouseButtonEvent::event_t)> m_mouse_button_event_callback;
|
BAN::Function<void(EventPacket::KeyEvent::event_t)> m_key_event_callback;
|
||||||
BAN::Function<void(EventPacket::MouseMoveEvent::event_t)> m_mouse_move_event_callback;
|
BAN::Function<void(EventPacket::MouseButtonEvent::event_t)> m_mouse_button_event_callback;
|
||||||
BAN::Function<void(EventPacket::MouseScrollEvent::event_t)> m_mouse_scroll_event_callback;
|
BAN::Function<void(EventPacket::MouseMoveEvent::event_t)> m_mouse_move_event_callback;
|
||||||
|
BAN::Function<void(EventPacket::MouseScrollEvent::event_t)> m_mouse_scroll_event_callback;
|
||||||
|
|
||||||
friend class BAN::UniqPtr<Window>;
|
friend class BAN::UniqPtr<Window>;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -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)
|
if (packet.attributes.shown && packet.attributes.focusable && m_state == State::Normal)
|
||||||
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,9 +177,15 @@ 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--)
|
||||||
{
|
{
|
||||||
auto& window = m_client_windows[i - 1];
|
auto& window = m_client_windows[i - 1];
|
||||||
|
|
@ -202,7 +208,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)
|
if (packet.attributes.focusable && packet.attributes.shown && m_state == State::Normal)
|
||||||
set_focused_window(target_window);
|
set_focused_window(target_window);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -302,6 +308,13 @@ 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;
|
||||||
|
|
@ -331,6 +344,12 @@ 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());
|
||||||
|
|
@ -486,6 +505,12 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
207
xbanan/Base.cpp
207
xbanan/Base.cpp
|
|
@ -8,6 +8,7 @@
|
||||||
#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>
|
||||||
|
|
@ -645,7 +646,7 @@ static BAN::Vector<WINDOW> get_path_to_child(WINDOW wid, int32_t x, int32_t y)
|
||||||
const auto& window = object.object.get<Object::Window>();
|
const auto& window = object.object.get<Object::Window>();
|
||||||
if (!window_contains(window, x, y))
|
if (!window_contains(window, x, y))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
MUST(result.push_back(wid));
|
MUST(result.push_back(wid));
|
||||||
|
|
||||||
const WINDOW old_wid = wid;
|
const WINDOW old_wid = wid;
|
||||||
|
|
@ -820,6 +821,55 @@ 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];
|
||||||
|
|
@ -1034,7 +1084,7 @@ static void on_mouse_button_event(Client& client_info, WINDOW wid, uint8_t xbutt
|
||||||
case Button5: mask = Button5Mask; break;
|
case Button5: mask = Button5Mask; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pressed)
|
if (pressed)
|
||||||
s_butmask |= mask;
|
s_butmask |= mask;
|
||||||
else
|
else
|
||||||
s_butmask &= ~mask;
|
s_butmask &= ~mask;
|
||||||
|
|
@ -1085,6 +1135,107 @@ 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];
|
||||||
|
|
@ -1242,13 +1393,18 @@ 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([]{});
|
gui_window_ptr->set_close_window_event_callback([&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([&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);
|
||||||
});
|
});
|
||||||
|
|
@ -1603,7 +1759,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
|
|
||||||
if (!window_changed)
|
if (!window_changed)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
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)
|
if (window.event_mask & StructureNotifyMask)
|
||||||
|
|
@ -1835,7 +1991,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
.data = {},
|
.data = {},
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
auto& property = it->value;
|
auto& property = it->value;
|
||||||
ASSERT(property.format == request.format);
|
ASSERT(property.format == request.format);
|
||||||
|
|
||||||
|
|
@ -1959,7 +2115,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const auto& property = it->value;
|
const auto& property = it->value;
|
||||||
|
|
||||||
const size_t offset = request.longOffset * 4;
|
const size_t offset = request.longOffset * 4;
|
||||||
const size_t bytes = BAN::Math::min<size_t>(request.longLength * 4, property.data.size() - offset);
|
const size_t bytes = BAN::Math::min<size_t>(request.longLength * 4, property.data.size() - offset);
|
||||||
ASSERT(bytes % (property.format / 8) == 0);
|
ASSERT(bytes % (property.format / 8) == 0);
|
||||||
|
|
@ -2136,9 +2292,34 @@ 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);
|
||||||
|
|
||||||
auto event = request.event;
|
WINDOW wid = request.destination;
|
||||||
event.u.u.sequenceNumber = client_info.sequence;
|
if (wid == PointerWindow || wid == InputFocus)
|
||||||
TRY(encode(client_info.output_buffer, event));
|
wid = s_focus_window;
|
||||||
|
|
||||||
|
(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;
|
||||||
}
|
}
|
||||||
|
|
@ -2469,7 +2650,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
TRY(client_info.objects.insert(request.gc));
|
TRY(client_info.objects.insert(request.gc));
|
||||||
TRY(g_objects.insert(request.gc, TRY(BAN::UniqPtr<Object>::create(Object {
|
TRY(g_objects.insert(request.gc, TRY(BAN::UniqPtr<Object>::create(Object {
|
||||||
.type = Object::Type::GraphicsContext,
|
.type = Object::Type::GraphicsContext,
|
||||||
.object = Object::GraphicsContext {
|
.object = Object::GraphicsContext {
|
||||||
.foreground = foreground,
|
.foreground = foreground,
|
||||||
.background = background,
|
.background = background,
|
||||||
.line_width = line_width,
|
.line_width = line_width,
|
||||||
|
|
@ -2887,7 +3068,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
.nColors = static_cast<CARD16>(count),
|
.nColors = static_cast<CARD16>(count),
|
||||||
};
|
};
|
||||||
TRY(encode(client_info.output_buffer, reply));
|
TRY(encode(client_info.output_buffer, reply));
|
||||||
|
|
||||||
dprintln(" colors:");
|
dprintln(" colors:");
|
||||||
for (size_t i = 0; i < count; i++)
|
for (size_t i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
|
|
@ -2934,7 +3115,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
case X_CreateCursor:
|
case X_CreateCursor:
|
||||||
{
|
{
|
||||||
auto request = decode<xCreateCursorReq>(packet).value();
|
auto request = decode<xCreateCursorReq>(packet).value();
|
||||||
|
|
||||||
dprintln("CreateCursor");
|
dprintln("CreateCursor");
|
||||||
dprintln(" cid: {}", request.cid);
|
dprintln(" cid: {}", request.cid);
|
||||||
dprintln(" source: {}", request.source);
|
dprintln(" source: {}", request.source);
|
||||||
|
|
@ -3002,7 +3183,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
case X_FreeCursor:
|
case X_FreeCursor:
|
||||||
{
|
{
|
||||||
const auto cid = packet.as_span<const uint32_t>()[1];
|
const auto cid = packet.as_span<const uint32_t>()[1];
|
||||||
|
|
||||||
dprintln("FreeCursor");
|
dprintln("FreeCursor");
|
||||||
dprintln(" cid: {}", cid);
|
dprintln(" cid: {}", cid);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,12 @@ 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 -Wno-sign-compare -Wno-missing-field-initializers)
|
target_compile_options(xbanan PRIVATE -Wall -Wextra)
|
||||||
|
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)
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,7 @@ 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 };
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ BAN::ErrorOr<void> fill_poly(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
dprintln(" gc: {}", request.gc);
|
dprintln(" gc: {}", request.gc);
|
||||||
dprintln(" shape: {}", request.shape);
|
dprintln(" shape: {}", request.shape);
|
||||||
dprintln(" coordMode: {}", request.coordMode);
|
dprintln(" coordMode: {}", request.coordMode);
|
||||||
|
|
||||||
auto [out_data_u32, out_w, out_h, _] = TRY(get_drawable_info(client_info, request.drawable, X_FillPoly));
|
auto [out_data_u32, out_w, out_h, _] = TRY(get_drawable_info(client_info, request.drawable, X_FillPoly));
|
||||||
|
|
||||||
const auto& gc = TRY_REF(get_gc(client_info, request.gc, X_FillPoly));
|
const auto& gc = TRY_REF(get_gc(client_info, request.gc, X_FillPoly));
|
||||||
|
|
@ -268,7 +268,7 @@ BAN::ErrorOr<void> fill_poly(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_objects[request.drawable]->type == Object::Type::Window)
|
if (g_objects[request.drawable]->type == Object::Type::Window)
|
||||||
invalidate_window(request.drawable, min_x, min_y, max_x - min_x + 1, max_y - min_y + 1);
|
invalidate_window(request.drawable, min_x, min_y, max_x - min_x + 1, max_y - min_y + 1);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
@ -347,7 +347,7 @@ BAN::ErrorOr<void> poly_fill_arc(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
|
|
||||||
const int32_t min_x = BAN::Math::max<int32_t>(0, arc.x);
|
const int32_t min_x = BAN::Math::max<int32_t>(0, arc.x);
|
||||||
const int32_t min_y = BAN::Math::max<int32_t>(0, arc.y);
|
const int32_t min_y = BAN::Math::max<int32_t>(0, arc.y);
|
||||||
|
|
||||||
const int32_t max_x = BAN::Math::min<int32_t>(out_w, arc.x + arc.width);
|
const int32_t max_x = BAN::Math::min<int32_t>(out_w, arc.x + arc.width);
|
||||||
const int32_t max_y = BAN::Math::min<int32_t>(out_h, arc.y + arc.height);
|
const int32_t max_y = BAN::Math::min<int32_t>(out_h, arc.y + arc.height);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -144,7 +144,7 @@ BAN::ErrorOr<void> extension_glx(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
delete &TRY_REF(get_glx_context(request.context));
|
delete &TRY_REF(get_glx_context(request.context));
|
||||||
client_info.objects.remove(request.context);
|
client_info.objects.remove(request.context);
|
||||||
g_objects.remove(request.context);
|
g_objects.remove(request.context);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case X_GLXIsDirect:
|
case X_GLXIsDirect:
|
||||||
|
|
@ -253,7 +253,7 @@ BAN::ErrorOr<void> extension_glx(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
.n = static_cast<CARD16>(string.size()),
|
.n = static_cast<CARD16>(string.size()),
|
||||||
};
|
};
|
||||||
TRY(encode(client_info.output_buffer, reply));
|
TRY(encode(client_info.output_buffer, reply));
|
||||||
|
|
||||||
TRY(encode(client_info.output_buffer, string));
|
TRY(encode(client_info.output_buffer, string));
|
||||||
for (size_t i = 0; (string.size() + i) % 4; i++)
|
for (size_t i = 0; (string.size() + i) % 4; i++)
|
||||||
TRY(encode(client_info.output_buffer, '\0'));
|
TRY(encode(client_info.output_buffer, '\0'));
|
||||||
|
|
@ -289,7 +289,7 @@ BAN::ErrorOr<void> extension_glx(Client& client_info, BAN::ConstByteSpan packet)
|
||||||
.numAttribs = attribs,
|
.numAttribs = attribs,
|
||||||
};
|
};
|
||||||
TRY(encode(client_info.output_buffer, reply));
|
TRY(encode(client_info.output_buffer, reply));
|
||||||
|
|
||||||
TRY(encode(client_info.output_buffer, g_fb_configs));
|
TRY(encode(client_info.output_buffer, g_fb_configs));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ static BAN::ErrorOr<void> extension_randr(Client& client_info, BAN::ConstByteSpa
|
||||||
{
|
{
|
||||||
static CARD32 crtc_id = 5;
|
static CARD32 crtc_id = 5;
|
||||||
static CARD32 output_id = 6;
|
static CARD32 output_id = 6;
|
||||||
static CARD32 mode_id = 7;
|
static CARD32 mode_id = 7;
|
||||||
static CARD32 timestamp = time(nullptr);
|
static CARD32 timestamp = time(nullptr);
|
||||||
|
|
||||||
static xRenderTransform transform {
|
static xRenderTransform transform {
|
||||||
|
|
|
||||||
|
|
@ -455,7 +455,7 @@ static void initialize_fonts()
|
||||||
|
|
||||||
auto it = s_available_fonts.find(BAN::String(name));
|
auto it = s_available_fonts.find(BAN::String(name));
|
||||||
if (it == s_available_fonts.end())
|
if (it == s_available_fonts.end())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MUST(s_available_fonts.insert(BAN::String(alias), it->value));
|
MUST(s_available_fonts.insert(BAN::String(alias), it->value));
|
||||||
}
|
}
|
||||||
|
|
@ -756,7 +756,7 @@ static void write_text(WriteTextInfo& info)
|
||||||
for (size_t i = 0; i < info.string_len; i++)
|
for (size_t i = 0; i < info.string_len; i++)
|
||||||
{
|
{
|
||||||
const uint16_t codepoint = info.wide ? (info.string[i * 2] << 8) | info.string[i * 2 + 1] : info.string[i];
|
const uint16_t codepoint = info.wide ? (info.string[i * 2] << 8) | info.string[i * 2 + 1] : info.string[i];
|
||||||
|
|
||||||
auto glyph_index = info.font->find_glyph(codepoint);
|
auto glyph_index = info.font->find_glyph(codepoint);
|
||||||
if (!glyph_index.has_value())
|
if (!glyph_index.has_value())
|
||||||
continue;
|
continue;
|
||||||
|
|
|
||||||
|
|
@ -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)); \
|
MUST(g_atoms_id_to_name.insert(name, #name##_sv.substring(3))); \
|
||||||
MUST(g_atoms_name_to_id.insert(#name##_sv, name)); \
|
MUST(g_atoms_name_to_id.insert(#name##_sv.substring(3), name)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
APPEND_ATOM(XA_PRIMARY);
|
APPEND_ATOM(XA_PRIMARY);
|
||||||
APPEND_ATOM(XA_SECONDARY);
|
APPEND_ATOM(XA_SECONDARY);
|
||||||
|
|
@ -253,6 +253,17 @@ 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");
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue