wind: Remove special window attributes and add different window layers.
All checks were successful
Build and test / build (push) Successful in 1m38s
All checks were successful
Build and test / build (push) Successful in 1m38s
Two layers are accessible to all apps: global and global_top (for popups and similar windows). Three other layers are accessible to privileged clients (background, system and lock), for things that need to be on a different level than user apps, like the taskbar, system popups, menus and the lock screen.
This commit is contained in:
parent
ccef3e2069
commit
fb3333a086
@ -125,7 +125,7 @@ Result<int> luna_main(int, char**)
|
|||||||
app.set_main_window(window);
|
app.set_main_window(window);
|
||||||
|
|
||||||
window->set_background(TASKBAR_COLOR);
|
window->set_background(TASKBAR_COLOR);
|
||||||
window->set_special_attributes(ui::UNFOCUSEABLE);
|
window->set_layer(ui::Layer::Background);
|
||||||
|
|
||||||
ui::HorizontalLayout layout(ui::Margins { 0, 0, 0, 0 }, ui::AdjustHeight::Yes, ui::AdjustWidth::No);
|
ui::HorizontalLayout layout(ui::Margins { 0, 0, 0, 0 }, ui::AdjustHeight::Yes, ui::AdjustWidth::No);
|
||||||
window->set_main_widget(layout);
|
window->set_main_widget(layout);
|
||||||
|
@ -65,7 +65,7 @@ namespace ui
|
|||||||
|
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
void set_special_attributes(WindowAttributes attributes);
|
void set_layer(Layer layer);
|
||||||
|
|
||||||
Result<void> draw();
|
Result<void> draw();
|
||||||
Result<ui::EventResult> handle_mouse_leave();
|
Result<ui::EventResult> handle_mouse_leave();
|
||||||
|
@ -25,7 +25,7 @@ namespace ui
|
|||||||
CLOSE_WINDOW_ID,
|
CLOSE_WINDOW_ID,
|
||||||
GET_SCREEN_RECT_ID,
|
GET_SCREEN_RECT_ID,
|
||||||
SET_TITLEBAR_HEIGHT_ID,
|
SET_TITLEBAR_HEIGHT_ID,
|
||||||
SET_SPECIAL_WINDOW_ATTRIBUTES_ID,
|
SET_WINDOW_LAYER_ID,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CreateWindowRequest
|
struct CreateWindowRequest
|
||||||
@ -81,16 +81,20 @@ namespace ui
|
|||||||
int height;
|
int height;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum WindowAttributes : u8
|
enum Layer : u8
|
||||||
{
|
{
|
||||||
UNFOCUSEABLE = 1,
|
Background,
|
||||||
|
Global,
|
||||||
|
GlobalTop,
|
||||||
|
System,
|
||||||
|
Lock
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SetSpecialWindowAttributesRequest
|
struct SetWindowLayer
|
||||||
{
|
{
|
||||||
static constexpr u8 ID = SET_SPECIAL_WINDOW_ATTRIBUTES_ID;
|
static constexpr u8 ID = SET_WINDOW_LAYER_ID;
|
||||||
|
|
||||||
int window;
|
int window;
|
||||||
WindowAttributes attributes;
|
Layer layer;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -115,11 +115,11 @@ namespace ui
|
|||||||
app.unregister_window(this, {});
|
app.unregister_window(this, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::set_special_attributes(WindowAttributes attributes)
|
void Window::set_layer(Layer layer)
|
||||||
{
|
{
|
||||||
ui::SetSpecialWindowAttributesRequest request;
|
ui::SetWindowLayer request;
|
||||||
request.window = m_id;
|
request.window = m_id;
|
||||||
request.attributes = attributes;
|
request.layer = layer;
|
||||||
App::the().client().send_async(request);
|
App::the().client().send_async(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,8 @@ set(SOURCES
|
|||||||
Keyboard.cpp
|
Keyboard.cpp
|
||||||
Keyboard.h
|
Keyboard.h
|
||||||
Client.h
|
Client.h
|
||||||
|
Layer.cpp
|
||||||
|
Layer.h
|
||||||
)
|
)
|
||||||
|
|
||||||
add_executable(wind ${SOURCES})
|
add_executable(wind ${SOURCES})
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include "IPC.h"
|
#include "IPC.h"
|
||||||
|
#include "Layer.h"
|
||||||
#include "Mouse.h"
|
#include "Mouse.h"
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
#include <luna/Alignment.h>
|
#include <luna/Alignment.h>
|
||||||
@ -47,7 +48,7 @@ static Result<void> handle_create_window_message(Client& client)
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto guard = make_scope_guard([window] {
|
auto guard = make_scope_guard([window] {
|
||||||
g_windows.remove(window);
|
window->layer->windows.remove(window);
|
||||||
delete window;
|
delete window;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -120,7 +121,7 @@ static Result<void> handle_close_window_message(Client& client)
|
|||||||
|
|
||||||
auto* window = client.windows[request.window];
|
auto* window = client.windows[request.window];
|
||||||
client.windows[request.window] = nullptr;
|
client.windows[request.window] = nullptr;
|
||||||
g_windows.remove(window);
|
window->layer->windows.remove(window);
|
||||||
Mouse::the().window_did_close(window);
|
Mouse::the().window_did_close(window);
|
||||||
delete window;
|
delete window;
|
||||||
|
|
||||||
@ -160,22 +161,40 @@ static Result<void> handle_set_titlebar_height_message(Client& client)
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
static Result<void> handle_set_special_window_attributes_message(Client& client)
|
static Result<void> handle_set_window_layer_message(Client& client)
|
||||||
{
|
{
|
||||||
ui::SetSpecialWindowAttributesRequest request;
|
ui::SetWindowLayer request;
|
||||||
if (!TRY(client.conn->read_message(request))) return {};
|
if (!TRY(client.conn->read_message(request))) return {};
|
||||||
|
|
||||||
if (!client.privileged)
|
if (request.layer != ui::Layer::Global && request.layer != ui::Layer::GlobalTop && !client.privileged)
|
||||||
{
|
{
|
||||||
os::eprintln(
|
os::eprintln("wind: Unprivileged client trying to set window layer to a privileged layer, disconnecting!");
|
||||||
"wind: Unprivileged client trying to call privileged request (SetSpecialWindowAttributes), disconnecting!");
|
|
||||||
client.should_be_disconnected = true;
|
client.should_be_disconnected = true;
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECK_WINDOW_ID(request, "SetSpecialWindowAttributes");
|
CHECK_WINDOW_ID(request, "SetWindowLayer");
|
||||||
|
|
||||||
client.windows[request.window]->attributes = request.attributes;
|
auto* window = client.windows[request.window];
|
||||||
|
|
||||||
|
window->layer->windows.remove(window);
|
||||||
|
|
||||||
|
switch (request.layer)
|
||||||
|
{
|
||||||
|
case ui::Layer::Background: window->layer = &l_background; break;
|
||||||
|
case ui::Layer::Global: window->layer = &l_global; break;
|
||||||
|
case ui::Layer::GlobalTop: window->layer = &l_global_top; break;
|
||||||
|
case ui::Layer::System: window->layer = &l_system; break;
|
||||||
|
case ui::Layer::Lock: window->layer = &l_lock; break;
|
||||||
|
default: {
|
||||||
|
window->layer->windows.append(window);
|
||||||
|
os::eprintln("wind: Client trying to set window layer to an invalid layer, disconnecting!");
|
||||||
|
client.should_be_disconnected = true;
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window->layer->windows.append(window);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -194,7 +213,7 @@ namespace wind
|
|||||||
case ui::CLOSE_WINDOW_ID: handle_close_window_message(client); break;
|
case ui::CLOSE_WINDOW_ID: handle_close_window_message(client); break;
|
||||||
case ui::GET_SCREEN_RECT_ID: handle_get_screen_rect_message(client); break;
|
case ui::GET_SCREEN_RECT_ID: handle_get_screen_rect_message(client); break;
|
||||||
case ui::SET_TITLEBAR_HEIGHT_ID: handle_set_titlebar_height_message(client); break;
|
case ui::SET_TITLEBAR_HEIGHT_ID: handle_set_titlebar_height_message(client); break;
|
||||||
case ui::SET_SPECIAL_WINDOW_ATTRIBUTES_ID: handle_set_special_window_attributes_message(client); break;
|
case ui::SET_WINDOW_LAYER_ID: handle_set_window_layer_message(client); break;
|
||||||
default: os::eprintln("wind: Invalid IPC message from client!"); return;
|
default: os::eprintln("wind: Invalid IPC message from client!"); return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
79
gui/wind/Layer.cpp
Normal file
79
gui/wind/Layer.cpp
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
#include "Layer.h"
|
||||||
|
#include "Client.h"
|
||||||
|
#include "Window.h"
|
||||||
|
|
||||||
|
Layer l_background;
|
||||||
|
Layer l_global;
|
||||||
|
Layer l_global_top;
|
||||||
|
Layer l_system;
|
||||||
|
Layer l_lock;
|
||||||
|
|
||||||
|
constexpr int NUM_LAYERS = 5;
|
||||||
|
|
||||||
|
static Layer* const layers_front_to_back[NUM_LAYERS] = { &l_lock, &l_system, &l_global_top, &l_global, &l_background };
|
||||||
|
static Layer* const layers_back_to_front[NUM_LAYERS] = { &l_background, &l_global, &l_global_top, &l_system, &l_lock };
|
||||||
|
|
||||||
|
Window* Layer::focused_window()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NUM_LAYERS; i++)
|
||||||
|
{
|
||||||
|
Layer* l = layers_front_to_back[i];
|
||||||
|
if (l->windows.last().has_value()) return l->windows.last().value();
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Layer::draw_all_windows(ui::Canvas& canvas)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NUM_LAYERS; i++)
|
||||||
|
{
|
||||||
|
Layer* l = layers_back_to_front[i];
|
||||||
|
for (Window* w : l->windows) { w->draw(canvas); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Window* Layer::propagate_mouse_event(ui::Point position, u8 buttons)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NUM_LAYERS; i++)
|
||||||
|
{
|
||||||
|
Layer* l = layers_front_to_back[i];
|
||||||
|
for (Window* window = l->windows.last().value_or(nullptr); window;
|
||||||
|
window = l->windows.previous(window).value_or(nullptr))
|
||||||
|
{
|
||||||
|
if (window->surface.contains(position))
|
||||||
|
{
|
||||||
|
ui::MouseEventRequest request;
|
||||||
|
request.window = window->id;
|
||||||
|
request.position = window->surface.relative(position);
|
||||||
|
request.buttons = buttons;
|
||||||
|
window->client->conn->send_async(request);
|
||||||
|
return window;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Window* Layer::propagate_drag_event(ui::Point position)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < NUM_LAYERS; i++)
|
||||||
|
{
|
||||||
|
Layer* l = layers_front_to_back[i];
|
||||||
|
for (Window* window = l->windows.last().value_or(nullptr); window;
|
||||||
|
window = l->windows.previous(window).value_or(nullptr))
|
||||||
|
{
|
||||||
|
if (window->surface.contains(position))
|
||||||
|
{
|
||||||
|
window->focus();
|
||||||
|
|
||||||
|
if (window->surface.absolute(window->titlebar).contains(position)) return window;
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
20
gui/wind/Layer.h
Normal file
20
gui/wind/Layer.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Window.h"
|
||||||
|
#include <luna/LinkedList.h>
|
||||||
|
#include <ui/Canvas.h>
|
||||||
|
|
||||||
|
struct Layer
|
||||||
|
{
|
||||||
|
LinkedList<Window> windows;
|
||||||
|
|
||||||
|
static Window* focused_window();
|
||||||
|
static void draw_all_windows(ui::Canvas& canvas);
|
||||||
|
static Window* propagate_mouse_event(ui::Point position, u8 buttons);
|
||||||
|
static Window* propagate_drag_event(ui::Point position);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Layer l_background;
|
||||||
|
extern Layer l_global;
|
||||||
|
extern Layer l_global_top;
|
||||||
|
extern Layer l_system;
|
||||||
|
extern Layer l_lock;
|
@ -1,5 +1,6 @@
|
|||||||
#include "Mouse.h"
|
#include "Mouse.h"
|
||||||
#include "Client.h"
|
#include "Client.h"
|
||||||
|
#include "Layer.h"
|
||||||
#include <os/File.h>
|
#include <os/File.h>
|
||||||
#include <os/IPC.h>
|
#include <os/IPC.h>
|
||||||
#include <ui/Image.h>
|
#include <ui/Image.h>
|
||||||
@ -57,45 +58,17 @@ void Mouse::update(const moon::MousePacket& packet)
|
|||||||
|
|
||||||
else if ((packet.buttons & moon::MouseButton::Left) && !m_dragging_window)
|
else if ((packet.buttons & moon::MouseButton::Left) && !m_dragging_window)
|
||||||
{
|
{
|
||||||
// Iterate from the end of the list, since windows at the beginning are stacked at the bottom and windows at the
|
if (auto* window = Layer::propagate_drag_event(m_position))
|
||||||
// top are at the end.
|
|
||||||
for (Window* window = g_windows.last().value_or(nullptr); window;
|
|
||||||
window = g_windows.previous(window).value_or(nullptr))
|
|
||||||
{
|
|
||||||
if (window->surface.contains(m_position))
|
|
||||||
{
|
|
||||||
if (!(window->attributes & ui::UNFOCUSEABLE)) window->focus();
|
|
||||||
|
|
||||||
if (window->surface.absolute(window->titlebar).contains(m_position))
|
|
||||||
{
|
{
|
||||||
m_dragging_window = window;
|
m_dragging_window = window;
|
||||||
m_initial_drag_position = window->surface.relative(m_position);
|
m_initial_drag_position = window->surface.relative(m_position);
|
||||||
os::println("Started drag: window at (%d,%d,%d,%d) with offset (%d,%d)", window->surface.pos.x,
|
os::println("Started drag: window at (%d,%d,%d,%d) with offset (%d,%d)", window->surface.pos.x,
|
||||||
window->surface.pos.y, window->surface.width, window->surface.height,
|
window->surface.pos.y, window->surface.width, window->surface.height, m_initial_drag_position.x,
|
||||||
m_initial_drag_position.x, m_initial_drag_position.y);
|
m_initial_drag_position.y);
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Window* new_active_window = nullptr;
|
Window* new_active_window = Layer::propagate_mouse_event(m_position, packet.buttons);
|
||||||
|
|
||||||
for (Window* window = g_windows.last().value_or(nullptr); window;
|
|
||||||
window = g_windows.previous(window).value_or(nullptr))
|
|
||||||
{
|
|
||||||
if (window->surface.contains(m_position))
|
|
||||||
{
|
|
||||||
ui::MouseEventRequest request;
|
|
||||||
request.window = window->id;
|
|
||||||
request.position = window->surface.relative(m_position);
|
|
||||||
request.buttons = packet.buttons;
|
|
||||||
window->client->conn->send_async(request);
|
|
||||||
new_active_window = window;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_active_window != new_active_window)
|
if (m_active_window != new_active_window)
|
||||||
{
|
{
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
|
#include "Layer.h"
|
||||||
#include <luna/Utf8.h>
|
#include <luna/Utf8.h>
|
||||||
#include <os/File.h>
|
#include <os/File.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <ui/Font.h>
|
#include <ui/Font.h>
|
||||||
#include <ui/Image.h>
|
#include <ui/Image.h>
|
||||||
|
|
||||||
LinkedList<Window> g_windows;
|
|
||||||
|
|
||||||
void Window::draw(ui::Canvas& screen)
|
void Window::draw(ui::Canvas& screen)
|
||||||
{
|
{
|
||||||
dirty = false;
|
dirty = false;
|
||||||
@ -18,15 +17,16 @@ void Window::draw(ui::Canvas& screen)
|
|||||||
void Window::focus()
|
void Window::focus()
|
||||||
{
|
{
|
||||||
// Bring the window to the front of the list.
|
// Bring the window to the front of the list.
|
||||||
g_windows.remove(this);
|
layer->windows.remove(this);
|
||||||
g_windows.append(this);
|
layer->windows.append(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::Window(ui::Rect r, RefString&& n) : surface(r), name(move(n))
|
Window::Window(ui::Rect r, RefString&& n) : surface(r), name(move(n))
|
||||||
{
|
{
|
||||||
auto font = ui::Font::default_font();
|
auto font = ui::Font::default_font();
|
||||||
titlebar = ui::Rect { 0, 0, 0, 0 };
|
titlebar = ui::Rect { 0, 0, 0, 0 };
|
||||||
g_windows.append(this);
|
l_global.windows.append(this);
|
||||||
|
layer = &l_global;
|
||||||
}
|
}
|
||||||
|
|
||||||
Window::~Window()
|
Window::~Window()
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <ui/ipc/Server.h>
|
#include <ui/ipc/Server.h>
|
||||||
|
|
||||||
struct Client;
|
struct Client;
|
||||||
|
struct Layer;
|
||||||
|
|
||||||
struct Window : public LinkedListNode<Window>
|
struct Window : public LinkedListNode<Window>
|
||||||
{
|
{
|
||||||
@ -17,8 +18,8 @@ struct Window : public LinkedListNode<Window>
|
|||||||
RefString shm_path;
|
RefString shm_path;
|
||||||
bool dirty { false };
|
bool dirty { false };
|
||||||
Client* client;
|
Client* client;
|
||||||
|
Layer* layer;
|
||||||
int id;
|
int id;
|
||||||
ui::WindowAttributes attributes { 0 };
|
|
||||||
|
|
||||||
Window(ui::Rect, RefString&&);
|
Window(ui::Rect, RefString&&);
|
||||||
~Window();
|
~Window();
|
||||||
@ -27,5 +28,3 @@ struct Window : public LinkedListNode<Window>
|
|||||||
|
|
||||||
void draw(ui::Canvas& screen);
|
void draw(ui::Canvas& screen);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern LinkedList<Window> g_windows;
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#define CLIENT_IMPLEMENTATION
|
#define CLIENT_IMPLEMENTATION
|
||||||
#include "Client.h"
|
#include "Client.h"
|
||||||
#include "Keyboard.h"
|
#include "Keyboard.h"
|
||||||
|
#include "Layer.h"
|
||||||
#include "Mouse.h"
|
#include "Mouse.h"
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
#include "Window.h"
|
#include "Window.h"
|
||||||
@ -23,37 +24,6 @@ static constexpr uid_t WIND_USER_ID = 2;
|
|||||||
static constexpr gid_t WIND_GROUP_ID = 2;
|
static constexpr gid_t WIND_GROUP_ID = 2;
|
||||||
static constexpr gid_t WSYS_GROUP_ID = 3;
|
static constexpr gid_t WSYS_GROUP_ID = 3;
|
||||||
|
|
||||||
static void debug(const Vector<OwnedPtr<Client>>& clients)
|
|
||||||
{
|
|
||||||
os::println("--- wind: DEBUG OUTPUT ---");
|
|
||||||
|
|
||||||
os::println("-- wind: Listing clients --");
|
|
||||||
|
|
||||||
for (const auto& client : clients)
|
|
||||||
{
|
|
||||||
os::println("Client with fd %d, owns %zu windows", client->conn->fd(), client->windows.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
os::println("-- wind: Listing windows --");
|
|
||||||
|
|
||||||
for (const auto& window : g_windows)
|
|
||||||
{
|
|
||||||
os::println("Window of client (fd %d), id %d, %sdirty (\"%s\") (%d,%d,%d,%d)", window->client->conn->fd(),
|
|
||||||
window->id, window->dirty ? "" : "not ", window->name.chars(), window->surface.pos.x,
|
|
||||||
window->surface.pos.y, window->surface.width, window->surface.height);
|
|
||||||
}
|
|
||||||
|
|
||||||
os::println("-- wind: Listing processes --");
|
|
||||||
|
|
||||||
system("ps");
|
|
||||||
|
|
||||||
os::println("-- wind: Listing memory usage --");
|
|
||||||
|
|
||||||
system("free -h");
|
|
||||||
|
|
||||||
os::println("--- wind: END DEBUG OUTPUT ---");
|
|
||||||
}
|
|
||||||
|
|
||||||
Result<int> luna_main(int argc, char** argv)
|
Result<int> luna_main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
srand((unsigned)time(NULL));
|
srand((unsigned)time(NULL));
|
||||||
@ -133,7 +103,7 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
screen.canvas().fill(background);
|
screen.canvas().fill(background);
|
||||||
for (auto* window : g_windows) window->draw(screen.canvas());
|
Layer::draw_all_windows(screen.canvas());
|
||||||
mouse_pointer.draw(screen.canvas());
|
mouse_pointer.draw(screen.canvas());
|
||||||
screen.sync();
|
screen.sync();
|
||||||
|
|
||||||
@ -153,11 +123,9 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
moon::KeyboardPacket packet;
|
moon::KeyboardPacket packet;
|
||||||
TRY(keyboard->read_typed(packet));
|
TRY(keyboard->read_typed(packet));
|
||||||
if (!packet.released && packet.key == moon::K_Tab) debug(clients);
|
|
||||||
auto request = wind::Keyboard::decode_keyboard_event((moon::KeyCode)packet.key, packet.released);
|
auto request = wind::Keyboard::decode_keyboard_event((moon::KeyCode)packet.key, packet.released);
|
||||||
if (g_windows.last().has_value())
|
if (auto* window = Layer::focused_window())
|
||||||
{
|
{
|
||||||
auto* window = g_windows.last().value();
|
|
||||||
request.window = window->id;
|
request.window = window->id;
|
||||||
window->client->conn->send_async(request);
|
window->client->conn->send_async(request);
|
||||||
}
|
}
|
||||||
@ -198,7 +166,7 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
{
|
{
|
||||||
if (window)
|
if (window)
|
||||||
{
|
{
|
||||||
g_windows.remove(window);
|
window->layer->windows.remove(window);
|
||||||
mouse_pointer.window_did_close(window);
|
mouse_pointer.window_did_close(window);
|
||||||
delete window;
|
delete window;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user