Compare commits
10 Commits
df2aa925cb
...
16d57d0194
| Author | SHA1 | Date | |
|---|---|---|---|
| 16d57d0194 | |||
| f1a0738d13 | |||
| b81ff29e00 | |||
| 0dc88d09bf | |||
| 97e82afd4d | |||
| d787afb7e3 | |||
| f6a87f064f | |||
| 7fe5b0174f | |||
| 6450fd9a2f | |||
| 2ddd67dede |
@@ -374,6 +374,9 @@ void invalidate_window(WINDOW wid, int32_t x, int32_t y, int32_t w, int32_t h)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (wid == g_root.windowId)
|
||||
return;
|
||||
|
||||
auto& object = *g_objects[wid];
|
||||
ASSERT(object.type == Object::Type::Window);
|
||||
|
||||
@@ -506,17 +509,26 @@ transitient_for_done:
|
||||
|
||||
static BAN::ErrorOr<void> map_window(Client& client_info, WINDOW wid)
|
||||
{
|
||||
static const CARD32 WM_CLASS = g_atoms_name_to_id["WM_CLASS"_sv];
|
||||
|
||||
auto& object = *g_objects[wid];
|
||||
ASSERT(object.type == Object::Type::Window);
|
||||
|
||||
auto& window = object.object.get<Object::Window>();
|
||||
if (window.mapped)
|
||||
return {};
|
||||
window.mapped = true;
|
||||
|
||||
if (window.parent == g_root.windowId)
|
||||
{
|
||||
ASSERT(!window.platform_window);
|
||||
|
||||
// NOTE: This is not perfect but seems to work.
|
||||
// This is used to not display "dummy" event windows
|
||||
// that should not be visible.
|
||||
if (!window.properties.contains(WM_CLASS))
|
||||
return {};
|
||||
|
||||
auto info = get_plaform_window_info(window);
|
||||
window.platform_window = TRY(g_platform_ops.create_window(
|
||||
info.transient_for,
|
||||
@@ -529,8 +541,6 @@ static BAN::ErrorOr<void> map_window(Client& client_info, WINDOW wid)
|
||||
));
|
||||
}
|
||||
|
||||
window.mapped = true;
|
||||
|
||||
for (auto& pixel : window.pixels)
|
||||
pixel = window.background;
|
||||
invalidate_window(wid, 0, 0, window.width, window.height);
|
||||
@@ -715,7 +725,7 @@ static PlatformWindow* get_platform_window(const Object::Window& window)
|
||||
{
|
||||
if (window.platform_window)
|
||||
return const_cast<PlatformWindow*>(window.platform_window.ptr());
|
||||
if (window.parent == g_root.windowId)
|
||||
if (window.parent == None)
|
||||
return nullptr;
|
||||
|
||||
auto& object = *g_objects[window.parent];
|
||||
@@ -728,30 +738,28 @@ void update_cursor(WINDOW wid, int32_t x, int32_t y)
|
||||
if (g_platform_ops.set_cursor == nullptr)
|
||||
return;
|
||||
|
||||
const auto child_wid = find_child_window(wid, x, y);
|
||||
if (child_wid == None)
|
||||
wid = find_child_window(wid, x, y);
|
||||
if (wid == None)
|
||||
return;
|
||||
|
||||
CURSOR cursor = None;
|
||||
|
||||
if (child_wid != None)
|
||||
const CURSOR cid = [&wid]() -> CURSOR {
|
||||
for (;;)
|
||||
{
|
||||
auto& object = *g_objects[child_wid];
|
||||
ASSERT(object.type == Object::Type::Window);
|
||||
cursor = object.object.get<Object::Window>().cursor;
|
||||
const auto& window = g_objects[wid]->object.get<Object::Window>();
|
||||
if (window.cursor != None || window.parent == None)
|
||||
return window.cursor;
|
||||
wid = window.parent;
|
||||
}
|
||||
}();
|
||||
|
||||
static CURSOR active_cursor = None;
|
||||
if (cursor == active_cursor)
|
||||
static CURSOR active_cid = None;
|
||||
if (cid == active_cid)
|
||||
return;
|
||||
|
||||
auto& object = *g_objects[wid];
|
||||
ASSERT(object.type == Object::Type::Window);
|
||||
auto& window = object.object.get<Object::Window>();
|
||||
const auto& window = g_objects[wid]->object.get<Object::Window>();
|
||||
g_platform_ops.set_cursor(get_platform_window(window), get_cursor_safe(cid));
|
||||
|
||||
g_platform_ops.set_cursor(get_platform_window(window), get_cursor_safe(cursor));
|
||||
|
||||
active_cursor = window.cursor;
|
||||
active_cid = cid;
|
||||
}
|
||||
|
||||
static void on_root_client_message(const xEvent& event)
|
||||
@@ -1010,9 +1018,11 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
}
|
||||
|
||||
if (cursor_id.has_value())
|
||||
{
|
||||
window.cursor = cursor_id.value();
|
||||
if (window.hovered)
|
||||
update_cursor(request.window, window.cursor_x, window.cursor_y);
|
||||
}
|
||||
|
||||
if (background.has_value())
|
||||
window.background = background.value();
|
||||
@@ -1932,12 +1942,15 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
|
||||
const auto& window = TRY_REF(get_window(client_info, wid, opcode));
|
||||
|
||||
int32_t root_x, root_y;
|
||||
int32_t event_x, event_y;
|
||||
root_x = event_x = window.cursor_x;
|
||||
root_y = event_y = window.cursor_y;
|
||||
|
||||
const auto child_wid = find_child_window(wid, event_x, event_y);
|
||||
WINDOW child_wid { None };
|
||||
for (auto wid_ : window.children)
|
||||
{
|
||||
const auto& child_window = g_objects[wid_]->object.get<Object::Window>();
|
||||
if (!child_window.hovered)
|
||||
continue;
|
||||
child_wid = wid_;
|
||||
break;
|
||||
}
|
||||
|
||||
xQueryPointerReply reply {
|
||||
.type = X_Reply,
|
||||
@@ -1945,11 +1958,11 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
.sequenceNumber = client_info.sequence,
|
||||
.length = 0,
|
||||
.root = g_root.windowId,
|
||||
.child = static_cast<CARD32>(child_wid == wid ? None : child_wid),
|
||||
.rootX = static_cast<INT16>(root_x),
|
||||
.rootY = static_cast<INT16>(root_y),
|
||||
.winX = static_cast<INT16>(event_x),
|
||||
.winY = static_cast<INT16>(event_y),
|
||||
.child = static_cast<CARD32>(child_wid),
|
||||
.rootX = static_cast<INT16>(window.cursor_x), // FIXME
|
||||
.rootY = static_cast<INT16>(window.cursor_y), // FIXME
|
||||
.winX = static_cast<INT16>(window.cursor_x),
|
||||
.winY = static_cast<INT16>(window.cursor_y),
|
||||
.mask = static_cast<KeyButMask>(g_keymask | g_butmask),
|
||||
};
|
||||
TRY(encode(client_info.output_buffer, reply));
|
||||
@@ -2052,8 +2065,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
.depth = request.depth,
|
||||
.width = request.width,
|
||||
.height = request.height,
|
||||
.data = data.span(),
|
||||
.owned_data = BAN::move(data),
|
||||
.data = BAN::move(data),
|
||||
}
|
||||
}))
|
||||
));
|
||||
@@ -2697,7 +2709,7 @@ BAN::ErrorOr<void> handle_packet(Client& client_info, BAN::ConstByteSpan packet)
|
||||
{
|
||||
auto request = decode<xQueryBestSizeReq>(packet).value();
|
||||
|
||||
dprintln("FreeCursor");
|
||||
dprintln("QueryBestSize");
|
||||
dprintln(" class: {}", request.c_class);
|
||||
dprintln(" drawable: {}", request.drawable);
|
||||
dprintln(" width: {}", request.width);
|
||||
|
||||
@@ -81,8 +81,7 @@ struct Object
|
||||
CARD8 depth;
|
||||
CARD32 width;
|
||||
CARD32 height;
|
||||
BAN::ByteSpan data;
|
||||
BAN::Vector<uint8_t> owned_data;
|
||||
BAN::Vector<uint8_t> data;
|
||||
};
|
||||
|
||||
struct GraphicsContext
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#include "Base.h"
|
||||
#include "Definitions.h"
|
||||
#include "Keymap.h"
|
||||
#include "Platform.h"
|
||||
#include "SafeGetters.h"
|
||||
#include "Utils.h"
|
||||
|
||||
#include <X11/X.h>
|
||||
@@ -451,14 +449,26 @@ static void send_enter_and_leave_events(WINDOW old_wid, int32_t old_x, int32_t o
|
||||
MUST(window.send_event(event, EnterWindowMask));
|
||||
}
|
||||
|
||||
const auto set_last_entry_hovered = [](const BAN::Vector<WINDOW>& path, bool value) {
|
||||
if (path.empty())
|
||||
return;
|
||||
g_objects[path.back()]->object.get<Object::Window>().hovered = value;
|
||||
};
|
||||
for (const auto wid : old_child_path)
|
||||
g_objects[wid]->object.get<Object::Window>().hovered = false;
|
||||
for (const auto wid : new_child_path)
|
||||
g_objects[wid]->object.get<Object::Window>().hovered = true;
|
||||
}
|
||||
|
||||
set_last_entry_hovered(old_child_path, false);
|
||||
set_last_entry_hovered(new_child_path, true);
|
||||
static WINDOW s_current_top_level_window = None;
|
||||
|
||||
void on_window_leave_event(WINDOW wid)
|
||||
{
|
||||
if (s_current_top_level_window != wid)
|
||||
return;
|
||||
|
||||
auto& object = *g_objects[wid];
|
||||
ASSERT(object.type == Object::Type::Window);
|
||||
auto& window = object.object.get<Object::Window>();
|
||||
|
||||
send_enter_and_leave_events(wid, window.cursor_x, window.cursor_y, wid, -1, -1);
|
||||
|
||||
s_current_top_level_window = None;
|
||||
}
|
||||
|
||||
void on_mouse_move_event(WINDOW wid, int32_t x, int32_t y)
|
||||
@@ -469,21 +479,17 @@ void on_mouse_move_event(WINDOW wid, int32_t x, int32_t y)
|
||||
|
||||
update_cursor(wid, x, y);
|
||||
|
||||
if (auto it = g_objects.find(s_current_top_level_window); it == g_objects.end())
|
||||
send_enter_and_leave_events(wid, -1, -1, wid, x, y);
|
||||
else
|
||||
{
|
||||
static WINDOW old_wid = g_root.windowId;
|
||||
|
||||
auto it = g_objects.find(old_wid);
|
||||
if (it == g_objects.end())
|
||||
it = g_objects.find(g_root.windowId);
|
||||
|
||||
ASSERT(it->value->type == Object::Type::Window);
|
||||
auto& old_window = it->value->object.get<Object::Window>();
|
||||
|
||||
send_enter_and_leave_events(old_wid, old_window.cursor_x, old_window.cursor_y, wid, x, y);
|
||||
|
||||
old_wid = wid;
|
||||
send_enter_and_leave_events(s_current_top_level_window, old_window.cursor_x, old_window.cursor_y, wid, x, y);
|
||||
}
|
||||
|
||||
s_current_top_level_window = wid;
|
||||
|
||||
update_cursor_position_recursive(wid, x, y);
|
||||
|
||||
// TODO: optimize with PointerMotionHint
|
||||
|
||||
@@ -9,6 +9,7 @@ void on_window_close_event(WINDOW wid);
|
||||
void on_window_resize_event(WINDOW wid, uint32_t width, uint32_t height);
|
||||
void on_window_focus_event(WINDOW wid, bool focused);
|
||||
void on_window_fullscreen_event(WINDOW wid, bool is_fullscreen);
|
||||
void on_window_leave_event(WINDOW wid);
|
||||
|
||||
void on_mouse_move_event(WINDOW wid, int32_t x, int32_t y);
|
||||
void on_mouse_button_event(WINDOW wid, uint8_t xbutton, bool pressed);
|
||||
|
||||
@@ -7,42 +7,13 @@
|
||||
#include <X11/X.h>
|
||||
#include <X11/extensions/shmproto.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <sys/shm.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static BYTE s_shm_event_base;
|
||||
static BYTE s_shm_error_base;
|
||||
static BYTE s_shm_major_opcode;
|
||||
|
||||
static bool is_local_socket(int socket)
|
||||
{
|
||||
sockaddr_storage addr;
|
||||
socklen_t addr_len = sizeof(addr);
|
||||
if (getpeername(socket, reinterpret_cast<sockaddr*>(&addr), &addr_len) == -1)
|
||||
return false;
|
||||
|
||||
switch (addr.ss_family)
|
||||
{
|
||||
case AF_UNIX:
|
||||
return true;
|
||||
case AF_INET:
|
||||
{
|
||||
const auto* addr_in = reinterpret_cast<const sockaddr_in*>(&addr);
|
||||
const auto ipv4 = ntohl(addr_in->sin_addr.s_addr);
|
||||
return (ipv4 & IN_CLASSA_NET) == IN_LOOPBACKNET;
|
||||
}
|
||||
case AF_INET6:
|
||||
{
|
||||
const auto* addr_in6 = reinterpret_cast<const sockaddr_in6*>(&addr);
|
||||
return IN6_IS_ADDR_LOOPBACK(&addr_in6->sin6_addr);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static BAN::ErrorOr<void*> get_shmseg(Client& client_info, CARD32 shmseg, BYTE op_major, BYTE op_minor)
|
||||
{
|
||||
auto it = g_objects.find(shmseg);
|
||||
@@ -74,11 +45,11 @@ static BAN::ErrorOr<void> extension_shm(Client& client_info, BAN::ConstByteSpan
|
||||
{
|
||||
case X_ShmQueryVersion:
|
||||
{
|
||||
dwarnln("ShmQueryVersion");
|
||||
dprintln("ShmQueryVersion");
|
||||
|
||||
xShmQueryVersionReply reply {
|
||||
.type = X_Reply,
|
||||
.sharedPixmaps = is_local_socket(client_info.fd),
|
||||
.sharedPixmaps = false,
|
||||
.sequenceNumber = client_info.sequence,
|
||||
.length = 0,
|
||||
.majorVersion = 1,
|
||||
@@ -95,7 +66,7 @@ static BAN::ErrorOr<void> extension_shm(Client& client_info, BAN::ConstByteSpan
|
||||
{
|
||||
auto request = decode<xShmAttachReq>(packet).value();
|
||||
|
||||
dwarnln("ShmAttach");
|
||||
dprintln("ShmAttach");
|
||||
dprintln(" shmseg: {}", request.shmseg);
|
||||
dprintln(" shmid: {}", request.shmid);
|
||||
dprintln(" readOnly: {}", request.readOnly);
|
||||
@@ -144,7 +115,7 @@ static BAN::ErrorOr<void> extension_shm(Client& client_info, BAN::ConstByteSpan
|
||||
{
|
||||
auto request = decode<xShmDetachReq>(packet).value();
|
||||
|
||||
dwarnln("ShmDetach");
|
||||
dprintln("ShmDetach");
|
||||
dprintln(" shmseg: {}", request.shmseg);
|
||||
|
||||
void* shm_segment = TRY(get_shmseg(client_info, request.shmseg, op_major, op_minor));
|
||||
@@ -159,7 +130,7 @@ static BAN::ErrorOr<void> extension_shm(Client& client_info, BAN::ConstByteSpan
|
||||
{
|
||||
auto request = decode<xShmPutImageReq>(packet).value();
|
||||
|
||||
dwarnln("ShmPutImage");
|
||||
dprintln("ShmPutImage");
|
||||
dprintln(" drawable: {}", request.drawable);
|
||||
dprintln(" gc: {}", request.gc);
|
||||
dprintln(" totalWidth: {}", request.totalWidth);
|
||||
@@ -223,7 +194,7 @@ static BAN::ErrorOr<void> extension_shm(Client& client_info, BAN::ConstByteSpan
|
||||
{
|
||||
auto request = decode<xShmGetImageReq>(packet).value();
|
||||
|
||||
dwarnln("ShmGetImage");
|
||||
dprintln("ShmGetImage");
|
||||
dprintln(" drawable: {}", request.drawable);
|
||||
dprintln(" x: {}", request.x);
|
||||
dprintln(" y: {}", request.y);
|
||||
@@ -265,44 +236,6 @@ static BAN::ErrorOr<void> extension_shm(Client& client_info, BAN::ConstByteSpan
|
||||
|
||||
break;
|
||||
}
|
||||
case X_ShmCreatePixmap:
|
||||
{
|
||||
auto request = decode<xShmCreatePixmapReq>(packet).value();
|
||||
|
||||
dwarnln("ShmCreatePixmap");
|
||||
dprintln(" depth: {}", request.depth);
|
||||
dprintln(" pid: {}", request.pid);
|
||||
dprintln(" drawable: {}", request.drawable);
|
||||
dprintln(" width: {}", request.width);
|
||||
dprintln(" height: {}", request.height);
|
||||
dprintln(" shmseg: {}", request.shmseg);
|
||||
dprintln(" offset: {}", request.offset);
|
||||
|
||||
uint8_t bpp = 0;
|
||||
for (auto format : g_formats)
|
||||
if (format.depth == request.depth)
|
||||
bpp = format.bitsPerPixel;
|
||||
ASSERT(bpp == 32);
|
||||
|
||||
void* shm_segment = TRY(get_shmseg(client_info, request.shmseg, op_major, op_minor));
|
||||
|
||||
TRY(client_info.objects.insert(request.pid));
|
||||
TRY(g_objects.insert(
|
||||
request.pid,
|
||||
TRY(BAN::UniqPtr<Object>::create(Object {
|
||||
.type = Object::Type::Pixmap,
|
||||
.object = Object::Pixmap {
|
||||
.depth = request.depth,
|
||||
.width = request.width,
|
||||
.height = request.height,
|
||||
.data = BAN::ByteSpan(static_cast<uint8_t*>(shm_segment) + request.offset, request.width * request.height * 4),
|
||||
.owned_data = {},
|
||||
}
|
||||
}))
|
||||
));
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
dwarnln("unsupported shm minor opcode {}", packet[1]);
|
||||
break;
|
||||
|
||||
@@ -60,8 +60,33 @@ void put_image(const PutImageInfo& info)
|
||||
}
|
||||
case ZPixmap:
|
||||
{
|
||||
bool needs_clipping = true;
|
||||
|
||||
if (info.gc.clip_mask == None)
|
||||
{
|
||||
needs_clipping = false;
|
||||
}
|
||||
else if (info.gc.clip_mask == UINT32_MAX)
|
||||
{
|
||||
const uint32_t clip_min_x = min_x - info.gc.clip_origin_x;
|
||||
const uint32_t clip_min_y = min_y - info.gc.clip_origin_y;
|
||||
|
||||
const uint32_t clip_max_x = max_x - info.gc.clip_origin_x;
|
||||
const uint32_t clip_max_y = max_y - info.gc.clip_origin_y;
|
||||
|
||||
for (const auto& rect : info.gc.clip_rects)
|
||||
{
|
||||
if (clip_min_x < rect.x || clip_max_x > rect.x + rect.width)
|
||||
continue;
|
||||
if (clip_min_y < rect.y || clip_max_y > rect.y + rect.height)
|
||||
continue;
|
||||
needs_clipping = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT(info.left_pad == 0);
|
||||
if (in_bpp == 32 && info.gc.clip_mask == None)
|
||||
if (in_bpp == 32 && !needs_clipping)
|
||||
{
|
||||
const auto bytes_per_row = (max_x - min_x) * 4;
|
||||
for (int32_t y = min_y; y < max_y; y++)
|
||||
|
||||
@@ -115,7 +115,7 @@ static BAN::ErrorOr<BAN::UniqPtr<PlatformWindow>> sdl2_create_window(PlatformWin
|
||||
window->width = width;
|
||||
window->height = height;
|
||||
|
||||
if (parent == nullptr || type != WindowType::Popup)
|
||||
if (parent == nullptr)
|
||||
x = y = SDL_WINDOWPOS_UNDEFINED;
|
||||
else
|
||||
{
|
||||
@@ -215,6 +215,9 @@ static void sdl2_poll_events(void*)
|
||||
case SDL_WINDOWEVENT_RESTORED:
|
||||
on_window_fullscreen_event(window.wid, false);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_LEAVE:
|
||||
on_window_leave_event(window.wid);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -325,11 +328,10 @@ static void sdl2_invalidate(PlatformWindow* window, const uint32_t* src_pixels,
|
||||
static void sdl2_request_fullscreen(PlatformWindow* window, bool fullscreen)
|
||||
{
|
||||
auto& sdl_window = *static_cast<SDLWindow*>(window);
|
||||
(void)sdl_window;
|
||||
(void)fullscreen;
|
||||
SDL_SetWindowFullscreen(sdl_window.window, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::UniqPtr<PlatformCursor>> sdl2_create_system_cursor(SystemCursorType type)
|
||||
static BAN::ErrorOr<BAN::UniqPtr<PlatformCursor>> sdl2_create_system_cursor(SystemCursorType type)
|
||||
{
|
||||
SDL_SystemCursor sdl_type;
|
||||
switch (type)
|
||||
@@ -385,7 +387,7 @@ BAN::ErrorOr<BAN::UniqPtr<PlatformCursor>> sdl2_create_system_cursor(SystemCurso
|
||||
return BAN::UniqPtr<PlatformCursor>(BAN::move(cursor));
|
||||
}
|
||||
|
||||
BAN::ErrorOr<BAN::UniqPtr<PlatformCursor>> sdl2_create_bitmap_cursor(const uint32_t* pixels, uint32_t width, uint32_t height, int32_t origin_x, int32_t origin_y)
|
||||
static BAN::ErrorOr<BAN::UniqPtr<PlatformCursor>> sdl2_create_bitmap_cursor(const uint32_t* pixels, uint32_t width, uint32_t height, int32_t origin_x, int32_t origin_y)
|
||||
{
|
||||
auto cursor = TRY(BAN::UniqPtr<SDLCursor>::create());
|
||||
|
||||
@@ -396,6 +398,8 @@ BAN::ErrorOr<BAN::UniqPtr<PlatformCursor>> sdl2_create_bitmap_cursor(const uint3
|
||||
return BAN::Error::from_errno(EFAULT);
|
||||
}
|
||||
|
||||
origin_x = BAN::Math::clamp<int32_t>(origin_x, 0, width - 1);
|
||||
origin_y = BAN::Math::clamp<int32_t>(origin_y, 0, height - 1);
|
||||
cursor->cursor = SDL_CreateColorCursor(surface, origin_x, origin_y);
|
||||
|
||||
SDL_FreeSurface(surface);
|
||||
@@ -409,7 +413,7 @@ BAN::ErrorOr<BAN::UniqPtr<PlatformCursor>> sdl2_create_bitmap_cursor(const uint3
|
||||
return BAN::UniqPtr<PlatformCursor>(BAN::move(cursor));
|
||||
}
|
||||
|
||||
void sdl2_set_cursor(PlatformWindow*, PlatformCursor* cursor)
|
||||
static void sdl2_set_cursor(PlatformWindow*, PlatformCursor* cursor)
|
||||
{
|
||||
if (cursor == nullptr)
|
||||
SDL_SetCursor(s_default_cursor);
|
||||
|
||||
@@ -290,6 +290,18 @@ int main()
|
||||
window.event_masks.remove(&client_info);
|
||||
}
|
||||
|
||||
for (auto it = client_info.objects.begin(); it != client_info.objects.end();)
|
||||
{
|
||||
auto obj_it = g_objects.find(*it);
|
||||
if (obj_it == g_objects.end() || obj_it->value->type != Object::Type::Window)
|
||||
it++;
|
||||
else
|
||||
{
|
||||
(void)destroy_window(client_info, *it);
|
||||
it = client_info.objects.begin();
|
||||
}
|
||||
}
|
||||
|
||||
for (auto id : client_info.objects)
|
||||
{
|
||||
auto it = g_objects.find(id);
|
||||
@@ -304,15 +316,14 @@ int main()
|
||||
case Object::Type::Pixmap:
|
||||
case Object::Type::GraphicsContext:
|
||||
case Object::Type::Font:
|
||||
case Object::Type::Window:
|
||||
break;
|
||||
case Object::Type::Window:
|
||||
ASSERT_NOT_REACHED();
|
||||
case Object::Type::Extension:
|
||||
{
|
||||
auto& extension = object.object.get<Object::Extension>();
|
||||
extension.destructor(extension);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_objects.remove(it);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user