Inhibit screensaver using dbus or xdg-screensaver

This commit is contained in:
Jack Andersen 2019-06-11 15:55:58 -10:00
parent 99519d3882
commit 29a67b9ea8
10 changed files with 166 additions and 73 deletions

View File

@ -19,7 +19,6 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
find_package(IPP)
if (IPP_FOUND)
list(APPEND _BOO_SYS_DEFINES -DINTEL_IPP=1)
include_directories(${IPP_INCLUDE_DIRS})
list(APPEND _BOO_SYS_INCLUDES ${IPP_INCLUDE_DIRS})
list(APPEND _BOO_SYS_LIBS ${IPP_LIBRARIES})
message(STATUS "Building with IPP support")
@ -29,9 +28,7 @@ endif ()
add_subdirectory(soxr/src)
set(BOO_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include CACHE PATH "boo include path" FORCE)
include_directories(include ${CMAKE_CURRENT_SOURCE_DIR} ${LOGVISOR_INCLUDE_DIR})
set(_EXTRA_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(lib/graphicsdev/nx)
if(TARGET nx_compiler)
@ -49,8 +46,6 @@ list(APPEND PLAT_HDRS
include/boo/graphicsdev/GL.hpp
include/boo/graphicsdev/Vulkan.hpp
include/boo/graphicsdev/VulkanDispatchTable.hpp)
add_library(glew lib/graphicsdev/glew.c)
endif()
if(WINDOWS_STORE)
@ -80,7 +75,7 @@ elseif(WIN32)
if (NOT ${VULKAN_SDK_DIRS} STREQUAL "/registry")
message(STATUS "Enabling Vulkan support")
list(GET VULKAN_SDK_DIRS 0 VULKAN_SDK_DIR)
include_directories("${VULKAN_SDK_DIR}/Include")
list(APPEND _EXTRA_INCLUDES ${VULKAN_SDK_DIR}/Include)
list(APPEND _BOO_SYS_DEFINES -DBOO_HAS_VULKAN=1 -DVK_USE_PLATFORM_WIN32_KHR=1)
list(APPEND _BOO_SYS_INCLUDES "${VULKAN_SDK_DIR}/Include")
list(APPEND PLAT_SRCS lib/graphicsdev/Vulkan.cpp
@ -92,7 +87,7 @@ elseif(WIN32)
if (NO AND TE_VIRTUAL_MIDI_H)
message(STATUS "Enabling teVirtualMIDI")
get_filename_component(TE_VIRTUAL_MIDI_DIR ${TE_VIRTUAL_MIDI_H} DIRECTORY)
include_directories(${TE_VIRTUAL_MIDI_DIR})
list(APPEND _EXTRA_INCLUDES ${TE_VIRTUAL_MIDI_DIR})
add_definitions("-DTE_VIRTUAL_MIDI=1")
endif()
@ -153,7 +148,6 @@ elseif(APPLE)
${QUARTZCORE_LIBRARY} ${COREVIDEO_LIBRARY} ${AUDIOTOOLBOX_LIBRARY}
${COREAUDIO_LIBRARY} ${COREMIDI_LIBRARY})
add_library(glew lib/graphicsdev/glew.c)
elseif(NX)
list(APPEND _BOO_SYS_DEFINES -DBOO_HAS_NX=1)
list(APPEND PLAT_SRCS
@ -228,7 +222,7 @@ else(NOT GEKKO)
message(FATAL_ERROR "Unix build of boo requires dbus")
endif()
include_directories(${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR})
list(APPEND _EXTRA_INCLUDES ${DBUS_INCLUDE_DIR} ${DBUS_ARCH_INCLUDE_DIR})
list(APPEND _BOO_SYS_LIBS X11 Xi Xrandr GL asound ${DBUS_LIBRARY} pthread)
if(NOT ${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
@ -274,7 +268,8 @@ if(NOT NX)
add_subdirectory(glslang/StandAlone)
if (NOT MSVC)
set_target_properties(glslang SPIRV PROPERTIES COMPILE_FLAGS -Wno-implicit-fallthrough)
target_compile_options(glslang PRIVATE -Wno-implicit-fallthrough -Wno-strict-aliasing)
target_compile_options(SPIRV PRIVATE -Wno-implicit-fallthrough -Wno-strict-aliasing)
endif()
target_include_directories(glslang-default-resource-limits
@ -284,12 +279,7 @@ if(NOT NX)
list(APPEND _BOO_SYS_LIBS glslang soxr xxhash OSDependent OGLCompiler SPIRV glslang-default-resource-limits)
endif()
set(BOO_SYS_LIBS ${_BOO_SYS_LIBS} CACHE PATH "boo system libraries" FORCE)
set(BOO_SYS_DEFINES ${_BOO_SYS_DEFINES} CACHE STRING "boo system defines" FORCE)
set(BOO_SYS_INCLUDES ${_BOO_SYS_INCLUDES} CACHE PATH "boo system includes" FORCE)
add_definitions(${_BOO_SYS_DEFINES})
include_directories(include glslang soxr/src)
list(APPEND _EXTRA_INCLUDES glslang soxr/src)
add_library(boo
lib/inputdev/DeviceBase.cpp include/boo/inputdev/DeviceBase.hpp
@ -343,6 +333,10 @@ add_library(boo
InputDeviceClasses.cpp
${PLAT_SRCS}
${PLAT_HDRS})
target_link_libraries(boo PUBLIC ${_BOO_SYS_LIBS} logvisor)
target_compile_definitions(boo PUBLIC ${_BOO_SYS_DEFINES})
target_include_directories(boo PUBLIC include ${_BOO_SYS_INCLUDES}
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${_EXTRA_INCLUDES})
if(COMMAND add_sanitizers)
add_sanitizers(boo)
endif()

View File

@ -549,11 +549,11 @@ public:
}
void setClampMode(TextureClampMode mode) {
for (int i = 0; i < m_colorBindCount; ++i) {
for (size_t i = 0; i < m_colorBindCount; ++i) {
glBindTexture(GL_TEXTURE_2D, m_bindTexs[0][i]);
SetClampMode(GL_TEXTURE_2D, mode);
}
for (int i = 0; i < m_depthBindCount; ++i) {
for (size_t i = 0; i < m_depthBindCount; ++i) {
glBindTexture(GL_TEXTURE_2D, m_bindTexs[1][i]);
SetClampMode(GL_TEXTURE_2D, mode);
}
@ -634,7 +634,7 @@ public:
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAX_LEVEL, m_mipCount - 1);
for (int f = 0; f < 6; ++f) {
size_t tmpWidth = m_width;
for (int m = 0; m < m_mipCount; ++m) {
for (size_t m = 0; m < m_mipCount; ++m) {
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, m, m_colorFormat, tmpWidth, tmpWidth,
0, GL_RGBA, compType, nullptr);
tmpWidth >>= 1;
@ -1258,14 +1258,14 @@ struct GLCommandQueue : IGraphicsCommandQueue {
if (tex->m_samples > 1) {
if (tex->m_colorBindCount) {
glGenFramebuffers(tex->m_colorBindCount, tex->m_bindFBOs[0]);
for (int i = 0; i < tex->m_colorBindCount; ++i) {
for (size_t i = 0; i < tex->m_colorBindCount; ++i) {
glBindFramebuffer(GL_FRAMEBUFFER, tex->m_bindFBOs[0][i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tex->m_bindTexs[0][i], 0);
}
}
if (tex->m_depthBindCount) {
glGenFramebuffers(tex->m_depthBindCount, tex->m_bindFBOs[1]);
for (int i = 0; i < tex->m_depthBindCount; ++i) {
for (size_t i = 0; i < tex->m_depthBindCount; ++i) {
glBindFramebuffer(GL_FRAMEBUFFER, tex->m_bindFBOs[1][i]);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex->m_bindTexs[1][i], 0);
}
@ -1820,14 +1820,14 @@ GLTextureR::GLTextureR(const ObjToken<BaseGraphicsData>& parent, GLCommandQueue*
nullptr);
}
for (int i = 0; i < colorBindingCount; ++i) {
for (size_t i = 0; i < colorBindingCount; ++i) {
glBindTexture(GL_TEXTURE_2D, m_bindTexs[0][i]);
glTexImage2D(GL_TEXTURE_2D, 0, colorFormat, width, height, 0, GL_RGBA, compType, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
SetClampMode(GL_TEXTURE_2D, clampMode);
}
for (int i = 0; i < depthBindingCount; ++i) {
for (size_t i = 0; i < depthBindingCount; ++i) {
glBindTexture(GL_TEXTURE_2D, m_bindTexs[1][i]);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32F, width, height, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
nullptr);

View File

@ -1444,7 +1444,7 @@ public:
size_t height = m_height;
size_t regionCount = std::min(size_t(16), m_mips);
size_t offset = 0;
for (int i = 0; i < regionCount; ++i) {
for (size_t i = 0; i < regionCount; ++i) {
size_t regionPitch = width * height * m_pixelPitchNum / m_pixelPitchDenom;
copyRegions[i].imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@ -1603,7 +1603,7 @@ public:
size_t height = m_height;
size_t regionCount = std::min(size_t(16), m_mips);
size_t offset = 0;
for (int i = 0; i < regionCount; ++i) {
for (size_t i = 0; i < regionCount; ++i) {
size_t regionPitch = width * height * m_layers * m_pixelPitchNum / m_pixelPitchDenom;
copyRegions[i].imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
@ -1971,18 +1971,18 @@ public:
void commitLayouts() {
m_colorTex.commitLayout();
m_depthTex.commitLayout();
for (int i = 0; i < m_colorBindCount; ++i)
for (size_t i = 0; i < m_colorBindCount; ++i)
m_colorBindTex[i].commitLayout();
for (int i = 0; i < m_depthBindCount; ++i)
for (size_t i = 0; i < m_depthBindCount; ++i)
m_depthBindTex[i].commitLayout();
}
void rollbackLayouts() {
m_colorTex.rollbackLayout();
m_depthTex.rollbackLayout();
for (int i = 0; i < m_colorBindCount; ++i)
for (size_t i = 0; i < m_colorBindCount; ++i)
m_colorBindTex[i].rollbackLayout();
for (int i = 0; i < m_depthBindCount; ++i)
for (size_t i = 0; i < m_depthBindCount; ++i)
m_depthBindTex[i].rollbackLayout();
}
};
@ -3039,7 +3039,7 @@ struct VulkanCommandQueue : IGraphicsCommandQueue {
}
size_t tmpWidth = ctex->m_width;
for (int32_t i = 1; i < ctex->m_mipCount; i++) {
for (size_t i = 1; i < ctex->m_mipCount; i++) {
VkImageBlit blit = {};
blit.srcSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;

View File

@ -26,7 +26,6 @@ static inline EDolphinControllerType parseType(unsigned char status) {
}
static inline EDolphinControllerType parseState(DolphinControllerState* stateOut, uint8_t* payload, bool& rumble) {
memset(stateOut, 0, sizeof(DolphinControllerState));
unsigned char status = payload[0];
EDolphinControllerType type = parseType(status);

View File

@ -408,7 +408,7 @@ struct HIDReports {
static void _AddItem(std::map<int32_t, std::vector<HIDMainItem>>& m, uint32_t flags, const HIDItemState& state) {
std::vector<HIDMainItem>& report = m[state.m_reportID];
report.reserve(report.size() + state.m_reportCount);
for (int i = 0; i < state.m_reportCount; ++i)
for (uint32_t i = 0; i < state.m_reportCount; ++i)
report.emplace_back(flags, state, i);
}

View File

@ -3,11 +3,87 @@
*/
#define APPLICATION_UNIX_CPP
#include <dbus/dbus.h>
#include <cstdint>
#include <unistd.h>
#include "logvisor/logvisor.hpp"
#include "boo/IApplication.hpp"
namespace boo {
static logvisor::Module Log("boo::ApplicationUnix");
IApplication* APP = nullptr;
class ScreenSaverInhibitor {
DBusConnection* m_dbus;
uint64_t m_wid;
DBusPendingCall* m_pending = nullptr;
uint32_t m_cookie = UINT32_MAX;
static void Callback(DBusPendingCall* pending, ScreenSaverInhibitor* user_data) {
user_data->HandleReply();
}
void HandleReply() {
DBusMessage* msg = nullptr;
DBusError err = DBUS_ERROR_INIT;
if ((msg = dbus_pending_call_steal_reply(m_pending)) &&
dbus_message_get_args(msg, &err, DBUS_TYPE_UINT32, &m_cookie, DBUS_TYPE_INVALID)) {
Log.report(logvisor::Info, "Screen saver inhibited");
} else {
/* Fallback to xdg-screensaver */
dbus_error_free(&err);
Log.report(logvisor::Info, "Falling back to xdg-screensaver inhibit");
if (!fork()) {
char win_id[32];
snprintf(win_id, 32, "0x%lX", m_wid);
execlp("xdg-screensaver", "xdg-screensaver", "suspend", win_id, nullptr);
exit(1);
}
}
if (msg)
dbus_message_unref(msg);
dbus_pending_call_unref(m_pending);
m_pending = nullptr;
}
public:
ScreenSaverInhibitor(DBusConnection* dbus, uint64_t wid) : m_dbus(dbus), m_wid(wid) {
#ifndef BOO_MSAN
DBusMessage* msg =
dbus_message_new_method_call("org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver",
"org.freedesktop.ScreenSaver", "Inhibit");
const char* appName = APP->getUniqueName().data();
const char* reason = "Game Active";
dbus_message_append_args(msg, DBUS_TYPE_STRING, &appName, DBUS_TYPE_STRING, &reason, DBUS_TYPE_INVALID);
dbus_connection_send_with_reply(m_dbus, msg, &m_pending, -1);
dbus_pending_call_set_notify(m_pending, DBusPendingCallNotifyFunction(Callback), this, nullptr);
dbus_message_unref(msg);
dbus_connection_flush(m_dbus);
#endif
}
~ScreenSaverInhibitor() {
#ifndef BOO_MSAN
if (m_cookie != UINT32_MAX) {
DBusMessage* msg =
dbus_message_new_method_call("org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver",
"org.freedesktop.ScreenSaver", "UnInhibit");
dbus_message_append_args(msg, DBUS_TYPE_UINT32, &m_cookie, DBUS_TYPE_INVALID);
dbus_connection_send(m_dbus, msg, nullptr);
dbus_message_unref(msg);
dbus_connection_flush(m_dbus);
}
#endif
}
};
}
#include "ApplicationXlib.hpp"
#include "ApplicationWayland.hpp"
#include <memory>
#include <dbus/dbus.h>
#include <cstdio>
/* No icon by default */
@ -46,7 +122,6 @@ DBusConnection* RegisterDBus(const char* appName, bool& isFirst) {
namespace boo {
IApplication* APP = nullptr;
int ApplicationRun(IApplication::EPlatformType platform, IApplicationCallback& cb, std::string_view uniqueName,
std::string_view friendlyName, std::string_view pname, const std::vector<std::string>& args,
std::string_view gfxApi, uint32_t samples, uint32_t anisotropy, bool deepColor,

View File

@ -8,6 +8,7 @@
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include <X11/Xatom.h>
#include <X11/extensions/XInput2.h>
#include <GL/glx.h>
#include <GL/glxext.h>
@ -16,8 +17,6 @@
#include <dbus/dbus.h>
DBusConnection* RegisterDBus(const char* appName, bool& isFirst);
#include "logvisor/logvisor.hpp"
#include <signal.h>
#include <sys/param.h>
#include <thread>
@ -35,7 +34,6 @@ DBusConnection* RegisterDBus(const char* appName, bool& isFirst);
#endif
namespace boo {
static logvisor::Module Log("boo::ApplicationXlib");
XlibCursors X_CURSORS;
int XINPUT_OPCODE = 0;
@ -140,6 +138,7 @@ static XIMStyle ChooseBetterStyle(XIMStyle style1, XIMStyle style2) {
}
class ApplicationXlib final : public IApplication {
friend class ScreenSaverInhibitor;
IApplicationCallback& m_callback;
const std::string m_uniqueName;
const std::string m_friendlyName;
@ -273,6 +272,7 @@ public:
// add a rule for which messages we want to see
DBusError err = {};
dbus_bus_add_match(m_dbus, "type='signal',interface='boo.signal.FileHandling'", &err);
dbus_connection_add_filter(m_dbus, DBusHandleMessageFunction(DBusCallback), this, nullptr);
dbus_connection_flush(m_dbus);
}
}
@ -381,7 +381,8 @@ public:
XFreeFontSet(m_xDisp, m_fontset);
if (m_xIM)
XCloseIM(m_xIM);
XCloseDisplay(m_xDisp);
if (m_xDisp)
XCloseDisplay(m_xDisp);
}
EPlatformType getPlatformType() const { return EPlatformType::Xlib; }
@ -389,6 +390,30 @@ public:
/* Empty handler for SIGINT */
static void _sigint(int) {}
static DBusHandlerResult DBusCallback(DBusConnection* connection,
DBusMessage* message,
ApplicationXlib* user_data) {
return user_data->HandleDBusMessage(message);
}
DBusHandlerResult HandleDBusMessage(DBusMessage* message) {
if (dbus_message_is_signal(message, "boo.signal.FileHandling", "Open")) {
/* read the parameters */
std::vector<std::string> paths;
DBusMessageIter iter;
dbus_message_iter_init(message, &iter);
while (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID) {
const char* argVal;
dbus_message_iter_get_basic(&iter, &argVal);
paths.push_back(argVal);
dbus_message_iter_next(&iter);
}
m_callback.appFilesOpen(this, paths);
return DBUS_HANDLER_RESULT_HANDLED;
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
int run() {
if (!m_xDisp)
return 1;
@ -409,6 +434,9 @@ public:
sigaddset(&waitmask, SIGUSR2);
pthread_sigmask(SIG_BLOCK, &waitmask, &origmask);
/* Screen Saver inhibitor */
std::optional<ScreenSaverInhibitor> inhibitor;
/* Spawn client thread */
int clientReturn = INT_MIN;
std::mutex initmt;
@ -449,13 +477,18 @@ public:
bool windowEvent;
Window evWindow = GetWindowOfEvent(&event, windowEvent);
if (windowEvent) {
auto window = m_windows.find(evWindow);
if (window != m_windows.end())
if (std::shared_ptr<IWindow> w = window->second.lock())
if (w->_incomingEvent(&event) && m_windows.size() == 1) {
needsQuit = true;
break;
}
if (event.type == ClientMessage && event.xclient.data.l[0] == 'NWID') {
if (!inhibitor) /* First window created, use to inhibit screensaver */
inhibitor.emplace(m_dbus, evWindow);
} else {
auto window = m_windows.find(evWindow);
if (window != m_windows.end())
if (std::shared_ptr<IWindow> w = window->second.lock())
if (w->_incomingEvent(&event) && m_windows.size() == 1) {
needsQuit = true;
break;
}
}
}
}
XUnlockDisplay(m_xDisp);
@ -466,25 +499,8 @@ public:
#ifndef BOO_MSAN
if (FD_ISSET(m_dbusFd, &fds)) {
DBusMessage* msg;
dbus_connection_read_write(m_dbus, 0);
while ((msg = dbus_connection_pop_message(m_dbus))) {
/* check if the message is a signal from the correct interface and with the correct name */
if (dbus_message_is_signal(msg, "boo.signal.FileHandling", "Open")) {
/* read the parameters */
std::vector<std::string> paths;
DBusMessageIter iter;
dbus_message_iter_init(msg, &iter);
while (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_INVALID) {
const char* argVal;
dbus_message_iter_get_basic(&iter, &argVal);
paths.push_back(argVal);
dbus_message_iter_next(&iter);
}
m_callback.appFilesOpen(this, paths);
}
dbus_message_unref(msg);
}
while (dbus_connection_dispatch(m_dbus) == DBUS_DISPATCH_DATA_REMAINS) {}
}
#endif
}
@ -513,7 +529,15 @@ public:
std::shared_ptr<IWindow> newWindow = _WindowXlibNew(title, m_xDisp, nullptr, m_xDefaultScreen, m_xIM, m_bestStyle,
m_fontset, m_lastGlxCtx, nullptr, &m_glContext);
#endif
m_windows[(Window)newWindow->getPlatformHandle()] = newWindow;
Window wid = (Window)newWindow->getPlatformHandle();
m_windows[wid] = newWindow;
XEvent reply = {};
reply.xclient.type = ClientMessage;
reply.xclient.window = wid;
reply.xclient.message_type = XA_INTEGER;
reply.xclient.format = 32;
reply.xclient.data.l[0] = 'NWID';
XSendEvent(m_xDisp, wid, false, 0, &reply);
XUnlockDisplay(m_xDisp);
return newWindow;
}

View File

@ -397,7 +397,7 @@ public:
s_glxError = false;
XErrorHandler oldHandler = XSetErrorHandler(ctxErrorHandler);
for (m_attribIdx = 0; m_attribIdx < std::extent<decltype(ContextAttribList)>::value; ++m_attribIdx) {
for (m_attribIdx = 0; m_attribIdx < int(std::extent_v<decltype(ContextAttribList)>); ++m_attribIdx) {
m_glxCtx = glXCreateContextAttribsARB(m_xDisp, m_fbconfig, m_lastCtx, true, ContextAttribList[m_attribIdx]);
if (m_glxCtx)
break;
@ -605,7 +605,7 @@ public:
* supported format will be returned. */
if (formatCount >= 1) {
if (m_ctx->m_deepColor) {
for (int i = 0; i < formatCount; ++i) {
for (uint32_t i = 0; i < formatCount; ++i) {
if (surfFormats[i].format == VK_FORMAT_R16G16B16A16_UNORM) {
m_format = surfFormats[i].format;
m_colorspace = surfFormats[i].colorSpace;
@ -614,7 +614,7 @@ public:
}
}
if (m_format == VK_FORMAT_UNDEFINED) {
for (int i = 0; i < formatCount; ++i) {
for (uint32_t i = 0; i < formatCount; ++i) {
if (surfFormats[i].format == VK_FORMAT_B8G8R8A8_UNORM || surfFormats[i].format == VK_FORMAT_R8G8B8A8_UNORM) {
m_format = surfFormats[i].format;
m_colorspace = surfFormats[i].colorSpace;
@ -1041,7 +1041,7 @@ public:
&actualFormat, &nitems, &bytes, (unsigned char**)&vals);
XUnlockDisplay(m_xDisp);
if (ret == Success) {
for (int i = 0; i < nitems; ++i) {
for (unsigned long i = 0; i < nitems; ++i) {
if (vals[i] == S_ATOMS->m_netwmStateFullscreen) {
fullscreen = true;
break;
@ -1422,11 +1422,12 @@ public:
return false;
}
case ClientMessage: {
if (event->xclient.data.l[0] == S_ATOMS->m_wmDeleteWindow && m_callback) {
if (Atom(event->xclient.data.l[0]) == S_ATOMS->m_wmDeleteWindow && m_callback) {
m_callback->destroyed();
m_callback = nullptr;
return true;
}
return true;
return false;
}
case Expose: {
Window nw = 0;

@ -1 +1 @@
Subproject commit a2ffe70b4e1fa54d7013f327b45970e18e08901a
Subproject commit a0ef17d895ba655ade171f76a984663639a1d390

View File

@ -1,5 +1,5 @@
add_executable(booTest WIN32 main.cpp)
target_link_libraries(booTest boo logvisor xxhash ${BOO_SYS_LIBS})
target_link_libraries(booTest boo)
if (COMMAND add_nro_target)
set_target_properties(booTest PROPERTIES SUFFIX ".elf")