mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-04 01:05:58 +03:00
Taskbar: More bringup work. We now see a basic window list.
This commit is contained in:
parent
ea801a99dc
commit
96104b5524
Notes:
sideshowbarker
2024-07-19 14:49:55 +09:00
Author: https://github.com/awesomekling Commit: https://github.com/SerenityOS/serenity/commit/96104b55249
@ -1,6 +1,7 @@
|
|||||||
OBJS = \
|
OBJS = \
|
||||||
TaskbarWindow.o \
|
TaskbarWindow.o \
|
||||||
TaskbarWidget.o \
|
TaskbarWidget.o \
|
||||||
|
WindowList.o \
|
||||||
main.o
|
main.o
|
||||||
|
|
||||||
APP = Taskbar
|
APP = Taskbar
|
||||||
|
@ -5,13 +5,14 @@
|
|||||||
#include <LibGUI/GPainter.h>
|
#include <LibGUI/GPainter.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
TaskbarWidget::TaskbarWidget(GWidget* parent)
|
TaskbarWidget::TaskbarWidget(WindowList& window_list, GWidget* parent)
|
||||||
: GFrame(parent)
|
: GFrame(parent)
|
||||||
|
, m_window_list(window_list)
|
||||||
{
|
{
|
||||||
set_fill_with_background_color(true);
|
set_fill_with_background_color(true);
|
||||||
set_layout(make<GBoxLayout>(Orientation::Horizontal));
|
set_layout(make<GBoxLayout>(Orientation::Horizontal));
|
||||||
layout()->set_margins({ 0, 8, 0, 8 });
|
layout()->set_margins({ 0, 3, 0, 3 });
|
||||||
layout()->set_spacing(8);
|
layout()->set_spacing(3);
|
||||||
|
|
||||||
set_frame_thickness(1);
|
set_frame_thickness(1);
|
||||||
set_frame_shape(GFrame::Shape::Panel);
|
set_frame_shape(GFrame::Shape::Panel);
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
#include <LibGUI/GFrame.h>
|
#include <LibGUI/GFrame.h>
|
||||||
|
|
||||||
|
class WindowList;
|
||||||
|
|
||||||
class TaskbarWidget final : public GFrame {
|
class TaskbarWidget final : public GFrame {
|
||||||
public:
|
public:
|
||||||
TaskbarWidget(GWidget* parent = nullptr);
|
TaskbarWidget(WindowList&, GWidget* parent = nullptr);
|
||||||
virtual ~TaskbarWidget() override;
|
virtual ~TaskbarWidget() override;
|
||||||
|
|
||||||
virtual const char* class_name() const override { return "TaskbarWidget"; }
|
virtual const char* class_name() const override { return "TaskbarWidget"; }
|
||||||
@ -10,4 +12,5 @@ public:
|
|||||||
private:
|
private:
|
||||||
virtual void paint_event(GPaintEvent&) override;
|
virtual void paint_event(GPaintEvent&) override;
|
||||||
|
|
||||||
|
WindowList& m_window_list;
|
||||||
};
|
};
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <LibGUI/GWindow.h>
|
#include <LibGUI/GWindow.h>
|
||||||
#include <LibGUI/GDesktop.h>
|
#include <LibGUI/GDesktop.h>
|
||||||
#include <LibGUI/GEventLoop.h>
|
#include <LibGUI/GEventLoop.h>
|
||||||
|
#include <LibGUI/GButton.h>
|
||||||
#include <WindowServer/WSAPITypes.h>
|
#include <WindowServer/WSAPITypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@ -16,7 +17,7 @@ TaskbarWindow::TaskbarWindow()
|
|||||||
|
|
||||||
GDesktop::the().on_rect_change = [this] (const Rect& rect) { on_screen_rect_change(rect); };
|
GDesktop::the().on_rect_change = [this] (const Rect& rect) { on_screen_rect_change(rect); };
|
||||||
|
|
||||||
auto* widget = new TaskbarWidget;
|
auto* widget = new TaskbarWidget(m_window_list);
|
||||||
set_main_widget(widget);
|
set_main_widget(widget);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -32,10 +33,51 @@ void TaskbarWindow::on_screen_rect_change(const Rect& rect)
|
|||||||
|
|
||||||
void TaskbarWindow::wm_event(GWMEvent& event)
|
void TaskbarWindow::wm_event(GWMEvent& event)
|
||||||
{
|
{
|
||||||
#if 0
|
WindowIdentifier identifier { event.client_id(), event.window_id() };
|
||||||
switch (event.type()) {
|
switch (event.type()) {
|
||||||
case GEvent::WM_WindowAdded:
|
case GEvent::WM_WindowAdded: {
|
||||||
m_window_list.append({})
|
auto& added_event = static_cast<GWMWindowAddedEvent&>(event);
|
||||||
|
printf("WM_WindowAdded: client_id=%d, window_id=%d, title=%s, rect=%s\n",
|
||||||
|
added_event.client_id(),
|
||||||
|
added_event.window_id(),
|
||||||
|
added_event.title().characters(),
|
||||||
|
added_event.rect().to_string().characters()
|
||||||
|
);
|
||||||
|
auto& window = m_window_list.ensure_window(identifier);
|
||||||
|
window.set_title(added_event.title());
|
||||||
|
window.set_rect(added_event.rect());
|
||||||
|
window.set_button(new GButton(main_widget()));
|
||||||
|
window.button()->set_size_policy(SizePolicy::Fixed, SizePolicy::Fixed);
|
||||||
|
window.button()->set_preferred_size({ 100, 22 });
|
||||||
|
window.button()->set_caption(window.title());
|
||||||
|
update();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GEvent::WM_WindowRemoved: {
|
||||||
|
auto& removed_event = static_cast<GWMWindowRemovedEvent&>(event);
|
||||||
|
printf("WM_WindowRemoved: client_id=%d, window_id=%d\n",
|
||||||
|
removed_event.client_id(),
|
||||||
|
removed_event.window_id()
|
||||||
|
);
|
||||||
|
m_window_list.remove_window(identifier);
|
||||||
|
update();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GEvent::WM_WindowStateChanged: {
|
||||||
|
auto& changed_event = static_cast<GWMWindowStateChangedEvent&>(event);
|
||||||
|
printf("WM_WindowStateChanged: client_id=%d, window_id=%d, title=%s, rect=%s\n",
|
||||||
|
changed_event.client_id(),
|
||||||
|
changed_event.window_id(),
|
||||||
|
changed_event.title().characters(),
|
||||||
|
changed_event.rect().to_string().characters()
|
||||||
|
);
|
||||||
|
auto& window = m_window_list.ensure_window(identifier);
|
||||||
|
window.set_title(changed_event.title());
|
||||||
|
window.set_rect(changed_event.rect());
|
||||||
|
window.button()->set_caption(changed_event.title());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
#include <LibGUI/GWindow.h>
|
#include <LibGUI/GWindow.h>
|
||||||
#include <LibGUI/GWidget.h>
|
#include <LibGUI/GWidget.h>
|
||||||
|
#include "WindowList.h"
|
||||||
|
|
||||||
class TaskbarWindow final : public GWindow {
|
class TaskbarWindow final : public GWindow {
|
||||||
public:
|
public:
|
||||||
TaskbarWindow();
|
TaskbarWindow();
|
||||||
virtual ~TaskbarWindow() override;
|
virtual ~TaskbarWindow() override;
|
||||||
|
|
||||||
int taskbar_height() const { return 20; }
|
int taskbar_height() const { return 28; }
|
||||||
|
|
||||||
virtual const char* class_name() const override { return "TaskbarWindow"; }
|
virtual const char* class_name() const override { return "TaskbarWindow"; }
|
||||||
|
|
||||||
@ -14,4 +15,6 @@ private:
|
|||||||
void on_screen_rect_change(const Rect&);
|
void on_screen_rect_change(const Rect&);
|
||||||
|
|
||||||
virtual void wm_event(GWMEvent&) override;
|
virtual void wm_event(GWMEvent&) override;
|
||||||
|
|
||||||
|
WindowList m_window_list;
|
||||||
};
|
};
|
||||||
|
17
Applications/Taskbar/WindowList.cpp
Normal file
17
Applications/Taskbar/WindowList.cpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#include "WindowList.h"
|
||||||
|
|
||||||
|
Window& WindowList::ensure_window(const WindowIdentifier& identifier)
|
||||||
|
{
|
||||||
|
auto it = m_windows.find(identifier);
|
||||||
|
if (it != m_windows.end())
|
||||||
|
return *it->value;
|
||||||
|
auto window = make<Window>(identifier);
|
||||||
|
auto& window_ref = *window;
|
||||||
|
m_windows.set(identifier, move(window));
|
||||||
|
return window_ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WindowList::remove_window(const WindowIdentifier& identifier)
|
||||||
|
{
|
||||||
|
m_windows.remove(identifier);
|
||||||
|
}
|
80
Applications/Taskbar/WindowList.h
Normal file
80
Applications/Taskbar/WindowList.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/AKString.h>
|
||||||
|
#include <AK/HashMap.h>
|
||||||
|
#include <AK/Traits.h>
|
||||||
|
#include <SharedGraphics/Rect.h>
|
||||||
|
#include <LibGUI/GButton.h>
|
||||||
|
|
||||||
|
class WindowIdentifier {
|
||||||
|
public:
|
||||||
|
WindowIdentifier(int client_id, int window_id)
|
||||||
|
: m_client_id(client_id)
|
||||||
|
, m_window_id(window_id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int client_id() const { return m_client_id; }
|
||||||
|
int window_id() const { return m_window_id; }
|
||||||
|
|
||||||
|
bool operator==(const WindowIdentifier& other) const
|
||||||
|
{
|
||||||
|
return m_client_id == other.m_client_id && m_window_id == other.m_window_id;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
int m_client_id { -1 };
|
||||||
|
int m_window_id { -1 };
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace AK {
|
||||||
|
template<>
|
||||||
|
struct Traits<WindowIdentifier> {
|
||||||
|
static unsigned hash(const WindowIdentifier& w) { return pair_int_hash(w.client_id(), w.window_id()); }
|
||||||
|
static void dump(const WindowIdentifier& w) { kprintf("WindowIdentifier(%d, %d)", w.client_id(), w.window_id()); }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
class Window {
|
||||||
|
public:
|
||||||
|
explicit Window(const WindowIdentifier& identifier)
|
||||||
|
: m_identifier(identifier)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~Window()
|
||||||
|
{
|
||||||
|
delete m_button;
|
||||||
|
}
|
||||||
|
|
||||||
|
WindowIdentifier identifier() const { return m_identifier; }
|
||||||
|
|
||||||
|
String title() const { return m_title; }
|
||||||
|
void set_title(const String& title) { m_title = title; }
|
||||||
|
|
||||||
|
Rect rect() const { return m_rect; }
|
||||||
|
void set_rect(const Rect& rect) { m_rect = rect; }
|
||||||
|
|
||||||
|
GButton* button() { return m_button; }
|
||||||
|
void set_button(GButton* button) { m_button = button; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
WindowIdentifier m_identifier;
|
||||||
|
String m_title;
|
||||||
|
Rect m_rect;
|
||||||
|
GButton* m_button { nullptr };
|
||||||
|
};
|
||||||
|
|
||||||
|
class WindowList {
|
||||||
|
public:
|
||||||
|
template<typename Callback> void for_each_window(Callback callback)
|
||||||
|
{
|
||||||
|
for (auto& it : m_windows)
|
||||||
|
callback(*it.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
Window& ensure_window(const WindowIdentifier&);
|
||||||
|
void remove_window(const WindowIdentifier&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
HashMap<WindowIdentifier, OwnPtr<Window>> m_windows;
|
||||||
|
};
|
@ -51,6 +51,6 @@ void SharedBuffer::seal()
|
|||||||
int rc = seal_shared_buffer(m_shared_buffer_id);
|
int rc = seal_shared_buffer(m_shared_buffer_id);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
perror("seal_shared_buffer");
|
perror("seal_shared_buffer");
|
||||||
exit(1);
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,9 @@ void GBoxLayout::run(GWidget& widget)
|
|||||||
dbgprintf("GBoxLayout: Starting with available size: %s\n", available_size.to_string().characters());
|
dbgprintf("GBoxLayout: Starting with available size: %s\n", available_size.to_string().characters());
|
||||||
|
|
||||||
for (auto& entry : m_entries) {
|
for (auto& entry : m_entries) {
|
||||||
|
if (!entry.widget)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!entry.widget->is_visible())
|
if (!entry.widget->is_visible())
|
||||||
continue;
|
continue;
|
||||||
++number_of_visible_entries;
|
++number_of_visible_entries;
|
||||||
@ -81,6 +84,8 @@ void GBoxLayout::run(GWidget& widget)
|
|||||||
int current_y = margins().top();
|
int current_y = margins().top();
|
||||||
|
|
||||||
for (auto& entry : m_entries) {
|
for (auto& entry : m_entries) {
|
||||||
|
if (!entry.widget)
|
||||||
|
continue;
|
||||||
if (!entry.widget->is_visible())
|
if (!entry.widget->is_visible())
|
||||||
continue;
|
continue;
|
||||||
Rect rect(current_x, current_y, 0, 0);
|
Rect rect(current_x, current_y, 0, 0);
|
||||||
|
@ -268,6 +268,17 @@ void GEventLoop::handle_menu_event(const WSAPI_ServerMessage& event)
|
|||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GEventLoop::handle_wm_event(const WSAPI_ServerMessage& event, GWindow& window)
|
||||||
|
{
|
||||||
|
if (event.type == WSAPI_ServerMessage::WM_WindowAdded)
|
||||||
|
return post_event(window, make<GWMWindowAddedEvent>(event.wm.client_id, event.wm.window_id, String(event.text, event.text_length), event.wm.rect));
|
||||||
|
if (event.type == WSAPI_ServerMessage::WM_WindowStateChanged)
|
||||||
|
return post_event(window, make<GWMWindowStateChangedEvent>(event.wm.client_id, event.wm.window_id, String(event.text, event.text_length), event.wm.rect));
|
||||||
|
if (event.type == WSAPI_ServerMessage::WM_WindowRemoved)
|
||||||
|
return post_event(window, make<GWMWindowRemovedEvent>(event.wm.client_id, event.wm.window_id));
|
||||||
|
ASSERT_NOT_REACHED();
|
||||||
|
}
|
||||||
|
|
||||||
void GEventLoop::wait_for_event()
|
void GEventLoop::wait_for_event()
|
||||||
{
|
{
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
@ -397,6 +408,11 @@ void GEventLoop::process_unprocessed_messages()
|
|||||||
case WSAPI_ServerMessage::Type::WindowResized:
|
case WSAPI_ServerMessage::Type::WindowResized:
|
||||||
handle_resize_event(event, *window);
|
handle_resize_event(event, *window);
|
||||||
break;
|
break;
|
||||||
|
case WSAPI_ServerMessage::Type::WM_WindowAdded:
|
||||||
|
case WSAPI_ServerMessage::Type::WM_WindowRemoved:
|
||||||
|
case WSAPI_ServerMessage::Type::WM_WindowStateChanged:
|
||||||
|
handle_wm_event(event, *window);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -60,6 +60,7 @@ private:
|
|||||||
void handle_window_close_request_event(const WSAPI_ServerMessage&, GWindow&);
|
void handle_window_close_request_event(const WSAPI_ServerMessage&, GWindow&);
|
||||||
void handle_menu_event(const WSAPI_ServerMessage&);
|
void handle_menu_event(const WSAPI_ServerMessage&);
|
||||||
void handle_window_entered_or_left_event(const WSAPI_ServerMessage&, GWindow&);
|
void handle_window_entered_or_left_event(const WSAPI_ServerMessage&, GWindow&);
|
||||||
|
void handle_wm_event(const WSAPI_ServerMessage&, GWindow&);
|
||||||
void get_next_timer_expiration(timeval&);
|
void get_next_timer_expiration(timeval&);
|
||||||
void connect_to_server();
|
void connect_to_server();
|
||||||
|
|
||||||
|
@ -40,6 +40,15 @@ void GLayout::add_widget(GWidget& widget)
|
|||||||
m_owner->notify_layout_changed(Badge<GLayout>());
|
m_owner->notify_layout_changed(Badge<GLayout>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLayout::remove_widget(GWidget& widget)
|
||||||
|
{
|
||||||
|
m_entries.remove_first_matching([&] (auto& entry) {
|
||||||
|
return entry.widget.ptr() == &widget;
|
||||||
|
});
|
||||||
|
if (m_owner)
|
||||||
|
m_owner->notify_layout_changed(Badge<GLayout>());
|
||||||
|
}
|
||||||
|
|
||||||
void GLayout::set_spacing(int spacing)
|
void GLayout::set_spacing(int spacing)
|
||||||
{
|
{
|
||||||
if (m_spacing == spacing)
|
if (m_spacing == spacing)
|
||||||
|
@ -16,6 +16,8 @@ public:
|
|||||||
void add_widget(GWidget&);
|
void add_widget(GWidget&);
|
||||||
void add_layout(OwnPtr<GLayout>&&);
|
void add_layout(OwnPtr<GLayout>&&);
|
||||||
|
|
||||||
|
void remove_widget(GWidget&);
|
||||||
|
|
||||||
virtual void run(GWidget&) = 0;
|
virtual void run(GWidget&) = 0;
|
||||||
|
|
||||||
void notify_adopted(Badge<GWidget>, GWidget&);
|
void notify_adopted(Badge<GWidget>, GWidget&);
|
||||||
|
@ -27,6 +27,10 @@ void GWidget::child_event(GChildEvent& event)
|
|||||||
if (event.child() && event.child()->is_widget() && layout())
|
if (event.child() && event.child()->is_widget() && layout())
|
||||||
layout()->add_widget(static_cast<GWidget&>(*event.child()));
|
layout()->add_widget(static_cast<GWidget&>(*event.child()));
|
||||||
}
|
}
|
||||||
|
if (event.type() == GEvent::ChildRemoved) {
|
||||||
|
if (event.child() && event.child()->is_widget() && layout())
|
||||||
|
layout()->remove_widget(static_cast<GWidget&>(*event.child()));
|
||||||
|
}
|
||||||
return GObject::child_event(event);
|
return GObject::child_event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +91,9 @@ struct WSAPI_ServerMessage {
|
|||||||
DidSetWallpaper,
|
DidSetWallpaper,
|
||||||
DidGetWallpaper,
|
DidGetWallpaper,
|
||||||
ScreenRectChanged,
|
ScreenRectChanged,
|
||||||
|
WM_WindowAdded,
|
||||||
|
WM_WindowRemoved,
|
||||||
|
WM_WindowStateChanged,
|
||||||
};
|
};
|
||||||
Type type { Invalid };
|
Type type { Invalid };
|
||||||
int window_id { -1 };
|
int window_id { -1 };
|
||||||
@ -103,6 +106,11 @@ struct WSAPI_ServerMessage {
|
|||||||
int server_pid;
|
int server_pid;
|
||||||
WSAPI_Rect screen_rect;
|
WSAPI_Rect screen_rect;
|
||||||
} greeting;
|
} greeting;
|
||||||
|
struct {
|
||||||
|
int client_id;
|
||||||
|
int window_id;
|
||||||
|
WSAPI_Rect rect;
|
||||||
|
} wm;
|
||||||
struct {
|
struct {
|
||||||
WSAPI_Rect rect;
|
WSAPI_Rect rect;
|
||||||
} screen;
|
} screen;
|
||||||
|
@ -26,6 +26,10 @@ public:
|
|||||||
WindowCloseRequest,
|
WindowCloseRequest,
|
||||||
WindowResized,
|
WindowResized,
|
||||||
|
|
||||||
|
WM_WindowAdded,
|
||||||
|
WM_WindowRemoved,
|
||||||
|
WM_WindowStateChanged,
|
||||||
|
|
||||||
__Begin_API_Client_Requests,
|
__Begin_API_Client_Requests,
|
||||||
APICreateMenubarRequest,
|
APICreateMenubarRequest,
|
||||||
APIDestroyMenubarRequest,
|
APIDestroyMenubarRequest,
|
||||||
@ -581,3 +585,62 @@ private:
|
|||||||
Rect m_old_rect;
|
Rect m_old_rect;
|
||||||
Rect m_rect;
|
Rect m_rect;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class WSWMEvent : public WSMessage {
|
||||||
|
public:
|
||||||
|
WSWMEvent(Type type, int client_id, int window_id)
|
||||||
|
: WSMessage(type)
|
||||||
|
, m_client_id(client_id)
|
||||||
|
, m_window_id(window_id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int client_id() const { return m_client_id; }
|
||||||
|
int window_id() const { return m_window_id; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int m_client_id;
|
||||||
|
int m_window_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WSWMWindowAddedEvent : public WSWMEvent {
|
||||||
|
public:
|
||||||
|
WSWMWindowAddedEvent(int client_id, int window_id, const String& title, const Rect& rect)
|
||||||
|
: WSWMEvent(WSMessage::WM_WindowAdded, client_id, window_id)
|
||||||
|
, m_title(title)
|
||||||
|
, m_rect(rect)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
String title() const { return m_title; }
|
||||||
|
Rect rect() const { return m_rect; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
String m_title;
|
||||||
|
Rect m_rect;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WSWMWindowRemovedEvent : public WSWMEvent {
|
||||||
|
public:
|
||||||
|
WSWMWindowRemovedEvent(int client_id, int window_id)
|
||||||
|
: WSWMEvent(WSMessage::WM_WindowRemoved, client_id, window_id)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class WSWMWindowStateChangedEvent : public WSWMEvent {
|
||||||
|
public:
|
||||||
|
WSWMWindowStateChangedEvent(int client_id, int window_id, const String& title, const Rect& rect)
|
||||||
|
: WSWMEvent(WSMessage::WM_WindowStateChanged, client_id, window_id)
|
||||||
|
, m_title(title)
|
||||||
|
, m_rect(rect)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
String title() const { return m_title; }
|
||||||
|
Rect rect() const { return m_rect; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
String m_title;
|
||||||
|
Rect m_rect;
|
||||||
|
};
|
||||||
|
@ -28,6 +28,9 @@ WSWindow::WSWindow(WSClientConnection& client, WSWindowType window_type, int win
|
|||||||
, m_window_id(window_id)
|
, m_window_id(window_id)
|
||||||
, m_icon(default_window_icon())
|
, m_icon(default_window_icon())
|
||||||
{
|
{
|
||||||
|
// FIXME: This should not be hard-coded here.
|
||||||
|
if (m_type == WSWindowType::Taskbar)
|
||||||
|
m_listens_to_wm_events = true;
|
||||||
WSWindowManager::the().add_window(*this);
|
WSWindowManager::the().add_window(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,6 +141,36 @@ void WSWindow::on_message(const WSMessage& message)
|
|||||||
server_message.window.old_rect = static_cast<const WSResizeEvent&>(message).old_rect();
|
server_message.window.old_rect = static_cast<const WSResizeEvent&>(message).old_rect();
|
||||||
server_message.window.rect = static_cast<const WSResizeEvent&>(message).rect();
|
server_message.window.rect = static_cast<const WSResizeEvent&>(message).rect();
|
||||||
break;
|
break;
|
||||||
|
case WSMessage::WM_WindowAdded: {
|
||||||
|
auto& added_event = static_cast<const WSWMWindowAddedEvent&>(message);
|
||||||
|
server_message.type = WSAPI_ServerMessage::Type::WM_WindowAdded;
|
||||||
|
server_message.wm.client_id = added_event.client_id();
|
||||||
|
server_message.wm.window_id = added_event.window_id();
|
||||||
|
ASSERT(added_event.title().length() < sizeof(server_message.text));
|
||||||
|
memcpy(server_message.text, added_event.title().characters(), added_event.title().length());
|
||||||
|
server_message.text_length = added_event.title().length();
|
||||||
|
server_message.wm.rect = added_event.rect();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WSMessage::WM_WindowRemoved: {
|
||||||
|
auto& removed_event = static_cast<const WSWMWindowRemovedEvent&>(message);
|
||||||
|
server_message.type = WSAPI_ServerMessage::Type::WM_WindowRemoved;
|
||||||
|
server_message.wm.client_id = removed_event.client_id();
|
||||||
|
server_message.wm.window_id = removed_event.window_id();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WSMessage::WM_WindowStateChanged: {
|
||||||
|
auto& changed_event = static_cast<const WSWMWindowStateChangedEvent&>(message);
|
||||||
|
server_message.type = WSAPI_ServerMessage::Type::WM_WindowStateChanged;
|
||||||
|
server_message.wm.client_id = changed_event.client_id();
|
||||||
|
server_message.wm.window_id = changed_event.window_id();
|
||||||
|
ASSERT(changed_event.title().length() < sizeof(server_message.text));
|
||||||
|
memcpy(server_message.text, changed_event.title().characters(), changed_event.title().length());
|
||||||
|
server_message.text_length = changed_event.title().length();
|
||||||
|
server_message.wm.rect = changed_event.rect();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,8 @@ public:
|
|||||||
|
|
||||||
bool is_blocked_by_modal_window() const;
|
bool is_blocked_by_modal_window() const;
|
||||||
|
|
||||||
|
bool listens_to_wm_events() const { return m_listens_to_wm_events; }
|
||||||
|
|
||||||
WSClientConnection* client() { return m_client; }
|
WSClientConnection* client() { return m_client; }
|
||||||
const WSClientConnection* client() const { return m_client; }
|
const WSClientConnection* client() const { return m_client; }
|
||||||
|
|
||||||
@ -124,6 +126,7 @@ private:
|
|||||||
bool m_has_painted_since_last_resize { false };
|
bool m_has_painted_since_last_resize { false };
|
||||||
bool m_modal { false };
|
bool m_modal { false };
|
||||||
bool m_resizable { false };
|
bool m_resizable { false };
|
||||||
|
bool m_listens_to_wm_events { false };
|
||||||
RetainPtr<GraphicsBitmap> m_backing_store;
|
RetainPtr<GraphicsBitmap> m_backing_store;
|
||||||
RetainPtr<GraphicsBitmap> m_last_backing_store;
|
RetainPtr<GraphicsBitmap> m_last_backing_store;
|
||||||
int m_window_id { -1 };
|
int m_window_id { -1 };
|
||||||
|
@ -294,7 +294,7 @@ void get_cpu_usage(unsigned& busy, unsigned& idle)
|
|||||||
FILE* fp = fopen("/proc/all", "r");
|
FILE* fp = fopen("/proc/all", "r");
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
perror("failed to open /proc/all");
|
perror("failed to open /proc/all");
|
||||||
exit(1);
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
for (;;) {
|
for (;;) {
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
@ -507,6 +507,12 @@ void WSWindowManager::add_window(WSWindow& window)
|
|||||||
set_active_window(&window);
|
set_active_window(&window);
|
||||||
if (m_switcher.is_visible() && window.type() != WSWindowType::WindowSwitcher)
|
if (m_switcher.is_visible() && window.type() != WSWindowType::WindowSwitcher)
|
||||||
m_switcher.refresh();
|
m_switcher.refresh();
|
||||||
|
|
||||||
|
for_each_window_listening_to_wm_events([&window] (WSWindow& listener) {
|
||||||
|
if (window.client())
|
||||||
|
WSMessageLoop::the().post_message(listener, make<WSWMWindowAddedEvent>(window.client()->client_id(), window.window_id(), window.title(), window.rect()));
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSWindowManager::move_to_front_and_make_active(WSWindow& window)
|
void WSWindowManager::move_to_front_and_make_active(WSWindow& window)
|
||||||
@ -534,6 +540,12 @@ void WSWindowManager::remove_window(WSWindow& window)
|
|||||||
set_active_window(*m_windows.begin());
|
set_active_window(*m_windows.begin());
|
||||||
if (m_switcher.is_visible() && window.type() != WSWindowType::WindowSwitcher)
|
if (m_switcher.is_visible() && window.type() != WSWindowType::WindowSwitcher)
|
||||||
m_switcher.refresh();
|
m_switcher.refresh();
|
||||||
|
|
||||||
|
for_each_window_listening_to_wm_events([&window] (WSWindow& listener) {
|
||||||
|
if (window.client())
|
||||||
|
WSMessageLoop::the().post_message(listener, make<WSWMWindowRemovedEvent>(window.client()->client_id(), window.window_id()));
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSWindowManager::notify_title_changed(WSWindow& window)
|
void WSWindowManager::notify_title_changed(WSWindow& window)
|
||||||
@ -542,6 +554,12 @@ void WSWindowManager::notify_title_changed(WSWindow& window)
|
|||||||
invalidate(outer_window_rect(window));
|
invalidate(outer_window_rect(window));
|
||||||
if (m_switcher.is_visible())
|
if (m_switcher.is_visible())
|
||||||
m_switcher.refresh();
|
m_switcher.refresh();
|
||||||
|
|
||||||
|
for_each_window_listening_to_wm_events([&window] (WSWindow& listener) {
|
||||||
|
if (window.client())
|
||||||
|
WSMessageLoop::the().post_message(listener, make<WSWMWindowStateChangedEvent>(window.client()->client_id(), window.window_id(), window.title(), window.rect()));
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSWindowManager::notify_rect_changed(WSWindow& window, const Rect& old_rect, const Rect& new_rect)
|
void WSWindowManager::notify_rect_changed(WSWindow& window, const Rect& old_rect, const Rect& new_rect)
|
||||||
@ -553,6 +571,12 @@ void WSWindowManager::notify_rect_changed(WSWindow& window, const Rect& old_rect
|
|||||||
invalidate(outer_window_rect(new_rect));
|
invalidate(outer_window_rect(new_rect));
|
||||||
if (m_switcher.is_visible() && window.type() != WSWindowType::WindowSwitcher)
|
if (m_switcher.is_visible() && window.type() != WSWindowType::WindowSwitcher)
|
||||||
m_switcher.refresh();
|
m_switcher.refresh();
|
||||||
|
|
||||||
|
for_each_window_listening_to_wm_events([&window] (WSWindow& listener) {
|
||||||
|
if (window.client())
|
||||||
|
WSMessageLoop::the().post_message(listener, make<WSWMWindowStateChangedEvent>(window.client()->client_id(), window.window_id(), window.title(), window.rect()));
|
||||||
|
return IterationDecision::Continue;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSWindowManager::handle_menu_mouse_event(WSMenu& menu, const WSMouseEvent& event)
|
void WSWindowManager::handle_menu_mouse_event(WSMenu& menu, const WSMouseEvent& event)
|
||||||
|
@ -112,6 +112,7 @@ private:
|
|||||||
template<typename Callback> IterationDecision for_each_visible_window_of_type_from_front_to_back(WSWindowType, Callback);
|
template<typename Callback> IterationDecision for_each_visible_window_of_type_from_front_to_back(WSWindowType, Callback);
|
||||||
template<typename Callback> IterationDecision for_each_visible_window_from_front_to_back(Callback);
|
template<typename Callback> IterationDecision for_each_visible_window_from_front_to_back(Callback);
|
||||||
template<typename Callback> IterationDecision for_each_visible_window_from_back_to_front(Callback);
|
template<typename Callback> IterationDecision for_each_visible_window_from_back_to_front(Callback);
|
||||||
|
template<typename Callback> void for_each_window_listening_to_wm_events(Callback);
|
||||||
template<typename Callback> void for_each_active_menubar_menu(Callback);
|
template<typename Callback> void for_each_active_menubar_menu(Callback);
|
||||||
void close_current_menu();
|
void close_current_menu();
|
||||||
virtual void on_message(const WSMessage&) override;
|
virtual void on_message(const WSMessage&) override;
|
||||||
@ -265,3 +266,14 @@ IterationDecision WSWindowManager::for_each_visible_window_from_front_to_back(Ca
|
|||||||
return IterationDecision::Abort;
|
return IterationDecision::Abort;
|
||||||
return for_each_visible_window_of_type_from_front_to_back(WSWindowType::WindowSwitcher, callback);
|
return for_each_visible_window_of_type_from_front_to_back(WSWindowType::WindowSwitcher, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Callback>
|
||||||
|
void WSWindowManager::for_each_window_listening_to_wm_events(Callback callback)
|
||||||
|
{
|
||||||
|
for (auto* window = m_windows_in_order.tail(); window; window = window->prev()) {
|
||||||
|
if (!window->listens_to_wm_events())
|
||||||
|
continue;
|
||||||
|
if (callback(*window) == IterationDecision::Abort)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user