From 48d4029cc7b74a8a9ac6fbdaf3de9901ada03847 Mon Sep 17 00:00:00 2001 From: JJ Roberts-White Date: Sun, 4 Jul 2021 11:33:04 +0000 Subject: [PATCH] One connection to LemonWM per process (not per window) --- Applications/DeviceManager/main.cpp | 4 +- Applications/FileManager/main.cpp | 5 +- Applications/GUITest/main.cpp | 5 +- Applications/ImgView/main.cpp | 21 +-- Applications/LemonMonitor/main.cpp | 6 +- Applications/Minesweeper/main.cpp | 5 +- Applications/Run/main.cpp | 4 +- Applications/Shell/main.cpp | 8 +- Applications/Shell/menu.cpp | 10 +- Applications/Snake/main.cpp | 6 + Applications/SysInfo/main.cpp | 4 +- Applications/Terminal/main.cpp | 4 +- Applications/TextEdit/main.cpp | 5 +- LibGUI/include/Lemon/GUI/Widgets.h | 1 + LibGUI/include/Lemon/GUI/Window.h | 78 ++++------ LibGUI/include/Lemon/GUI/WindowServer.h | 46 ++++++ LibGUI/meson.build | 15 +- LibGUI/src/{colours.cpp => Colours.cpp} | 0 LibGUI/src/{filedialog.cpp => FileDialog.cpp} | 5 +- LibGUI/src/{fileview.cpp => FileView.cpp} | 0 LibGUI/src/{image.cpp => Image.cpp} | 0 LibGUI/src/{messagebox.cpp => MessageBox.cpp} | 4 + LibGUI/src/{widgets.cpp => Widgets.cpp} | 6 +- LibGUI/src/{window.cpp => Window.cpp} | 119 ++++----------- LibGUI/src/WindowServer.cpp | 59 ++++++++ LibLemon/include/Lemon/System/IPC.h | 28 +++- Services/lemon.lemonwm.li | 24 ++-- System/LemonWM/WM.cpp | 136 ++++++++++-------- System/LemonWM/WM.h | 49 ++++--- System/LemonWM/Window.cpp | 15 +- System/Login/main.cpp | 4 +- 31 files changed, 386 insertions(+), 290 deletions(-) create mode 100644 LibGUI/include/Lemon/GUI/WindowServer.h rename LibGUI/src/{colours.cpp => Colours.cpp} (100%) rename LibGUI/src/{filedialog.cpp => FileDialog.cpp} (97%) rename LibGUI/src/{fileview.cpp => FileView.cpp} (100%) rename LibGUI/src/{image.cpp => Image.cpp} (100%) rename LibGUI/src/{messagebox.cpp => MessageBox.cpp} (94%) rename LibGUI/src/{widgets.cpp => Widgets.cpp} (99%) rename LibGUI/src/{window.cpp => Window.cpp} (73%) create mode 100644 LibGUI/src/WindowServer.cpp diff --git a/Applications/DeviceManager/main.cpp b/Applications/DeviceManager/main.cpp index 9c9f30c0..7a3714e7 100644 --- a/Applications/DeviceManager/main.cpp +++ b/Applications/DeviceManager/main.cpp @@ -128,13 +128,15 @@ int main(int argc, char** argv){ lv->SetModel(&model); while(!window->closed){ + Lemon::WindowServer::Instance()->Poll(); + Lemon::LemonEvent ev; while(window->PollEvent(ev)){ window->GUIHandleEvent(ev); } window->Paint(); - window->WaitEvent(); + Lemon::WindowServer::Instance()->Wait(); } return 0; diff --git a/Applications/FileManager/main.cpp b/Applications/FileManager/main.cpp index bed58b23..fc58b947 100755 --- a/Applications/FileManager/main.cpp +++ b/Applications/FileManager/main.cpp @@ -36,14 +36,15 @@ int main(int argc, char** argv){ fv->SetLayout(Lemon::GUI::LayoutSize::Stretch, Lemon::GUI::LayoutSize::Stretch, Lemon::GUI::WidgetAlignment::WAlignLeft); while(!window->closed){ + Lemon::WindowServer::Instance()->Poll(); + Lemon::LemonEvent ev; while(window->PollEvent(ev)){ window->GUIHandleEvent(ev); } window->Paint(); - - window->WaitEvent(); + Lemon::WindowServer::Instance()->Wait(); } delete window; diff --git a/Applications/GUITest/main.cpp b/Applications/GUITest/main.cpp index 56b50dd3..3174084c 100755 --- a/Applications/GUITest/main.cpp +++ b/Applications/GUITest/main.cpp @@ -93,14 +93,15 @@ int main(){ cxt.push_back(ent); while(!win->closed){ + Lemon::WindowServer::Instance()->Poll(); + Lemon::LemonEvent ev; while(win->PollEvent(ev)){ win->GUIHandleEvent(ev); } win->Paint(); - - win->WaitEvent(); + Lemon::WindowServer::Instance()->Wait(); } delete win; diff --git a/Applications/ImgView/main.cpp b/Applications/ImgView/main.cpp index 39e33c1e..7e5427e1 100755 --- a/Applications/ImgView/main.cpp +++ b/Applications/ImgView/main.cpp @@ -55,19 +55,11 @@ void OnWindowCmd(unsigned short cmd, Lemon::GUI::Window* win){ } int main(int argc, char** argv){ - window = new Lemon::GUI::Window("Image Viewer", {800, 500}, WINDOW_FLAGS_RESIZABLE, Lemon::GUI::WindowType::GUI); - window->CreateMenuBar(); - - window->menuBar->items.push_back(fileMenu); - window->menuBar->items.push_back(viewMenu); - window->OnMenuCmd = OnWindowCmd; imgWidget = new Lemon::GUI::Image({{0, 0}, {0, 0}}); imgWidget->SetLayout(Lemon::GUI::LayoutSize::Stretch, Lemon::GUI::LayoutSize::Stretch); imgWidget->SetScaling(Lemon::Graphics::Texture::TextureScaling::ScaleFit); - window->AddWidget(imgWidget); - if(argc > 1){ if(LoadImage(argv[1])){ return -1; @@ -76,13 +68,24 @@ int main(int argc, char** argv){ return -1; } + window = new Lemon::GUI::Window("Image Viewer", {800, 500}, WINDOW_FLAGS_RESIZABLE, Lemon::GUI::WindowType::GUI); + window->CreateMenuBar(); + + window->menuBar->items.push_back(fileMenu); + window->menuBar->items.push_back(viewMenu); + window->OnMenuCmd = OnWindowCmd; + + window->AddWidget(imgWidget); + while(!window->closed){ + Lemon::WindowServer::Instance()->Poll(); + Lemon::LemonEvent ev; while(window->PollEvent(ev)){ window->GUIHandleEvent(ev); } window->Paint(); - window->WaitEvent(); + Lemon::WindowServer::Instance()->Wait(); } } \ No newline at end of file diff --git a/Applications/LemonMonitor/main.cpp b/Applications/LemonMonitor/main.cpp index 0aa262b6..2d40ec1a 100644 --- a/Applications/LemonMonitor/main.cpp +++ b/Applications/LemonMonitor/main.cpp @@ -136,8 +136,8 @@ int main(int argc, char** argv){ paint = true; // Refresh processes every 800ms } + Lemon::WindowServer::Instance()->Poll(); Lemon::LemonEvent ev; - while(window->PollEvent(ev)){ window->GUIHandleEvent(ev); @@ -147,8 +147,8 @@ int main(int argc, char** argv){ if(paint){ window->Paint(); } - - window->WaitEvent(800000); // Wait up to 800ms + + Lemon::WindowServer::Instance()->Wait(800000); } return 0; diff --git a/Applications/Minesweeper/main.cpp b/Applications/Minesweeper/main.cpp index 5831f7da..581d0d62 100644 --- a/Applications/Minesweeper/main.cpp +++ b/Applications/Minesweeper/main.cpp @@ -283,6 +283,8 @@ int main(int argc, char** argv){ window->Paint(); while(!window->closed){ + Lemon::WindowServer::Instance()->Poll(); + Lemon::LemonEvent ev; while (window->PollEvent(ev)) { @@ -308,8 +310,7 @@ int main(int argc, char** argv){ } window->Paint(); - - window->WaitEvent(); + Lemon::WindowServer::Instance()->Wait(); } delete window; diff --git a/Applications/Run/main.cpp b/Applications/Run/main.cpp index 4b756a31..6aec3532 100644 --- a/Applications/Run/main.cpp +++ b/Applications/Run/main.cpp @@ -97,13 +97,15 @@ int main(int argc, char** argv){ window->AddWidget(okButton); while(!window->closed){ + Lemon::WindowServer::Instance()->Poll(); + Lemon::LemonEvent ev; while(window->PollEvent(ev)){ window->GUIHandleEvent(ev); } window->Paint(); - window->WaitEvent(); + Lemon::WindowServer::Instance()->Wait(); } return 0; diff --git a/Applications/Shell/main.cpp b/Applications/Shell/main.cpp index d22df08a..8cfb2b71 100755 --- a/Applications/Shell/main.cpp +++ b/Applications/Shell/main.cpp @@ -103,6 +103,10 @@ void OnTaskbarPaint(surface_t* surface){ } int main(){ + if(chdir("/system")){ + return 1; + } + handle_t svc = Lemon::CreateService("lemon.shell"); shell = new ShellInstance(svc, "Instance"); @@ -134,10 +138,10 @@ int main(){ Lemon::Waiter waiter; waiter.WaitOnAll(&shell->GetInterface()); - waiter.WaitOn(taskbar); - waiter.WaitOn(menuWindow); + waiter.WaitOn(Lemon::WindowServer::Instance()); for(;;){ + Lemon::WindowServer::Instance()->Poll(); shell->Poll(); Lemon::LemonEvent ev; diff --git a/Applications/Shell/menu.cpp b/Applications/Shell/menu.cpp index 7ddcca2e..0b6c71bf 100644 --- a/Applications/Shell/menu.cpp +++ b/Applications/Shell/menu.cpp @@ -197,17 +197,21 @@ Lemon::GUI::Window* InitializeMenu(){ menuWindow = new Lemon::GUI::Window("", {MENU_WIDTH, MENU_HEIGHT}, WINDOW_FLAGS_NODECORATION | WINDOW_FLAGS_NOSHELL | WINDOW_FLAGS_ALWAYS_ACTIVE, Lemon::GUI::GUI); - vector2i_t screenBounds = menuWindow->GetScreenBounds(); + vector2i_t screenBounds = Lemon::WindowServer::Instance()->GetScreenBounds(); menuWindow->Relocate({ screenBounds.x / 2 - 200, screenBounds.y / 2 - 150 }); listView = new Lemon::GUI::ListView({0, 0, 0, 24}); - menuWindow->AddWidget(listView); - listView->SetLayout(Lemon::GUI::LayoutSize::Stretch, Lemon::GUI::LayoutSize::Stretch, Lemon::GUI::WidgetAlignment::WAlignLeft, Lemon::GUI::WidgetAlignment::WAlignBottom); listView->SetModel(&menuModel); listView->displayColumnNames = false; + listView->drawBackground = false; filterBox = new Lemon::GUI::TextBox({0, 0, 0, 24}, false); + + menuWindow->AddWidget(listView); menuWindow->AddWidget(filterBox); + menuWindow->SetActive(filterBox); + + listView->SetLayout(Lemon::GUI::LayoutSize::Stretch, Lemon::GUI::LayoutSize::Stretch, Lemon::GUI::WidgetAlignment::WAlignLeft, Lemon::GUI::WidgetAlignment::WAlignBottom); filterBox->SetLayout(Lemon::GUI::LayoutSize::Stretch, Lemon::GUI::LayoutSize::Fixed, Lemon::GUI::WidgetAlignment::WAlignLeft, Lemon::GUI::WidgetAlignment::WAlignTop); const char* itemsPath = "/system/lemon/menu/"; diff --git a/Applications/Snake/main.cpp b/Applications/Snake/main.cpp index c875b52d..d100b836 100755 --- a/Applications/Snake/main.cpp +++ b/Applications/Snake/main.cpp @@ -39,6 +39,8 @@ void GameOverLoop(){ win->SwapBuffers(); while(!win->closed && gameOver){ + Lemon::WindowServer::Instance()->Poll(); + Lemon::LemonEvent ev; while(win->PollEvent(ev)){ if(ev.event == Lemon::EventKeyPressed){ @@ -50,6 +52,8 @@ void GameOverLoop(){ exit(0); } } + + Lemon::WindowServer::Instance()->Wait(); } } @@ -86,6 +90,8 @@ int main(){ Reset(); while(!win->closed){ + Lemon::WindowServer::Instance()->Poll(); + Lemon::LemonEvent ev; while(win->PollEvent(ev)){ if(ev.event == Lemon::EventKeyPressed){ diff --git a/Applications/SysInfo/main.cpp b/Applications/SysInfo/main.cpp index b688a735..e0496570 100755 --- a/Applications/SysInfo/main.cpp +++ b/Applications/SysInfo/main.cpp @@ -50,6 +50,8 @@ int main(int argc, char** argv){ ypos += 16; while(!window->closed){ + Lemon::WindowServer::Instance()->Poll(); + Lemon::LemonEvent ev; while(window->PollEvent(ev)){ window->GUIHandleEvent(ev); @@ -64,6 +66,6 @@ int main(int argc, char** argv){ usedMem->label = buf; } sysInfo = _sysInfo; - window->WaitEvent(); + Lemon::WindowServer::Instance()->Wait(); } } \ No newline at end of file diff --git a/Applications/Terminal/main.cpp b/Applications/Terminal/main.cpp index 778a2cc2..9719abf0 100755 --- a/Applications/Terminal/main.cpp +++ b/Applications/Terminal/main.cpp @@ -585,6 +585,8 @@ int main(int argc, char** argv){ } for(;;){ + Lemon::WindowServer::Instance()->Poll(); + Lemon::LemonEvent ev; while(window->PollEvent(ev)){ if(ev.event == Lemon::EventKeyPressed){ @@ -640,7 +642,7 @@ int main(int argc, char** argv){ paintAll = false; } - window->WaitEvent(); + Lemon::WindowServer::Instance()->Wait(); } return 0; diff --git a/Applications/TextEdit/main.cpp b/Applications/TextEdit/main.cpp index 4aa97c6a..37da7f11 100755 --- a/Applications/TextEdit/main.cpp +++ b/Applications/TextEdit/main.cpp @@ -166,14 +166,15 @@ int main(int argc, char** argv){ } while(!window->closed){ + Lemon::WindowServer::Instance()->Poll(); + Lemon::LemonEvent ev; while(window->PollEvent(ev)){ window->GUIHandleEvent(ev); } window->Paint(); - - window->WaitEvent(); + Lemon::WindowServer::Instance()->Wait(); } delete window; diff --git a/LibGUI/include/Lemon/GUI/Widgets.h b/LibGUI/include/Lemon/GUI/Widgets.h index 090838e8..e0ab5fb2 100755 --- a/LibGUI/include/Lemon/GUI/Widgets.h +++ b/LibGUI/include/Lemon/GUI/Widgets.h @@ -326,6 +326,7 @@ namespace Lemon::GUI { int selected = 0; bool displayColumnNames = true; + bool drawBackground = true; protected: DataModel* model = nullptr; diff --git a/LibGUI/include/Lemon/GUI/Window.h b/LibGUI/include/Lemon/GUI/Window.h index 0b09e455..feeaba84 100755 --- a/LibGUI/include/Lemon/GUI/Window.h +++ b/LibGUI/include/Lemon/GUI/Window.h @@ -1,14 +1,11 @@ #pragma once -#include #include - +#include +#include #include #include -#include - -//#include -#include +#include #include #include @@ -55,20 +52,18 @@ namespace Lemon::GUI { void OnMouseMove(vector2i_t mousePos); }; - class Window : - LemonWMClient, public LemonWMServerEndpoint { + class Window final { + friend class Lemon::WindowServer; public: Window(const char* title, vector2i_t size, uint32_t flags = 0, int type = WindowType::Basic, vector2i_t pos = {20, 20}); ~Window(); - //inline void InitializeShellConnection() { LemonWMServerEndpoint::InitializeShellConnection(); } - ///////////////////////////// /// \brief Set title of window /// /// \param name Service name to be used, must be unique ///////////////////////////// - inline void SetTitle(const std::string& title) { LemonWMServerEndpoint::SetTitle(title); } + void SetTitle(const std::string& title); ///////////////////////////// /// \brief Relocate window @@ -77,7 +72,7 @@ namespace Lemon::GUI { /// /// \param pos New position of window ///////////////////////////// - inline void Relocate(vector2i_t pos) { LemonWMServerEndpoint::Relocate(pos.x, pos.y); } + void Relocate(vector2i_t pos); ///////////////////////////// /// \brief Resize window @@ -89,30 +84,30 @@ namespace Lemon::GUI { void Resize(vector2i_t size); ///////////////////////////// - /// \brief Minimize window + /// \brief Minimize a window /// - /// Show/hide the window on screen + /// Show/hide the specified window on screen /// + /// \param windowID Window to show/hide /// \param minimized Whether to show/hide the window ///////////////////////////// - inline void Minimize(bool minimized = true) { LemonWMServerEndpoint::Minimize(windowID, minimized); } + void Minimize(int windowID, bool minimized); ///////////////////////////// - /// \brief Minimize a window + /// \brief Minimize window /// - /// Show/hide the specified window on screen + /// Show/hide the window on screen /// - /// \param windowID Window to show/hide /// \param minimized Whether to show/hide the window ///////////////////////////// - inline void Minimize(int windowID, bool minimized) { LemonWMServerEndpoint::Minimize(windowID, minimized); } + inline void Minimize(bool minimized = true) { Minimize(ID(), minimized); } ///////////////////////////// /// \brief Update window flags /// /// \param flags New Flags ///////////////////////////// - inline void UpdateFlags(uint32_t flags) { this->flags = flags; LemonWMServerEndpoint::UpdateFlags(flags); } + void UpdateFlags(uint32_t flags); ///////////////////////////// /// \brief Paint window @@ -129,7 +124,7 @@ namespace Lemon::GUI { void SwapBuffers(); ///////////////////////////// - /// \brief Poll the window for events + /// \brief Check the event queue for events. /// /// Fill ev with an event if an event has been found and return true, otherwise return false /// @@ -138,15 +133,6 @@ namespace Lemon::GUI { /// \return true when an event has been received, false when there was no event ///////////////////////////// bool PollEvent(LemonEvent& ev); - - ///////////////////////////// - /// \brief Wait for an event - /// - /// \param timeout Timeout in microseconds - /// - /// Blocks the thread until an event has been recieved - ///////////////////////////// - void WaitEvent(long timeout = -1); ///////////////////////////// /// \brief Send event @@ -223,6 +209,13 @@ namespace Lemon::GUI { ///////////////////////////// inline uint32_t GetFlags() const { return flags; } + ///////////////////////////// + /// \brief Get Window ID + /// + /// \return window id + ///////////////////////////// + inline long ID() const { return windowID; } + ///////////////////////////// /// \brief Get Window Size /// @@ -235,22 +228,7 @@ namespace Lemon::GUI { /// /// \return window position ///////////////////////////// - inline vector2i_t GetPosition() { - auto pos = LemonWMServerEndpoint::GetPosition(); - - return { pos.x, pos.y }; - }; - - ///////////////////////////// - /// \brief Get Screen Bounds - /// - /// \return screen width and height - ///////////////////////////// - inline vector2i_t GetScreenBounds() { - auto b = LemonWMServerEndpoint::GetScreenBounds(); - - return { b.width, b.height }; - }; + vector2i_t GetPosition(); ///////////////////////////// /// \brief OnPaint callback @@ -274,17 +252,13 @@ namespace Lemon::GUI { bool closed = false; // Set to true when close button pressed private: - void OnPeerDisconnect(handle_t client); - void OnSendEvent(handle_t client, int32_t id, uint64_t data); - void OnPing(handle_t client); - class TooltipWindow : protected LemonWMServerEndpoint { public: TooltipWindow(const char* text, vector2i_t pos, const RGBAColour& bgColour); void SetText(const char* text); - inline void Relocate(vector2i_t pos) { LemonWMServerEndpoint::Relocate(pos.x, pos.y); } + inline void Relocate(vector2i_t pos) { LemonWMServerEndpoint::Relocate(windowID, pos.x, pos.y); } void Paint(); @@ -319,7 +293,5 @@ namespace Lemon::GUI { std::unique_ptr tooltipWindow = nullptr; std::queue eventQueue; - - void UpdateGUITheme(const std::string& path); }; } \ No newline at end of file diff --git a/LibGUI/include/Lemon/GUI/WindowServer.h b/LibGUI/include/Lemon/GUI/WindowServer.h new file mode 100644 index 00000000..15e7dc2d --- /dev/null +++ b/LibGUI/include/Lemon/GUI/WindowServer.h @@ -0,0 +1,46 @@ +#pragma once + +#include + +#include + +#include +#include + +namespace Lemon { + namespace GUI { class Window; } + + class WindowServer final + : public LemonWMServerEndpoint, LemonWMClient { + public: + static WindowServer* Instance(); + + void RegisterWindow(GUI::Window* win); + void UnregisterWindow(long windowID); + + void Poll(); + + ///////////////////////////// + /// \brief Get Screen Bounds + /// + /// \return screen width and height + ///////////////////////////// + inline vector2i_t GetScreenBounds() { + LemonWMServer::GetScreenBoundsResponse r = LemonWMServerEndpoint::GetScreenBounds(); + + return { r.width, r.height }; + } + private: + WindowServer(); + + void OnPeerDisconnect(handle_t client) override; + void OnSendEvent(handle_t client, int64_t windowID, int32_t id, uint64_t data) override; + void OnThemeUpdate(handle_t client, const std::string& name) override; + void OnPing(handle_t client, int64_t windowID) override; + + std::map m_windows; + + static WindowServer* m_instance; + static std::mutex m_instanceLock; + }; +} \ No newline at end of file diff --git a/LibGUI/meson.build b/LibGUI/meson.build index 0eaff5cb..c4c5d016 100755 --- a/LibGUI/meson.build +++ b/LibGUI/meson.build @@ -9,13 +9,14 @@ libgui_cpp_args = ['-Wno-missing-braces', '-m64' ] libgui_cpp_files = [ - 'src/window.cpp', - 'src/widgets.cpp', - 'src/colours.cpp', - 'src/fileview.cpp', - 'src/filedialog.cpp', - 'src/image.cpp', - 'src/messagebox.cpp', + 'src/Colours.cpp', + 'src/FileView.cpp', + 'src/FileDialog.cpp', + 'src/Image.cpp', + 'src/MessageBox.cpp', + 'src/Widgets.cpp', + 'src/Window.cpp', + 'src/WindowServer.cpp', ] prefix = get_option('prefix') diff --git a/LibGUI/src/colours.cpp b/LibGUI/src/Colours.cpp similarity index 100% rename from LibGUI/src/colours.cpp rename to LibGUI/src/Colours.cpp diff --git a/LibGUI/src/filedialog.cpp b/LibGUI/src/FileDialog.cpp similarity index 97% rename from LibGUI/src/filedialog.cpp rename to LibGUI/src/FileDialog.cpp index 0e495a1b..7179d0fd 100755 --- a/LibGUI/src/filedialog.cpp +++ b/LibGUI/src/FileDialog.cpp @@ -107,14 +107,15 @@ namespace Lemon::GUI{ win->Paint(); while(!win->closed && !selectedPth){ + Lemon::WindowServer::Instance()->Poll(); + LemonEvent ev; while(win->PollEvent(ev)){ win->GUIHandleEvent(ev); } win->Paint(); - - win->WaitEvent(); + Lemon::WindowServer::Instance()->Wait(); } delete win; diff --git a/LibGUI/src/fileview.cpp b/LibGUI/src/FileView.cpp similarity index 100% rename from LibGUI/src/fileview.cpp rename to LibGUI/src/FileView.cpp diff --git a/LibGUI/src/image.cpp b/LibGUI/src/Image.cpp similarity index 100% rename from LibGUI/src/image.cpp rename to LibGUI/src/Image.cpp diff --git a/LibGUI/src/messagebox.cpp b/LibGUI/src/MessageBox.cpp similarity index 94% rename from LibGUI/src/messagebox.cpp rename to LibGUI/src/MessageBox.cpp index 896974ac..d4b8915c 100644 --- a/LibGUI/src/messagebox.cpp +++ b/LibGUI/src/MessageBox.cpp @@ -46,6 +46,8 @@ namespace Lemon::GUI bool paint = true; while(!win->closed){ + Lemon::WindowServer::Instance()->Poll(); + LemonEvent ev; while(win->PollEvent(ev)){ win->GUIHandleEvent(ev); @@ -56,6 +58,8 @@ namespace Lemon::GUI win->Paint(); paint = false; } + + Lemon::WindowServer::Instance()->Wait(); } delete win; diff --git a/LibGUI/src/widgets.cpp b/LibGUI/src/Widgets.cpp similarity index 99% rename from LibGUI/src/widgets.cpp rename to LibGUI/src/Widgets.cpp index f2b7fcb5..ea03727c 100755 --- a/LibGUI/src/widgets.cpp +++ b/LibGUI/src/Widgets.cpp @@ -817,8 +817,10 @@ namespace Lemon::GUI { } void ListView::Paint(surface_t* surface){ - Graphics::DrawRect(fixedBounds.x, fixedBounds.y, fixedBounds.width, columnDisplayHeight, colours[Colour::Background], surface); - Graphics::DrawRect(fixedBounds.x, fixedBounds.y + columnDisplayHeight, fixedBounds.width, fixedBounds.height - 20, colours[Colour::ContentBackground], surface); + if(drawBackground){ + Graphics::DrawRect(fixedBounds.x, fixedBounds.y, fixedBounds.width, columnDisplayHeight, colours[Colour::Background], surface); + Graphics::DrawRect(fixedBounds.x, fixedBounds.y + columnDisplayHeight, fixedBounds.width, fixedBounds.height - 20, colours[Colour::ContentBackground], surface); + } if(!model){ return; // If there is no model there is no data to display diff --git a/LibGUI/src/window.cpp b/LibGUI/src/Window.cpp similarity index 73% rename from LibGUI/src/window.cpp rename to LibGUI/src/Window.cpp index 38b5e020..c6975b6b 100755 --- a/LibGUI/src/window.cpp +++ b/LibGUI/src/Window.cpp @@ -2,6 +2,8 @@ #include #include +#include + #include #include @@ -9,17 +11,18 @@ namespace Lemon::GUI{ Window::Window(const char* title, vector2i_t size, uint32_t flags, int type, vector2i_t pos) - : LemonWMServerEndpoint("lemon.lemonwm/Instance"), rootContainer({{0, 0}, size}) { - windowType = type; - this->flags = flags; - + : rootContainer({{0, 0}, size}), flags(flags), windowType(type) { rootContainer.SetWindow(this); - auto response = CreateWindow(pos.x, pos.y, size.x, size.y, flags, title); + WindowServer* server = WindowServer::Instance(); + + auto response = server->CreateWindow(pos.x, pos.y, size.x, size.y, flags, title); windowBufferKey = response.bufferKey; windowID = response.windowID; + server->RegisterWindow(this); + if(windowBufferKey <= 0){ printf("[LibLemon] Warning: Window::Window: Failed to obtain window buffer!\n"); return; @@ -37,71 +40,20 @@ namespace Lemon::GUI{ } Window::~Window(){ - DestroyWindow(); + WindowServer* server = WindowServer::Instance(); + + server->DestroyWindow(windowID); + server->UnregisterWindow(windowID); Lemon::UnmapSharedMemory(windowBufferInfo, windowBufferKey); } - void Window::UpdateGUITheme(const std::string& path){ - JSONParser jP = JSONParser(path.c_str()); - auto json = jP.Parse(); - - if(json.IsObject()){ - JSONValue obj; - if(json.object->find("gui") != json.object->end() && (obj = json.object->at("gui")).IsObject()) { - std::map& values = *obj.object; - - if(auto it = values.find("background"); it != values.end()){ - auto& v = it->second; - - if(v.IsArray() && v.array->size() >= 3){ - Lemon::colours[Lemon::Colour::Background] = (RGBAColour){v.array->at(0).AsUnsignedNumber(), v.array->at(1).AsUnsignedNumber(), v.array->at(2).AsUnsignedNumber(), 255}; - } else {} // TODO: Do something when invalid valaue - } - - if(auto it = values.find("content"); it != values.end()){ - auto& v = it->second; - - if(v.IsArray() && v.array->size() >= 3){ - Lemon::colours[Lemon::Colour::ContentBackground] = (RGBAColour){v.array->at(0).AsUnsignedNumber(), v.array->at(1).AsUnsignedNumber(), v.array->at(2).AsUnsignedNumber(), 255}; - } else {} // TODO: Do something when invalid valaue - } - - if(auto it = values.find("text"); it != values.end()){ - auto& v = it->second; - - if(v.IsArray() && v.array->size() >= 3){ - Lemon::colours[Lemon::Colour::Text] = (RGBAColour){v.array->at(0).AsUnsignedNumber(), v.array->at(1).AsUnsignedNumber(), v.array->at(2).AsUnsignedNumber(), 255}; - } else {} // TODO: Do something when invalid valaue - } - - if(auto it = values.find("textAlternate"); it != values.end()){ - auto& v = it->second; - - if(v.IsArray() && v.array->size() >= 3){ - Lemon::colours[Lemon::Colour::TextAlternate] = (RGBAColour){v.array->at(0).AsUnsignedNumber(), v.array->at(1).AsUnsignedNumber(), v.array->at(2).AsUnsignedNumber(), 255}; - } else {} // TODO: Do something when invalid valaue - } - - if(auto it = values.find("highlight"); it != values.end()){ - auto& v = it->second; - - if(v.IsArray() && v.array->size() >= 3){ - Lemon::colours[Lemon::Colour::Foreground] = (RGBAColour){v.array->at(0).AsUnsignedNumber(), v.array->at(1).AsUnsignedNumber(), v.array->at(2).AsUnsignedNumber(), 255}; - } else {} // TODO: Do something when invalid valaue - } - - if(auto it = values.find("contentShadow"); it != values.end()){ - auto& v = it->second; + void Window::SetTitle(const std::string& title){ + WindowServer::Instance()->SetTitle(windowID, title); + } - if(v.IsArray() && v.array->size() >= 3){ - Lemon::colours[Lemon::Colour::ContentShadow] = (RGBAColour){v.array->at(0).AsUnsignedNumber(), v.array->at(1).AsUnsignedNumber(), v.array->at(2).AsUnsignedNumber(), 255}; - } else {} // TODO: Do something when invalid valaue - } - } - } else { - printf("[LibLemon] Warning: Failed to parse system theme!\n"); - } + void Window::Relocate(vector2i_t pos){ + WindowServer::Instance()->Relocate(windowID, pos.x, pos.y); } void Window::Resize(vector2i_t size){ @@ -115,7 +67,7 @@ namespace Lemon::GUI{ rootContainer.UpdateFixedBounds(); - windowBufferKey = LemonWMServerEndpoint::Resize(size.x, size.y).bufferKey; + windowBufferKey = WindowServer::Instance()->Resize(windowID, size.x, size.y).bufferKey; if(windowBufferKey <= 0){ printf("[LibLemon] Warning: Window::Resize: Failed to obtain window buffer!\n"); @@ -136,6 +88,15 @@ namespace Lemon::GUI{ Paint(); } + void Window::Minimize(int windowID, bool minimized){ + WindowServer::Instance()->Minimize(windowID, minimized); + } + + void Window::UpdateFlags(uint32_t flags){ + this->flags = flags; + WindowServer::Instance()->UpdateFlags(windowID, flags); + } + void Window::SwapBuffers(){ if(windowBufferInfo->drawing) return; @@ -167,12 +128,6 @@ namespace Lemon::GUI{ } bool Window::PollEvent(LemonEvent& ev){ - Message m; - long ret; - while((ret = Poll(m)) > 0){ - HandleMessage(handle, m); - } - if(!eventQueue.empty()){ ev = eventQueue.front(); eventQueue.pop(); @@ -181,10 +136,6 @@ namespace Lemon::GUI{ } return false; } - - void Window::WaitEvent(long tm){ - Wait(tm); - } void Window::GUIHandleEvent(LemonEvent& ev){ switch(ev.event){ @@ -319,19 +270,7 @@ namespace Lemon::GUI{ std::string str = serializedEntries.str(); - LemonWMServerEndpoint::DisplayContextMenu(pos.x, pos.y, str); - } - - void Window::OnPeerDisconnect(handle_t){ - throw std::runtime_error("Lost connected to window server!"); - } - - void Window::OnSendEvent(handle_t, int32_t id, uint64_t data){ - eventQueue.push(LemonEvent{ .event = id, .data = data }); - } - - void Window::OnPing(handle_t){ - Pong(); + WindowServer::Instance()->DisplayContextMenu(windowID, pos.x, pos.y, str); } void Window::CreateMenuBar(){ @@ -388,7 +327,7 @@ namespace Lemon::GUI{ } surface.buffer = nullptr; // Invalidate surface buffer - windowBufferKey = Resize(textObject.Size().x + 8, textObject.Size().y + 8).bufferKey; + windowBufferKey = Resize(windowID, textObject.Size().x + 8, textObject.Size().y + 8).bufferKey; if(windowBufferKey <= 0){ printf("[LibLemon] Warning: Window::TooltipWindow::Resize: Failed to obtain window buffer!\n"); return; diff --git a/LibGUI/src/WindowServer.cpp b/LibGUI/src/WindowServer.cpp new file mode 100644 index 00000000..800d0f94 --- /dev/null +++ b/LibGUI/src/WindowServer.cpp @@ -0,0 +1,59 @@ +#include + +#include + +#include + +namespace Lemon { + WindowServer* WindowServer::m_instance = nullptr; + std::mutex WindowServer::m_instanceLock; + + WindowServer* WindowServer::Instance(){ + if(m_instance){ + return m_instance; + } + + std::scoped_lock acquire(m_instanceLock); + if(!m_instance){ + m_instance = new WindowServer(); + } + + return m_instance; + } + + void WindowServer::RegisterWindow(GUI::Window* win){ + m_windows[win->ID()] = win; + } + + void WindowServer::UnregisterWindow(long windowID){ + m_windows.erase(windowID); + } + + void WindowServer::Poll(){ + Lemon::Message m; + while(Endpoint::Poll(m) > 0){ + HandleMessage(handle, m); + } + } + + WindowServer::WindowServer() + : LemonWMServerEndpoint("lemon.lemonwm/Instance"){ + assert(!m_instance); + } + + void WindowServer::OnPeerDisconnect(handle_t) { + throw std::runtime_error("WindowServer has disconnected!"); + } + + void WindowServer::OnSendEvent(handle_t, int64_t windowID, int32_t id, uint64_t data) { + m_windows.at(windowID)->eventQueue.push(Lemon::LemonEvent{ .event = id, .data = data }); + } + + void WindowServer::OnThemeUpdate(handle_t, const std::string& name) { + (void)name; + } + + void WindowServer::OnPing(handle_t, int64_t windowID) { + Pong(windowID); + } +} \ No newline at end of file diff --git a/LibLemon/include/Lemon/System/IPC.h b/LibLemon/include/Lemon/System/IPC.h index b00bf0b4..2c4b0d87 100644 --- a/LibLemon/include/Lemon/System/IPC.h +++ b/LibLemon/include/Lemon/System/IPC.h @@ -32,7 +32,7 @@ namespace Lemon{ /// /// \return Handle ID of service on success, negative error code on failure ///////////////////////////// - inline handle_t CreateInterface(const handle_t svc, const char* name, const uint16_t msgSize){ + inline handle_t CreateInterface(handle_t svc, const char* name, uint16_t msgSize){ return syscall(SYS_CREATE_INTERFACE, svc, name, msgSize); } @@ -45,7 +45,7 @@ namespace Lemon{ /// /// \return Handle ID of endpoint on success, 0 when no pending connections, negative error code on failure ///////////////////////////// - inline handle_t InterfaceAccept(const handle_t interface){ + inline handle_t InterfaceAccept(handle_t interface){ return syscall(SYS_INTERFACE_ACCEPT, interface); } @@ -74,10 +74,26 @@ namespace Lemon{ /// /// \return 0 on success, negative error code on failure ///////////////////////////// - __attribute__((always_inline)) inline long EndpointQueue(const handle_t endpoint, const uint64_t id, const uint16_t size, const uintptr_t data){ + __attribute__((always_inline)) inline long EndpointQueue(handle_t endpoint, uint64_t id, uint16_t size, uintptr_t data){ return syscall(SYS_ENDPOINT_QUEUE, endpoint, id, size, data); } + ///////////////////////////// + /// \brief EndpointQueue (endpoint, id, size, data) - Queue a message on an endpoint + /// + /// Queues a new message on the specified endpoint. + /// + /// \param endpoint (handle_t) Handle ID of specified endpoint + /// \param id (uint64_t) Message ID + /// \param data (T) Message data + /// + /// \return 0 on success, negative error code on failure + ///////////////////////////// + template + __attribute__((always_inline)) inline long EndpointQueue(handle_t endpoint, uint64_t id, const T& data){ + return syscall(SYS_ENDPOINT_QUEUE, endpoint, id, sizeof(T), &data); + } + ///////////////////////////// /// \brief EndpointDequeue (endpoint, id, size, data) /// @@ -90,7 +106,7 @@ namespace Lemon{ /// /// \return 0 on empty, 1 on success, negative error code on failure ///////////////////////////// - __attribute__((always_inline)) inline long EndpointDequeue(const handle_t endpoint, uint64_t* id, uint16_t* size, uint8_t* data){ + __attribute__((always_inline)) inline long EndpointDequeue(handle_t endpoint, uint64_t* id, uint16_t* size, uint8_t* data){ return syscall(SYS_ENDPOINT_DEQUEUE, endpoint, id, size, data); } @@ -109,7 +125,7 @@ namespace Lemon{ /// /// \return 0 on success, negative error code on failure ///////////////////////////// - __attribute__((always_inline)) inline long EndpointCall(const handle_t endpoint, const uint64_t id, const uintptr_t data, const uint64_t rID, uintptr_t rData, uint16_t* size){ + __attribute__((always_inline)) inline long EndpointCall(handle_t endpoint, uint64_t id, uintptr_t data, uint64_t rID, uintptr_t rData, uint16_t* size){ return syscall(SYS_ENDPOINT_CALL, endpoint, id, data, rID, rData, size); } @@ -123,7 +139,7 @@ namespace Lemon{ /// /// \return 0 on success, negative error code on failure ///////////////////////////// - __attribute__((always_inline)) inline long EndpointInfo(const handle_t endp, LemonEndpointInfo& info){ + __attribute__((always_inline)) inline long EndpointInfo(handle_t endp, LemonEndpointInfo& info){ return syscall(SYS_ENDPOINT_INFO, endp, &info); } } \ No newline at end of file diff --git a/Services/lemon.lemonwm.li b/Services/lemon.lemonwm.li index f3aeb10a..6760bf34 100644 --- a/Services/lemon.lemonwm.li +++ b/Services/lemon.lemonwm.li @@ -1,25 +1,29 @@ interface LemonWMServer { CreateWindow(s32 x, s32 y, s32 width, s32 height, u32 flags, string title) -> (s64 windowID, s64 bufferKey) - DestroyWindow() + DestroyWindow(s64 windowID) - SetTitle(string title) - UpdateFlags(u32 flags) + SetTitle(s64 windowID, string title) + UpdateFlags(s64 windowID, u32 flags) - Relocate(s32 x, s32 y) - GetPosition() -> (s32 x, s32 y) + Relocate(s64 windowID, s32 x, s32 y) + GetPosition(s64 windowID) -> (s32 x, s32 y) GetScreenBounds() -> (s32 width, s32 height) - Resize(s32 width, s32 height) -> (s64 bufferKey) + Resize(s64 windowID, s32 width, s32 height) -> (s64 bufferKey) Minimize(s64 windowID, bool minimized) - DisplayContextMenu(s32 x, s32 y, string entries) + DisplayContextMenu(s64 windowID, s32 x, s32 y, string entries) - Pong() + ReloadConfig() + + Pong(s64 windowID) } interface LemonWMClient { - SendEvent(s32 id, u64 data) - Ping() + SendEvent(s64 windowID, s32 id, u64 data) + ThemeUpdate(string name) + + Ping(s64 windowID) } \ No newline at end of file diff --git a/System/LemonWM/WM.cpp b/System/LemonWM/WM.cpp index 31787cad..25e192d8 100644 --- a/System/LemonWM/WM.cpp +++ b/System/LemonWM/WM.cpp @@ -25,9 +25,9 @@ void* WMInstance::InitializeShellConnection(){ return nullptr; } -WMWindow* WMInstance::FindWindow(int id){ +WMWindow* WMInstance::FindWindow(int64_t id){ for(WMWindow* win : windows){ - if(win->clientID == id){ + if(win->windowID == id){ return win; } } @@ -35,6 +35,20 @@ WMWindow* WMInstance::FindWindow(int id){ return nullptr; } +WMWindow* WMInstance::FindWindowByClient(handle_t client){ + for(WMWindow* win : windows){ + if(win->GetClient() == client){ + return win; + } + } + + return nullptr; +} + +int64_t WMInstance::NextWindowID(){ + return nextWindowID++; +} + void WMInstance::MinimizeWindow(WMWindow* win, bool state){ win->Minimize(state); @@ -108,28 +122,7 @@ void WMInstance::SetActive(WMWindow* win){ } } -int64_t WMInstance::CreateWindowBuffer(int width, int height, WindowBuffer** buffer){ - size_t windowBufferSize = ((sizeof(WindowBuffer) + 0x1F) & (~0x1F)) + ((width * height * 4 + 0x1F) & (~0x1F) /* Round up to 32 bytes */) * 2; - - int64_t windowBufferKey = Lemon::CreateSharedMemory(windowBufferSize, SMEM_FLAGS_SHARED); - if(windowBufferKey <= 0){ - printf("[LemonWM] Warning: Error %ld obtaining shared memory for window\n", -windowBufferKey); - return windowBufferKey; - } - - WindowBuffer* windowBufferInfo = (WindowBuffer*)Lemon::MapSharedMemory(windowBufferKey); - windowBufferInfo->currentBuffer = 0; - windowBufferInfo->buffer1Offset = ((sizeof(WindowBuffer) + 0x1F) & (~0x1F)); - windowBufferInfo->buffer2Offset = ((sizeof(WindowBuffer) + 0x1F) & (~0x1F)) + ((width * height * 4 + 0x1F) & (~0x1F) /* Round up to 32 bytes*/); - - *buffer = windowBufferInfo; - - return windowBufferKey; -} - -void WMInstance::OnPeerDisconnect(handle_t client){ - WMWindow* win = FindWindow(client); - +void WMInstance::DestroyWindow(WMWindow* win){ if(!win){ return; } @@ -157,6 +150,25 @@ void WMInstance::OnPeerDisconnect(handle_t client){ delete win; } +int64_t WMInstance::CreateWindowBuffer(int width, int height, WindowBuffer** buffer){ + size_t windowBufferSize = ((sizeof(WindowBuffer) + 0x1F) & (~0x1F)) + ((width * height * 4 + 0x1F) & (~0x1F) /* Round up to 32 bytes */) * 2; + + int64_t windowBufferKey = Lemon::CreateSharedMemory(windowBufferSize, SMEM_FLAGS_SHARED); + if(windowBufferKey <= 0){ + printf("[LemonWM] Warning: Error %ld obtaining shared memory for window\n", -windowBufferKey); + return windowBufferKey; + } + + WindowBuffer* windowBufferInfo = (WindowBuffer*)Lemon::MapSharedMemory(windowBufferKey); + windowBufferInfo->currentBuffer = 0; + windowBufferInfo->buffer1Offset = ((sizeof(WindowBuffer) + 0x1F) & (~0x1F)); + windowBufferInfo->buffer2Offset = ((sizeof(WindowBuffer) + 0x1F) & (~0x1F)) + ((width * height * 4 + 0x1F) & (~0x1F) /* Round up to 32 bytes*/); + + *buffer = windowBufferInfo; + + return windowBufferKey; +} + void WMInstance::OnCreateWindow(handle_t client, int32_t x, int32_t y, int32_t width, int32_t height, uint32_t flags, const std::string& title){ printf("[LemonWM] Creating Window: Pos: (%d, %d), Size: %dx%d, Title: %s\n", x,y, width, height, title.c_str()); @@ -167,11 +179,11 @@ void WMInstance::OnCreateWindow(handle_t client, int32_t x, int32_t y, int32_t w return; // Error obtaining window buffer shared memory } - WMWindow* win = new WMWindow(this, client, client, wBufferKey, wBufferInfo, {x,y}, {width, height}, flags, title); + WMWindow* win = new WMWindow(this, client, wBufferKey, wBufferInfo, {x,y}, {width, height}, flags, title); windows.push_back(win); win->RecalculateButtonRects(); - win->Queue(Lemon::Message(LemonWMServer::ResponseCreateWindow, LemonWMServer::CreateWindowResponse{ .windowID = client, .bufferKey = wBufferKey })); + win->Queue(Lemon::Message(LemonWMServer::ResponseCreateWindow, LemonWMServer::CreateWindowResponse{ .windowID = win->ID(), .bufferKey = wBufferKey })); //if(shellConnected && !(win->flags & WINDOW_FLAGS_NOSHELL)){ //Lemon::Shell::AddWindow(client, Lemon::Shell::ShellWindowState::ShellWindowStateNormal, title, shellClient); @@ -181,8 +193,8 @@ void WMInstance::OnCreateWindow(handle_t client, int32_t x, int32_t y, int32_t w redrawBackground = true; } -void WMInstance::OnDestroyWindow(handle_t client){ - WMWindow* win = FindWindow(client); +void WMInstance::OnDestroyWindow(handle_t client, int64_t windowID){ + WMWindow* win = FindWindow(windowID); if(!win){ printf("[LemonWM] Warning: Unknown Window ID: %ld\n", client); return; @@ -211,30 +223,30 @@ void WMInstance::OnDestroyWindow(handle_t client){ delete win; } -void WMInstance::OnSetTitle(handle_t client, const std::string& title){ - WMWindow* win = FindWindow(client); +void WMInstance::OnSetTitle(handle_t, int64_t windowID, const std::string& title){ + WMWindow* win = FindWindow(windowID); if(!win){ - printf("[LemonWM] Warning: Unknown Window ID: %ld\n", client); + printf("[LemonWM] Warning: Unknown Window ID: %ld\n", windowID); return; } win->title = title; } -void WMInstance::OnUpdateFlags(handle_t client, uint32_t flags){ - WMWindow* win = FindWindow(client); +void WMInstance::OnUpdateFlags(handle_t, int64_t windowID, uint32_t flags){ + WMWindow* win = FindWindow(windowID); if(!win){ - printf("[LemonWM] Warning: Unknown Window ID: %ld\n", client); + printf("[LemonWM] Warning: Unknown Window ID: %ld\n", windowID); return; } win->flags = flags; } -void WMInstance::OnRelocate(handle_t client, int32_t x, int32_t y){ - WMWindow* win = FindWindow(client); +void WMInstance::OnRelocate(handle_t, int64_t windowID, int32_t x, int32_t y){ + WMWindow* win = FindWindow(windowID); if(!win){ - printf("[LemonWM] Warning: Unknown Window ID: %ld\n", client); + printf("[LemonWM] Warning: Unknown Window ID: %ld\n", windowID); return; } @@ -242,30 +254,20 @@ void WMInstance::OnRelocate(handle_t client, int32_t x, int32_t y){ redrawBackground = true; } -void WMInstance::OnGetPosition(handle_t client){ - WMWindow* win = FindWindow(client); +void WMInstance::OnGetPosition(handle_t, int64_t windowID){ + WMWindow* win = FindWindow(windowID); if(!win){ - printf("[LemonWM] Warning: Unknown Window ID: %ld\n", client); + printf("[LemonWM] Warning: Unknown Window ID: %ld\n", windowID); return; } win->Queue(Lemon::Message(LemonWMServer::ResponseGetPosition, LemonWMServer::GetPositionResponse{win->pos.x, win->pos.y})); } -void WMInstance::OnGetScreenBounds(handle_t client){ - WMWindow* win = FindWindow(client); +void WMInstance::OnResize(handle_t, int64_t windowID, int32_t width, int32_t height){ + WMWindow* win = FindWindow(windowID); if(!win){ - printf("[LemonWM] Warning: Unknown Window ID: %ld\n", client); - return; - } - - win->Queue(Lemon::Message(LemonWMServer::ResponseGetScreenBounds, LemonWMServer::GetScreenBoundsResponse{surface.width, surface.height})); -} - -void WMInstance::OnResize(handle_t client, int32_t width, int32_t height){ - WMWindow* win = FindWindow(client); - if(!win){ - printf("[LemonWM] Warning: Unknown Window ID: %ld\n", client); + printf("[LemonWM] Warning: Unknown Window ID: %ld\n", windowID); return; } @@ -281,14 +283,14 @@ void WMInstance::OnResize(handle_t client, int32_t width, int32_t height){ redrawBackground = true; } -void WMInstance::OnMinimize(handle_t client, int64_t windowID, bool minimized){ +void WMInstance::OnMinimize(handle_t, int64_t windowID, bool minimized){ MinimizeWindow(windowID, minimized); } -void WMInstance::OnDisplayContextMenu(handle_t client, int32_t x, int32_t y, const std::string& entries){ - WMWindow* win = FindWindow(client); +void WMInstance::OnDisplayContextMenu(handle_t, int64_t windowID, int32_t x, int32_t y, const std::string& entries){ + WMWindow* win = FindWindow(windowID); if(!win){ - printf("[LemonWM] Warning: Unknown Window ID: %ld\n", client); + printf("[LemonWM] Warning: Unknown Window ID: %ld\n", windowID); return; } @@ -321,14 +323,28 @@ void WMInstance::OnDisplayContextMenu(handle_t client, int32_t x, int32_t y, con contextMenuActive = true; } -void WMInstance::OnPong(handle_t client){ - WMWindow* win = FindWindow(client); +void WMInstance::OnPong(handle_t, int64_t windowID){ + WMWindow* win = FindWindow(windowID); if(!win){ - printf("[LemonWM] Warning: Unknown Window ID: %ld\n", client); + printf("[LemonWM] Warning: Unknown Window ID: %ld\n", windowID); return; } } +void WMInstance::OnPeerDisconnect(handle_t client){ + for(WMWindow* win = FindWindowByClient(client); win; win = FindWindowByClient(client)){ + DestroyWindow(win); + } +} + +void WMInstance::OnGetScreenBounds(handle_t client){ + Lemon::EndpointQueue(client, LemonWMServer::ResponseGetScreenBounds, LemonWMServer::GetScreenBoundsResponse{surface.width, surface.height}); +} + +void WMInstance::OnReloadConfig(handle_t client){ + (void)client; +} + void WMInstance::Poll(){ Lemon::Message m; handle_t client; diff --git a/System/LemonWM/WM.h b/System/LemonWM/WM.h index deee45c1..58a37be8 100644 --- a/System/LemonWM/WM.h +++ b/System/LemonWM/WM.h @@ -52,8 +52,10 @@ enum ResizePoint { class WMWindow : public LemonWMClientEndpoint { friend class CompositorInstance; + + WMInstance* wm; public: - WMWindow(WMInstance* wm, handle_t endp, handle_t id, int64_t key, WindowBuffer* bufferInfo, vector2i_t pos, vector2i_t size, unsigned int flags, const std::string& title); + WMWindow(WMInstance* wm, handle_t client, int64_t key, WindowBuffer* bufferInfo, vector2i_t pos, vector2i_t size, unsigned int flags, const std::string& title); ~WMWindow(); vector2i_t pos = {0, 0}; @@ -65,7 +67,10 @@ class WMWindow short closeBState = ButtonStateUp; short minimizeBState = ButtonStateUp; - handle_t clientID = 0; + int64_t windowID = 0; + + inline handle_t GetClient() { return LemonWMClientEndpoint::handle; } + inline int64_t ID() const { return windowID; } void DrawDecoration(surface_t* surface, rect_t) const; void DrawClip(surface_t* surface, rect_t clip); @@ -73,7 +78,7 @@ class WMWindow inline void SendEvent(const Lemon::LemonEvent& ev) { if(!(flags & WINDOW_FLAGS_TOOLTIP)) - LemonWMClientEndpoint::SendEvent(ev.event, ev.data); + LemonWMClientEndpoint::SendEvent(windowID, ev.event, ev.data); } void Minimize(bool state); @@ -102,8 +107,6 @@ class WMWindow uint8_t* buffer2; int64_t bufferKey; - WMInstance* wm; - rect_t closeRect, minimizeRect; surface_t windowSurface; @@ -174,11 +177,13 @@ class CompositorInstance{ surface_t backgroundImage; }; -class WMInstance +class WMInstance final : LemonWMServer { protected: friend void* _InitializeShellConnection(void*); friend class WMWindow; + + int64_t nextWindowID = 1; Lemon::Interface server; Lemon::Endpoint shellClient; @@ -197,27 +202,33 @@ class WMInstance void* InitializeShellConnection(); void Poll(); void PostEvent(const Lemon::LemonEvent& ev, WMWindow* win); - WMWindow* FindWindow(int id); + + WMWindow* FindWindow(int64_t id); + WMWindow* FindWindowByClient(handle_t clientID); + int64_t NextWindowID(); void MinimizeWindow(WMWindow* win, bool state); void MinimizeWindow(int id, bool state); void SetActive(WMWindow* win); + void DestroyWindow(WMWindow* win); int64_t CreateWindowBuffer(int width, int height, WindowBuffer** buffer); - void OnPeerDisconnect(handle_t client); - void OnCreateWindow(handle_t client, int32_t x, int32_t y, int32_t width, int32_t height, uint32_t flags, const std::string& title); - void OnDestroyWindow(handle_t client); - void OnSetTitle(handle_t client, const std::string& title); - void OnUpdateFlags(handle_t client, uint32_t flags); - void OnRelocate(handle_t client, int32_t x, int32_t y); - void OnGetPosition(handle_t client); - void OnGetScreenBounds(handle_t client); - void OnResize(handle_t client, int32_t width, int32_t height); - void OnMinimize(handle_t client, int64_t windowID, bool minimized); - void OnDisplayContextMenu(handle_t client, int32_t x, int32_t y, const std::string& entries); - virtual void OnPong(handle_t client); + void OnCreateWindow(handle_t client, int32_t x, int32_t y, int32_t width, int32_t height, uint32_t flags, const std::string& title) override; + void OnDestroyWindow(handle_t client, int64_t windowID) override; + void OnSetTitle(handle_t client, int64_t windowID, const std::string& title) override; + void OnUpdateFlags(handle_t client, int64_t windowID, uint32_t flags) override; + void OnRelocate(handle_t client, int64_t windowID, int32_t x, int32_t y) override; + void OnGetPosition(handle_t client, int64_t windowID) override; + void OnResize(handle_t client, int64_t windowID, int32_t width, int32_t height) override; + void OnMinimize(handle_t client, int64_t windowID, bool minimized) override; + void OnDisplayContextMenu(handle_t client, int64_t windowID, int32_t x, int32_t y, const std::string& entries) override; + void OnPong(handle_t client, int64_t windowID) override; + + void OnPeerDisconnect(handle_t client) override; + void OnGetScreenBounds(handle_t client) override; + void OnReloadConfig(handle_t client) override; public: timespec startTime; diff --git a/System/LemonWM/Window.cpp b/System/LemonWM/Window.cpp index 11562ac0..349f71ad 100644 --- a/System/LemonWM/Window.cpp +++ b/System/LemonWM/Window.cpp @@ -5,23 +5,16 @@ #include #include -WMWindow::WMWindow(WMInstance* wm, handle_t endp, handle_t id, int64_t key, WindowBuffer* bufferInfo, vector2i_t pos, vector2i_t size, unsigned int flags, const std::string& title) - : LemonWMClientEndpoint(endp){ - this->wm = wm; +WMWindow::WMWindow(WMInstance* wm, handle_t client, int64_t key, WindowBuffer* bufferInfo, vector2i_t pos, vector2i_t size, unsigned int flags, const std::string& title) + : LemonWMClientEndpoint(client), + wm(wm), pos(pos), size(size), title(title), flags(flags), windowID(wm->NextWindowID()) { - clientID = id; - bufferKey = key; windowBufferInfo = bufferInfo; buffer1 = ((uint8_t*)windowBufferInfo) + windowBufferInfo->buffer1Offset; buffer2 = ((uint8_t*)windowBufferInfo) + windowBufferInfo->buffer2Offset; - this->pos = pos; - this->size = size; - this->flags = flags; - this->title = title; - windowSurface = { .width = size.x, .height = size.y, .depth = 32, .buffer = buffer1 }; } @@ -94,7 +87,7 @@ void WMWindow::Minimize(bool state){ if(!minimized){ windowBufferInfo->dirty = true; } else { - LemonWMClientEndpoint::SendEvent(Lemon::EventWindowMinimized, 0); + LemonWMClientEndpoint::SendEvent(windowID, Lemon::EventWindowMinimized, 0); } } diff --git a/System/Login/main.cpp b/System/Login/main.cpp index 1dd9c525..1c57ee74 100644 --- a/System/Login/main.cpp +++ b/System/Login/main.cpp @@ -135,13 +135,15 @@ int main(int argc, char** argv){ window->AddWidget(okButton); while(1){ + Lemon::WindowServer::Instance()->Poll(); + Lemon::LemonEvent ev; while (window->PollEvent(ev)) { window->GUIHandleEvent(ev); } window->Paint(); - window->WaitEvent(); + Lemon::WindowServer::Instance()->Wait(); } return -1;