mirror of
https://github.com/RGBCube/serenity
synced 2025-07-24 22:17:42 +00:00
WindowServer: Rename WSEvent subclasses WSFooEvent for consistency.
Add a WSWindowInvalidationEvent that carries a rect instead of having an awkward single-purpose rect in WSEvent. Flesh out WSKeyEvent a bit more.
This commit is contained in:
parent
aefbbeb3cb
commit
51595603bd
8 changed files with 72 additions and 81 deletions
|
@ -80,7 +80,11 @@ struct GUI_Event {
|
||||||
} mouse;
|
} mouse;
|
||||||
struct {
|
struct {
|
||||||
char character;
|
char character;
|
||||||
unsigned modifiers;
|
byte key;
|
||||||
|
byte modifiers;
|
||||||
|
bool ctrl : 1;
|
||||||
|
bool alt : 1;
|
||||||
|
bool shift : 1;
|
||||||
} key;
|
} key;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -120,10 +120,10 @@ int Process::gui$invalidate_window(int window_id, const GUI_Rect* rect)
|
||||||
dbgprintf("%s<%u> gui$invalidate_window (window_id=%d, rect={%d,%d %dx%d})\n", name().characters(), pid(), window_id, rect->location.x, rect->location.y, rect->size.width, rect->size.height);
|
dbgprintf("%s<%u> gui$invalidate_window (window_id=%d, rect={%d,%d %dx%d})\n", name().characters(), pid(), window_id, rect->location.x, rect->location.y, rect->size.width, rect->size.height);
|
||||||
#endif
|
#endif
|
||||||
auto& window = *(*it).value;
|
auto& window = *(*it).value;
|
||||||
auto event = make<WSEvent>(WSEvent::WM_Invalidate);
|
Rect invalidation_rect;
|
||||||
if (rect)
|
if (rect)
|
||||||
event->set_rect(*rect);
|
invalidation_rect = *rect;
|
||||||
WSEventLoop::the().post_event(&window, move(event));
|
WSEventLoop::the().post_event(&window, make<WSWindowInvalidationEvent>(invalidation_rect));
|
||||||
WSEventLoop::the().server_process().request_wakeup();
|
WSEventLoop::the().server_process().request_wakeup();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,24 +49,30 @@ public:
|
||||||
|
|
||||||
const char* name() const { return WSEvent_names[(unsigned)m_type]; }
|
const char* name() const { return WSEvent_names[(unsigned)m_type]; }
|
||||||
|
|
||||||
bool isMouseEvent() const { return m_type == MouseMove || m_type == MouseDown || m_type == MouseUp; }
|
bool is_mouse_event() const { return m_type == MouseMove || m_type == MouseDown || m_type == MouseUp; }
|
||||||
bool isKeyEvent() const { return m_type == KeyUp || m_type == KeyDown; }
|
bool is_key_event() const { return m_type == KeyUp || m_type == KeyDown; }
|
||||||
bool isPaintEvent() const { return m_type == Paint; }
|
bool is_paint_event() const { return m_type == Paint; }
|
||||||
|
|
||||||
Rect rect() const { return m_rect; }
|
|
||||||
void set_rect(const GUI_Rect& rect)
|
|
||||||
{
|
|
||||||
m_rect = rect;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type m_type { Invalid };
|
Type m_type { Invalid };
|
||||||
|
};
|
||||||
|
|
||||||
|
class WSWindowInvalidationEvent final : public WSEvent {
|
||||||
|
public:
|
||||||
|
explicit WSWindowInvalidationEvent(const Rect& rect = Rect())
|
||||||
|
: WSEvent(WSEvent::WM_Invalidate)
|
||||||
|
, m_rect(rect)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
const Rect& rect() const { return m_rect; }
|
||||||
|
private:
|
||||||
Rect m_rect;
|
Rect m_rect;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PaintEvent final : public WSEvent {
|
class WSPaintEvent final : public WSEvent {
|
||||||
public:
|
public:
|
||||||
explicit PaintEvent(const Rect& rect = Rect())
|
explicit WSPaintEvent(const Rect& rect = Rect())
|
||||||
: WSEvent(WSEvent::Paint)
|
: WSEvent(WSEvent::Paint)
|
||||||
, m_rect(rect)
|
, m_rect(rect)
|
||||||
{
|
{
|
||||||
|
@ -85,21 +91,12 @@ enum class MouseButton : byte {
|
||||||
Middle = 4,
|
Middle = 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum KeyboardKey {
|
class WSKeyEvent final : public WSEvent {
|
||||||
Invalid,
|
|
||||||
LeftArrow,
|
|
||||||
RightArrow,
|
|
||||||
UpArrow,
|
|
||||||
DownArrow,
|
|
||||||
Backspace,
|
|
||||||
Return,
|
|
||||||
};
|
|
||||||
|
|
||||||
class KeyEvent final : public WSEvent {
|
|
||||||
public:
|
public:
|
||||||
KeyEvent(Type type, int key)
|
WSKeyEvent(Type type, int key, char character)
|
||||||
: WSEvent(type)
|
: WSEvent(type)
|
||||||
, m_key(key)
|
, m_key(key)
|
||||||
|
, m_character(character)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +104,7 @@ public:
|
||||||
bool ctrl() const { return m_ctrl; }
|
bool ctrl() const { return m_ctrl; }
|
||||||
bool alt() const { return m_alt; }
|
bool alt() const { return m_alt; }
|
||||||
bool shift() const { return m_shift; }
|
bool shift() const { return m_shift; }
|
||||||
String text() const { return m_text; }
|
char character() const { return m_character; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class WSEventLoop;
|
friend class WSEventLoop;
|
||||||
|
@ -116,12 +113,12 @@ private:
|
||||||
bool m_ctrl { false };
|
bool m_ctrl { false };
|
||||||
bool m_alt { false };
|
bool m_alt { false };
|
||||||
bool m_shift { false };
|
bool m_shift { false };
|
||||||
String m_text;
|
char m_character { 0 };
|
||||||
};
|
};
|
||||||
|
|
||||||
class MouseEvent final : public WSEvent {
|
class WSMouseEvent final : public WSEvent {
|
||||||
public:
|
public:
|
||||||
MouseEvent(Type type, const Point& position, unsigned buttons, MouseButton button = MouseButton::None)
|
WSMouseEvent(Type type, const Point& position, unsigned buttons, MouseButton button = MouseButton::None)
|
||||||
: WSEvent(type)
|
: WSEvent(type)
|
||||||
, m_position(position)
|
, m_position(position)
|
||||||
, m_buttons(buttons)
|
, m_buttons(buttons)
|
||||||
|
|
|
@ -80,14 +80,16 @@ void WSEventLoop::post_event(WSEventReceiver* receiver, OwnPtr<WSEvent>&& event)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (event->type() == WSEvent::WM_Invalidate) {
|
if (event->type() == WSEvent::WM_Invalidate) {
|
||||||
|
auto& invalidation_event = static_cast<WSWindowInvalidationEvent&>(*event);
|
||||||
for (auto& queued_event : m_queued_events) {
|
for (auto& queued_event : m_queued_events) {
|
||||||
if (receiver == queued_event.receiver
|
if (receiver == queued_event.receiver && queued_event.event->type() == WSEvent::WM_Invalidate) {
|
||||||
&& queued_event.event->type() == WSEvent::WM_Invalidate
|
auto& queued_invalidation_event = static_cast<WSWindowInvalidationEvent&>(*queued_event.event);
|
||||||
&& (queued_event.event->rect().is_empty() || queued_event.event->rect().contains(event->rect()))) {
|
if (queued_invalidation_event.rect().is_empty() || queued_invalidation_event.rect().contains(invalidation_event.rect())) {
|
||||||
#ifdef WSEVENTLOOP_DEBUG
|
#ifdef WSEVENTLOOP_DEBUG
|
||||||
dbgprintf("Swallow WM_Invalidate\n");
|
dbgprintf("Swallow WM_Invalidate\n");
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ void WSScreen::on_receive_mouse_data(int dx, int dy, bool left_button, bool righ
|
||||||
if (right_button)
|
if (right_button)
|
||||||
buttons |= (unsigned)MouseButton::Right;
|
buttons |= (unsigned)MouseButton::Right;
|
||||||
if (m_cursor_location != prev_location) {
|
if (m_cursor_location != prev_location) {
|
||||||
auto event = make<MouseEvent>(WSEvent::MouseMove, m_cursor_location, buttons);
|
auto event = make<WSMouseEvent>(WSEvent::MouseMove, m_cursor_location, buttons);
|
||||||
WSEventLoop::the().post_event(&WSWindowManager::the(), move(event));
|
WSEventLoop::the().post_event(&WSWindowManager::the(), move(event));
|
||||||
}
|
}
|
||||||
bool prev_left_button = m_left_mouse_button_pressed;
|
bool prev_left_button = m_left_mouse_button_pressed;
|
||||||
|
@ -55,38 +55,22 @@ void WSScreen::on_receive_mouse_data(int dx, int dy, bool left_button, bool righ
|
||||||
m_left_mouse_button_pressed = left_button;
|
m_left_mouse_button_pressed = left_button;
|
||||||
m_right_mouse_button_pressed = right_button;
|
m_right_mouse_button_pressed = right_button;
|
||||||
if (prev_left_button != left_button) {
|
if (prev_left_button != left_button) {
|
||||||
auto event = make<MouseEvent>(left_button ? WSEvent::MouseDown : WSEvent::MouseUp, m_cursor_location, buttons, MouseButton::Left);
|
auto event = make<WSMouseEvent>(left_button ? WSEvent::MouseDown : WSEvent::MouseUp, m_cursor_location, buttons, MouseButton::Left);
|
||||||
WSEventLoop::the().post_event(&WSWindowManager::the(), move(event));
|
WSEventLoop::the().post_event(&WSWindowManager::the(), move(event));
|
||||||
}
|
}
|
||||||
if (prev_right_button != right_button) {
|
if (prev_right_button != right_button) {
|
||||||
auto event = make<MouseEvent>(right_button ? WSEvent::MouseDown : WSEvent::MouseUp, m_cursor_location, buttons, MouseButton::Right);
|
auto event = make<WSMouseEvent>(right_button ? WSEvent::MouseDown : WSEvent::MouseUp, m_cursor_location, buttons, MouseButton::Right);
|
||||||
WSEventLoop::the().post_event(&WSWindowManager::the(), move(event));
|
WSEventLoop::the().post_event(&WSWindowManager::the(), move(event));
|
||||||
}
|
}
|
||||||
if (m_cursor_location != prev_location || prev_left_button != left_button)
|
if (m_cursor_location != prev_location || prev_left_button != left_button)
|
||||||
WSWindowManager::the().draw_cursor();
|
WSWindowManager::the().draw_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSScreen::on_receive_keyboard_data(Keyboard::Event key)
|
void WSScreen::on_receive_keyboard_data(Keyboard::Event kernel_event)
|
||||||
{
|
{
|
||||||
auto event = make<KeyEvent>(key.is_press() ? WSEvent::KeyDown : WSEvent::KeyUp, 0);
|
auto event = make<WSKeyEvent>(kernel_event.is_press() ? WSEvent::KeyDown : WSEvent::KeyUp, kernel_event.key, kernel_event.character);
|
||||||
int key_code = 0;
|
event->m_shift = kernel_event.shift();
|
||||||
|
event->m_ctrl = kernel_event.ctrl();
|
||||||
switch (key.character) {
|
event->m_alt = kernel_event.alt();
|
||||||
case 8: key_code = KeyboardKey::Backspace; break;
|
|
||||||
case 10: key_code = KeyboardKey::Return; break;
|
|
||||||
}
|
|
||||||
event->m_key = key_code;
|
|
||||||
|
|
||||||
if (key.character) {
|
|
||||||
char buf[] = { 0, 0 };
|
|
||||||
char& ch = buf[0];
|
|
||||||
ch = key.character;
|
|
||||||
event->m_text = buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
event->m_shift = key.shift();
|
|
||||||
event->m_ctrl = key.ctrl();
|
|
||||||
event->m_alt = key.alt();
|
|
||||||
|
|
||||||
WSEventLoop::the().post_event(&WSWindowManager::the(), move(event));
|
WSEventLoop::the().post_event(&WSWindowManager::the(), move(event));
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,32 +55,36 @@ void WSWindow::event(WSEvent& event)
|
||||||
switch (event.type()) {
|
switch (event.type()) {
|
||||||
case WSEvent::Paint:
|
case WSEvent::Paint:
|
||||||
gui_event.type = GUI_Event::Type::Paint;
|
gui_event.type = GUI_Event::Type::Paint;
|
||||||
gui_event.paint.rect = static_cast<PaintEvent&>(event).rect();
|
gui_event.paint.rect = static_cast<WSPaintEvent&>(event).rect();
|
||||||
break;
|
break;
|
||||||
case WSEvent::MouseMove:
|
case WSEvent::MouseMove:
|
||||||
gui_event.type = GUI_Event::Type::MouseMove;
|
gui_event.type = GUI_Event::Type::MouseMove;
|
||||||
gui_event.mouse.position = static_cast<MouseEvent&>(event).position();
|
gui_event.mouse.position = static_cast<WSMouseEvent&>(event).position();
|
||||||
gui_event.mouse.button = GUI_MouseButton::NoButton;
|
gui_event.mouse.button = GUI_MouseButton::NoButton;
|
||||||
gui_event.mouse.buttons = static_cast<MouseEvent&>(event).buttons();
|
gui_event.mouse.buttons = static_cast<WSMouseEvent&>(event).buttons();
|
||||||
break;
|
break;
|
||||||
case WSEvent::MouseDown:
|
case WSEvent::MouseDown:
|
||||||
gui_event.type = GUI_Event::Type::MouseDown;
|
gui_event.type = GUI_Event::Type::MouseDown;
|
||||||
gui_event.mouse.position = static_cast<MouseEvent&>(event).position();
|
gui_event.mouse.position = static_cast<WSMouseEvent&>(event).position();
|
||||||
gui_event.mouse.button = to_api(static_cast<MouseEvent&>(event).button());
|
gui_event.mouse.button = to_api(static_cast<WSMouseEvent&>(event).button());
|
||||||
gui_event.mouse.buttons = static_cast<MouseEvent&>(event).buttons();
|
gui_event.mouse.buttons = static_cast<WSMouseEvent&>(event).buttons();
|
||||||
break;
|
break;
|
||||||
case WSEvent::MouseUp:
|
case WSEvent::MouseUp:
|
||||||
gui_event.type = GUI_Event::Type::MouseUp;
|
gui_event.type = GUI_Event::Type::MouseUp;
|
||||||
gui_event.mouse.position = static_cast<MouseEvent&>(event).position();
|
gui_event.mouse.position = static_cast<WSMouseEvent&>(event).position();
|
||||||
gui_event.mouse.button = to_api(static_cast<MouseEvent&>(event).button());
|
gui_event.mouse.button = to_api(static_cast<WSMouseEvent&>(event).button());
|
||||||
gui_event.mouse.buttons = static_cast<MouseEvent&>(event).buttons();
|
gui_event.mouse.buttons = static_cast<WSMouseEvent&>(event).buttons();
|
||||||
break;
|
break;
|
||||||
case WSEvent::KeyDown:
|
case WSEvent::KeyDown:
|
||||||
gui_event.type = GUI_Event::Type::KeyDown;
|
gui_event.type = GUI_Event::Type::KeyDown;
|
||||||
gui_event.key.character = static_cast<KeyEvent&>(event).text()[0];
|
gui_event.key.character = static_cast<WSKeyEvent&>(event).character();
|
||||||
|
gui_event.key.key = static_cast<WSKeyEvent&>(event).key();
|
||||||
|
gui_event.key.alt = static_cast<WSKeyEvent&>(event).alt();
|
||||||
|
gui_event.key.ctrl = static_cast<WSKeyEvent&>(event).ctrl();
|
||||||
|
gui_event.key.shift = static_cast<WSKeyEvent&>(event).shift();
|
||||||
break;
|
break;
|
||||||
case WSEvent::WM_Invalidate:
|
case WSEvent::WM_Invalidate:
|
||||||
WSWindowManager::the().invalidate(*this, event.rect());
|
WSWindowManager::the().invalidate(*this, static_cast<WSWindowInvalidationEvent&>(event).rect());
|
||||||
return;
|
return;
|
||||||
case WSEvent::WindowActivated:
|
case WSEvent::WindowActivated:
|
||||||
gui_event.type = GUI_Event::Type::WindowActivated;
|
gui_event.type = GUI_Event::Type::WindowActivated;
|
||||||
|
|
|
@ -231,7 +231,7 @@ void WSWindowManager::notify_rect_changed(WSWindow& window, const Rect& old_rect
|
||||||
invalidate(outer_window_rect(new_rect));
|
invalidate(outer_window_rect(new_rect));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSWindowManager::handle_titlebar_mouse_event(WSWindow& window, MouseEvent& event)
|
void WSWindowManager::handle_titlebar_mouse_event(WSWindow& window, WSMouseEvent& event)
|
||||||
{
|
{
|
||||||
if (event.type() == WSEvent::MouseDown && event.button() == MouseButton::Left) {
|
if (event.type() == WSEvent::MouseDown && event.button() == MouseButton::Left) {
|
||||||
#ifdef DRAG_DEBUG
|
#ifdef DRAG_DEBUG
|
||||||
|
@ -247,7 +247,7 @@ void WSWindowManager::handle_titlebar_mouse_event(WSWindow& window, MouseEvent&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSWindowManager::process_mouse_event(MouseEvent& event)
|
void WSWindowManager::process_mouse_event(WSMouseEvent& event)
|
||||||
{
|
{
|
||||||
if (event.type() == WSEvent::MouseUp && event.button() == MouseButton::Left) {
|
if (event.type() == WSEvent::MouseUp && event.button() == MouseButton::Left) {
|
||||||
if (m_drag_window) {
|
if (m_drag_window) {
|
||||||
|
@ -294,7 +294,7 @@ void WSWindowManager::process_mouse_event(MouseEvent& event)
|
||||||
}
|
}
|
||||||
// FIXME: Should we just alter the coordinates of the existing MouseEvent and pass it through?
|
// FIXME: Should we just alter the coordinates of the existing MouseEvent and pass it through?
|
||||||
Point position { event.x() - window->rect().x(), event.y() - window->rect().y() };
|
Point position { event.x() - window->rect().x(), event.y() - window->rect().y() };
|
||||||
auto local_event = make<MouseEvent>(event.type(), position, event.buttons(), event.button());
|
auto local_event = make<WSMouseEvent>(event.type(), position, event.buttons(), event.button());
|
||||||
window->event(*local_event);
|
window->event(*local_event);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -379,10 +379,10 @@ void WSWindowManager::event(WSEvent& event)
|
||||||
{
|
{
|
||||||
ASSERT_INTERRUPTS_ENABLED();
|
ASSERT_INTERRUPTS_ENABLED();
|
||||||
LOCKER(m_lock);
|
LOCKER(m_lock);
|
||||||
if (event.isMouseEvent())
|
if (event.is_mouse_event())
|
||||||
return process_mouse_event(static_cast<MouseEvent&>(event));
|
return process_mouse_event(static_cast<WSMouseEvent&>(event));
|
||||||
|
|
||||||
if (event.isKeyEvent()) {
|
if (event.is_key_event()) {
|
||||||
// FIXME: This is a good place to hook key events globally. :)
|
// FIXME: This is a good place to hook key events globally. :)
|
||||||
if (m_active_window)
|
if (m_active_window)
|
||||||
return m_active_window->event(event);
|
return m_active_window->event(event);
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
#include "WSEventReceiver.h"
|
#include "WSEventReceiver.h"
|
||||||
|
|
||||||
class WSScreen;
|
class WSScreen;
|
||||||
class MouseEvent;
|
class WSMouseEvent;
|
||||||
class PaintEvent;
|
class WSPaintEvent;
|
||||||
class WSWindow;
|
class WSWindow;
|
||||||
class CharacterBitmap;
|
class CharacterBitmap;
|
||||||
class GraphicsBitmap;
|
class GraphicsBitmap;
|
||||||
|
@ -43,8 +43,8 @@ private:
|
||||||
WSWindowManager();
|
WSWindowManager();
|
||||||
virtual ~WSWindowManager() override;
|
virtual ~WSWindowManager() override;
|
||||||
|
|
||||||
void process_mouse_event(MouseEvent&);
|
void process_mouse_event(WSMouseEvent&);
|
||||||
void handle_titlebar_mouse_event(WSWindow&, MouseEvent&);
|
void handle_titlebar_mouse_event(WSWindow&, WSMouseEvent&);
|
||||||
|
|
||||||
void set_active_window(WSWindow*);
|
void set_active_window(WSWindow*);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue