more full window object
Some checks failed
Build and Deploy / build-windows (CLANG64) (push) Waiting to run
Build and Deploy / package-dist (push) Blocked by required conditions
Build and Deploy / deploy-itch (push) Blocked by required conditions
Build and Deploy / deploy-gitea (push) Blocked by required conditions
Build and Deploy / build-macos (push) Failing after 5s
Build and Deploy / build-linux (push) Failing after 1m27s

This commit is contained in:
2025-05-25 21:55:21 -05:00
parent aac0c3813b
commit 7b70def11f

View File

@@ -145,174 +145,103 @@ static JSValue js_window_constructor(JSContext *js, JSValueConst new_target, int
}
JS_FreeValue(js, height_val);
// Create SDL properties object
SDL_PropertiesID props = SDL_CreateProperties();
// Always set basic properties
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height);
SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, title);
// Handle window position
int x = SDL_WINDOWPOS_UNDEFINED;
JSValue x_val = JS_GetPropertyStr(js, opts, "x");
if (!JS_IsUndefined(x_val)) {
if (JS_IsString(x_val)) {
const char *pos = JS_ToCString(js, x_val);
if (strcmp(pos, "centered") == 0) x = SDL_WINDOWPOS_CENTERED;
if (strcmp(pos, "centered") == 0)
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, SDL_WINDOWPOS_CENTERED);
else
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, SDL_WINDOWPOS_UNDEFINED);
JS_FreeCString(js, pos);
} else {
x = js2number(js, x_val);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, js2number(js, x_val));
}
}
JS_FreeValue(js, x_val);
int y = SDL_WINDOWPOS_UNDEFINED;
JSValue y_val = JS_GetPropertyStr(js, opts, "y");
if (!JS_IsUndefined(y_val)) {
if (JS_IsString(y_val)) {
const char *pos = JS_ToCString(js, y_val);
if (strcmp(pos, "centered") == 0) y = SDL_WINDOWPOS_CENTERED;
if (strcmp(pos, "centered") == 0)
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, SDL_WINDOWPOS_CENTERED);
else
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, SDL_WINDOWPOS_UNDEFINED);
JS_FreeCString(js, pos);
} else {
y = js2number(js, y_val);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, js2number(js, y_val));
}
}
JS_FreeValue(js, y_val);
// Build window flags
Uint64 flags = 0;
// Helper function to check and set boolean properties
#define SET_BOOL_PROP(js_name, sdl_prop) do { \
JSValue val = JS_GetPropertyStr(js, opts, js_name); \
if (!JS_IsUndefined(val)) { \
SDL_SetBooleanProperty(props, sdl_prop, JS_ToBool(js, val)); \
} \
JS_FreeValue(js, val); \
} while(0)
// Check boolean properties
JSValue resizable = JS_GetPropertyStr(js, opts, "resizable");
if (JS_ToBool(js, resizable)) flags |= SDL_WINDOW_RESIZABLE;
JS_FreeValue(js, resizable);
// Set all boolean properties directly on the SDL properties object
SET_BOOL_PROP("resizable", SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN);
SET_BOOL_PROP("fullscreen", SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN);
SET_BOOL_PROP("hidden", SDL_PROP_WINDOW_CREATE_HIDDEN_BOOLEAN);
SET_BOOL_PROP("borderless", SDL_PROP_WINDOW_CREATE_BORDERLESS_BOOLEAN);
SET_BOOL_PROP("alwaysOnTop", SDL_PROP_WINDOW_CREATE_ALWAYS_ON_TOP_BOOLEAN);
SET_BOOL_PROP("minimized", SDL_PROP_WINDOW_CREATE_MINIMIZED_BOOLEAN);
SET_BOOL_PROP("maximized", SDL_PROP_WINDOW_CREATE_MAXIMIZED_BOOLEAN);
SET_BOOL_PROP("mouseGrabbed", SDL_PROP_WINDOW_CREATE_MOUSE_GRABBED_BOOLEAN);
SET_BOOL_PROP("highPixelDensity", SDL_PROP_WINDOW_CREATE_HIGH_PIXEL_DENSITY_BOOLEAN);
SET_BOOL_PROP("transparent", SDL_PROP_WINDOW_CREATE_TRANSPARENT_BOOLEAN);
SET_BOOL_PROP("utility", SDL_PROP_WINDOW_CREATE_UTILITY_BOOLEAN);
SET_BOOL_PROP("tooltip", SDL_PROP_WINDOW_CREATE_TOOLTIP_BOOLEAN);
SET_BOOL_PROP("popupMenu", SDL_PROP_WINDOW_CREATE_MENU_BOOLEAN);
SET_BOOL_PROP("opengl", SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN);
SET_BOOL_PROP("vulkan", SDL_PROP_WINDOW_CREATE_VULKAN_BOOLEAN);
SET_BOOL_PROP("metal", SDL_PROP_WINDOW_CREATE_METAL_BOOLEAN);
SET_BOOL_PROP("modal", SDL_PROP_WINDOW_CREATE_MODAL_BOOLEAN);
SET_BOOL_PROP("externalGraphicsContext", SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN);
JSValue fullscreen = JS_GetPropertyStr(js, opts, "fullscreen");
if (JS_ToBool(js, fullscreen)) flags |= SDL_WINDOW_FULLSCREEN;
JS_FreeValue(js, fullscreen);
JSValue hidden = JS_GetPropertyStr(js, opts, "hidden");
if (JS_ToBool(js, hidden)) flags |= SDL_WINDOW_HIDDEN;
JS_FreeValue(js, hidden);
JSValue borderless = JS_GetPropertyStr(js, opts, "borderless");
if (JS_ToBool(js, borderless)) flags |= SDL_WINDOW_BORDERLESS;
JS_FreeValue(js, borderless);
JSValue always_on_top = JS_GetPropertyStr(js, opts, "alwaysOnTop");
if (JS_ToBool(js, always_on_top)) flags |= SDL_WINDOW_ALWAYS_ON_TOP;
JS_FreeValue(js, always_on_top);
JSValue minimized = JS_GetPropertyStr(js, opts, "minimized");
if (JS_ToBool(js, minimized)) flags |= SDL_WINDOW_MINIMIZED;
JS_FreeValue(js, minimized);
JSValue maximized = JS_GetPropertyStr(js, opts, "maximized");
if (JS_ToBool(js, maximized)) flags |= SDL_WINDOW_MAXIMIZED;
JS_FreeValue(js, maximized);
JSValue mouse_grabbed = JS_GetPropertyStr(js, opts, "mouseGrabbed");
if (JS_ToBool(js, mouse_grabbed)) flags |= SDL_WINDOW_MOUSE_GRABBED;
JS_FreeValue(js, mouse_grabbed);
JSValue keyboard_grabbed = JS_GetPropertyStr(js, opts, "keyboardGrabbed");
if (JS_ToBool(js, keyboard_grabbed)) flags |= SDL_WINDOW_KEYBOARD_GRABBED;
JS_FreeValue(js, keyboard_grabbed);
JSValue high_pixel_density = JS_GetPropertyStr(js, opts, "highPixelDensity");
if (JS_ToBool(js, high_pixel_density)) flags |= SDL_WINDOW_HIGH_PIXEL_DENSITY;
JS_FreeValue(js, high_pixel_density);
JSValue transparent = JS_GetPropertyStr(js, opts, "transparent");
if (JS_ToBool(js, transparent)) flags |= SDL_WINDOW_TRANSPARENT;
JS_FreeValue(js, transparent);
JSValue not_focusable = JS_GetPropertyStr(js, opts, "notFocusable");
if (JS_ToBool(js, not_focusable)) flags |= SDL_WINDOW_NOT_FOCUSABLE;
JS_FreeValue(js, not_focusable);
// Special window types
JSValue utility = JS_GetPropertyStr(js, opts, "utility");
if (JS_ToBool(js, utility)) flags |= SDL_WINDOW_UTILITY;
JS_FreeValue(js, utility);
JSValue tooltip = JS_GetPropertyStr(js, opts, "tooltip");
if (JS_ToBool(js, tooltip)) flags |= SDL_WINDOW_TOOLTIP;
JS_FreeValue(js, tooltip);
JSValue popup_menu = JS_GetPropertyStr(js, opts, "popupMenu");
if (JS_ToBool(js, popup_menu)) flags |= SDL_WINDOW_POPUP_MENU;
JS_FreeValue(js, popup_menu);
// Graphics API flags
JSValue opengl = JS_GetPropertyStr(js, opts, "opengl");
if (JS_ToBool(js, opengl)) flags |= SDL_WINDOW_OPENGL;
JS_FreeValue(js, opengl);
JSValue vulkan = JS_GetPropertyStr(js, opts, "vulkan");
if (JS_ToBool(js, vulkan)) flags |= SDL_WINDOW_VULKAN;
JS_FreeValue(js, vulkan);
JSValue metal = JS_GetPropertyStr(js, opts, "metal");
if (JS_ToBool(js, metal)) flags |= SDL_WINDOW_METAL;
JS_FreeValue(js, metal);
// Handle parent window for tooltips, popups, etc
SDL_Window *parent = NULL;
JSValue parent_val = JS_GetPropertyStr(js, opts, "parent");
if (!JS_IsUndefined(parent_val)) {
parent = js2SDL_Window(js, parent_val);
// Handle focusable (inverse logic)
JSValue focusable_val = JS_GetPropertyStr(js, opts, "focusable");
if (!JS_IsUndefined(focusable_val)) {
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FOCUSABLE_BOOLEAN, JS_ToBool(js, focusable_val));
}
JS_FreeValue(js, parent_val);
JS_FreeValue(js, focusable_val);
// Create window with properties if we need special handling
SDL_Window *window = NULL;
// Handle notFocusable (for backwards compatibility)
JSValue not_focusable_val = JS_GetPropertyStr(js, opts, "notFocusable");
if (!JS_IsUndefined(not_focusable_val)) {
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FOCUSABLE_BOOLEAN, !JS_ToBool(js, not_focusable_val));
}
JS_FreeValue(js, not_focusable_val);
if (parent || (flags & (SDL_WINDOW_TOOLTIP | SDL_WINDOW_POPUP_MENU))) {
// Use SDL_CreateWindowWithProperties for advanced features
SDL_PropertiesID props = SDL_CreateProperties();
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, width);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, height);
SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, title);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_X_NUMBER, x);
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_Y_NUMBER, y);
// Set boolean properties
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_RESIZABLE_BOOLEAN, flags & SDL_WINDOW_RESIZABLE);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN, flags & SDL_WINDOW_FULLSCREEN);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_HIDDEN_BOOLEAN, flags & SDL_WINDOW_HIDDEN);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_BORDERLESS_BOOLEAN, flags & SDL_WINDOW_BORDERLESS);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_ALWAYS_ON_TOP_BOOLEAN, flags & SDL_WINDOW_ALWAYS_ON_TOP);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_MINIMIZED_BOOLEAN, flags & SDL_WINDOW_MINIMIZED);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_MAXIMIZED_BOOLEAN, flags & SDL_WINDOW_MAXIMIZED);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_MOUSE_GRABBED_BOOLEAN, flags & SDL_WINDOW_MOUSE_GRABBED);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_TRANSPARENT_BOOLEAN, flags & SDL_WINDOW_TRANSPARENT);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FOCUSABLE_BOOLEAN, !(flags & SDL_WINDOW_NOT_FOCUSABLE));
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_UTILITY_BOOLEAN, flags & SDL_WINDOW_UTILITY);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_TOOLTIP_BOOLEAN, flags & SDL_WINDOW_TOOLTIP);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_MENU_BOOLEAN, flags & SDL_WINDOW_POPUP_MENU);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN, flags & SDL_WINDOW_OPENGL);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_VULKAN_BOOLEAN, flags & SDL_WINDOW_VULKAN);
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_METAL_BOOLEAN, flags & SDL_WINDOW_METAL);
#undef SET_BOOL_PROP
// Handle parent window
JSValue parent_val = JS_GetPropertyStr(js, opts, "parent");
if (!JS_IsUndefined(parent_val) && !JS_IsNull(parent_val)) {
SDL_Window *parent = js2SDL_Window(js, parent_val);
if (parent) {
SDL_SetPointerProperty(props, SDL_PROP_WINDOW_CREATE_PARENT_POINTER, parent);
}
// Handle modal property
JSValue modal = JS_GetPropertyStr(js, opts, "modal");
if (JS_ToBool(js, modal) && parent) {
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_MODAL_BOOLEAN, 1);
}
JS_FreeValue(js, modal);
// Handle external graphics context
JSValue external_graphics = JS_GetPropertyStr(js, opts, "externalGraphicsContext");
if (JS_ToBool(js, external_graphics)) {
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_EXTERNAL_GRAPHICS_CONTEXT_BOOLEAN, 1);
}
JS_FreeValue(js, external_graphics);
window = SDL_CreateWindowWithProperties(props);
SDL_DestroyProperties(props);
} else {
// Use simpler API for basic windows
window = SDL_CreateWindow(title, width, height, flags);
}
JS_FreeValue(js, parent_val);
// Create window with properties
SDL_Window *window = SDL_CreateWindowWithProperties(props);
SDL_DestroyProperties(props);
// Always free the title string since we allocated it
if (title) {
@@ -323,13 +252,31 @@ static JSValue js_window_constructor(JSContext *js, JSValueConst new_target, int
return JS_ThrowReferenceError(js, "Failed to create window: %s", SDL_GetError());
}
// Create the window JS object
JSValue window_obj = SDL_Window2js(js, window);
// Set additional properties that can't be set during creation
// These will be applied through the property setters
JSValue opacity_val = JS_GetPropertyStr(js, opts, "opacity");
if (!JS_IsUndefined(opacity_val)) {
float opacity = js2number(js, opacity_val);
SDL_SetWindowOpacity(window, opacity);
JS_SetPropertyStr(js, window_obj, "opacity", opacity_val);
}
JSValue min_size_val = JS_GetPropertyStr(js, opts, "minimumSize");
if (!JS_IsUndefined(min_size_val)) {
JS_SetPropertyStr(js, window_obj, "minimumSize", min_size_val);
}
JSValue max_size_val = JS_GetPropertyStr(js, opts, "maximumSize");
if (!JS_IsUndefined(max_size_val)) {
JS_SetPropertyStr(js, window_obj, "maximumSize", max_size_val);
}
JSValue pos_val = JS_GetPropertyStr(js, opts, "position");
if (!JS_IsUndefined(pos_val)) {
JS_SetPropertyStr(js, window_obj, "position", pos_val);
}
JS_FreeValue(js, opacity_val);
// Handle text input
JSValue text_input = JS_GetPropertyStr(js, opts, "textInput");
@@ -338,7 +285,7 @@ static JSValue js_window_constructor(JSContext *js, JSValueConst new_target, int
}
JS_FreeValue(js, text_input);
return SDL_Window2js(js, window);
return window_obj;
}
// Window functions
@@ -425,10 +372,335 @@ JSValue js_window_set_icon(JSContext *js, JSValue self, int argc, JSValue *argv)
return JS_UNDEFINED;
}
JSValue js_window_mouse_grab(JSContext *js, JSValue self, int argc, JSValue *argv)
// Position getter/setter
JSValue js_window_get_position(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_SetWindowMouseGrab(w, JS_ToBool(js,argv[0]));
int x, y;
SDL_GetWindowPosition(w, &x, &y);
return vec22js(js, (HMM_Vec2){x,y});
}
JSValue js_window_set_position(JSContext *js, JSValue self, JSValue val)
{
SDL_Window *w = js2SDL_Window(js,self);
HMM_Vec2 pos = js2vec2(js,val);
SDL_SetWindowPosition(w,pos.x,pos.y);
return JS_UNDEFINED;
}
// Mouse grab getter/setter
JSValue js_window_get_mouseGrab(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
return JS_NewBool(js, SDL_GetWindowMouseGrab(w));
}
JSValue js_window_set_mouseGrab(JSContext *js, JSValue self, JSValue val)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_SetWindowMouseGrab(w, JS_ToBool(js,val));
return JS_UNDEFINED;
}
// Keyboard grab getter/setter
JSValue js_window_get_keyboardGrab(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
return JS_NewBool(js, SDL_GetWindowKeyboardGrab(w));
}
JSValue js_window_set_keyboardGrab(JSContext *js, JSValue self, JSValue val)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_SetWindowKeyboardGrab(w, JS_ToBool(js,val));
return JS_UNDEFINED;
}
// Opacity getter/setter
JSValue js_window_get_opacity(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
return number2js(js, SDL_GetWindowOpacity(w));
}
JSValue js_window_set_opacity(JSContext *js, JSValue self, JSValue val)
{
SDL_Window *w = js2SDL_Window(js,self);
float opacity = js2number(js,val);
SDL_SetWindowOpacity(w, opacity);
return JS_UNDEFINED;
}
// Minimum size getter/setter
JSValue js_window_get_minimumSize(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
int width, height;
SDL_GetWindowMinimumSize(w, &width, &height);
return vec22js(js, (HMM_Vec2){width,height});
}
JSValue js_window_set_minimumSize(JSContext *js, JSValue self, JSValue val)
{
SDL_Window *w = js2SDL_Window(js,self);
HMM_Vec2 size = js2vec2(js,val);
SDL_SetWindowMinimumSize(w,size.x,size.y);
return JS_UNDEFINED;
}
// Maximum size getter/setter
JSValue js_window_get_maximumSize(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
int width, height;
SDL_GetWindowMaximumSize(w, &width, &height);
return vec22js(js, (HMM_Vec2){width,height});
}
JSValue js_window_set_maximumSize(JSContext *js, JSValue self, JSValue val)
{
SDL_Window *w = js2SDL_Window(js,self);
HMM_Vec2 size = js2vec2(js,val);
SDL_SetWindowMaximumSize(w,size.x,size.y);
return JS_UNDEFINED;
}
// Resizable setter (read from flags)
JSValue js_window_get_resizable(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_WindowFlags flags = SDL_GetWindowFlags(w);
return JS_NewBool(js, flags & SDL_WINDOW_RESIZABLE);
}
JSValue js_window_set_resizable(JSContext *js, JSValue self, JSValue val)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_SetWindowResizable(w, JS_ToBool(js,val));
return JS_UNDEFINED;
}
// Bordered getter/setter
JSValue js_window_get_bordered(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_WindowFlags flags = SDL_GetWindowFlags(w);
return JS_NewBool(js, !(flags & SDL_WINDOW_BORDERLESS));
}
JSValue js_window_set_bordered(JSContext *js, JSValue self, JSValue val)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_SetWindowBordered(w, JS_ToBool(js,val));
return JS_UNDEFINED;
}
// Always on top getter/setter
JSValue js_window_get_alwaysOnTop(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_WindowFlags flags = SDL_GetWindowFlags(w);
return JS_NewBool(js, flags & SDL_WINDOW_ALWAYS_ON_TOP);
}
JSValue js_window_set_alwaysOnTop(JSContext *js, JSValue self, JSValue val)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_SetWindowAlwaysOnTop(w, JS_ToBool(js,val));
return JS_UNDEFINED;
}
// Fullscreen getter/setter
JSValue js_window_get_fullscreen(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_WindowFlags flags = SDL_GetWindowFlags(w);
return JS_NewBool(js, flags & SDL_WINDOW_FULLSCREEN);
}
JSValue js_window_set_fullscreen(JSContext *js, JSValue self, JSValue val)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_SetWindowFullscreen(w, JS_ToBool(js,val));
return JS_UNDEFINED;
}
// Focusable setter
JSValue js_window_get_focusable(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_WindowFlags flags = SDL_GetWindowFlags(w);
return JS_NewBool(js, !(flags & SDL_WINDOW_NOT_FOCUSABLE));
}
JSValue js_window_set_focusable(JSContext *js, JSValue self, JSValue val)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_SetWindowFocusable(w, JS_ToBool(js,val));
return JS_UNDEFINED;
}
// Modal setter
JSValue js_window_get_modal(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_WindowFlags flags = SDL_GetWindowFlags(w);
return JS_NewBool(js, flags & SDL_WINDOW_MODAL);
}
JSValue js_window_set_modal(JSContext *js, JSValue self, JSValue val)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_SetWindowModal(w, JS_ToBool(js,val));
return JS_UNDEFINED;
}
// Hidden/visible state
JSValue js_window_get_visible(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_WindowFlags flags = SDL_GetWindowFlags(w);
return JS_NewBool(js, !(flags & SDL_WINDOW_HIDDEN));
}
JSValue js_window_set_visible(JSContext *js, JSValue self, JSValue val)
{
SDL_Window *w = js2SDL_Window(js,self);
if (JS_ToBool(js,val))
SDL_ShowWindow(w);
else
SDL_HideWindow(w);
return JS_UNDEFINED;
}
// Minimized state
JSValue js_window_get_minimized(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_WindowFlags flags = SDL_GetWindowFlags(w);
return JS_NewBool(js, flags & SDL_WINDOW_MINIMIZED);
}
JSValue js_window_set_minimized(JSContext *js, JSValue self, JSValue val)
{
SDL_Window *w = js2SDL_Window(js,self);
if (JS_ToBool(js,val))
SDL_MinimizeWindow(w);
else
SDL_RestoreWindow(w);
return JS_UNDEFINED;
}
// Maximized state
JSValue js_window_get_maximized(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_WindowFlags flags = SDL_GetWindowFlags(w);
return JS_NewBool(js, flags & SDL_WINDOW_MAXIMIZED);
}
JSValue js_window_set_maximized(JSContext *js, JSValue self, JSValue val)
{
SDL_Window *w = js2SDL_Window(js,self);
if (JS_ToBool(js,val))
SDL_MaximizeWindow(w);
else
SDL_RestoreWindow(w);
return JS_UNDEFINED;
}
// Other window methods
JSValue js_window_raise(JSContext *js, JSValue self, int argc, JSValue *argv)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_RaiseWindow(w);
return JS_UNDEFINED;
}
JSValue js_window_restore(JSContext *js, JSValue self, int argc, JSValue *argv)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_RestoreWindow(w);
return JS_UNDEFINED;
}
JSValue js_window_flash(JSContext *js, JSValue self, int argc, JSValue *argv)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_FlashOperation op = SDL_FLASH_BRIEFLY;
if (argc > 0 && JS_IsString(argv[0])) {
const char *operation = JS_ToCString(js,argv[0]);
if (strcmp(operation, "cancel") == 0) op = SDL_FLASH_CANCEL;
else if (strcmp(operation, "briefly") == 0) op = SDL_FLASH_BRIEFLY;
else if (strcmp(operation, "until_focused") == 0) op = SDL_FLASH_UNTIL_FOCUSED;
JS_FreeCString(js,operation);
}
SDL_FlashWindow(w, op);
return JS_UNDEFINED;
}
JSValue js_window_destroy(JSContext *js, JSValue self, int argc, JSValue *argv)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_DestroyWindow(w);
return JS_UNDEFINED;
}
JSValue js_window_get_id(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
return number2js(js, SDL_GetWindowID(w));
}
JSValue js_window_get_parent(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_Window *parent = SDL_GetWindowParent(w);
if (!parent) return JS_NULL;
return SDL_Window2js(js, parent);
}
JSValue js_window_set_parent(JSContext *js, JSValue self, JSValue val)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_Window *parent = NULL;
if (!JS_IsNull(val) && !JS_IsUndefined(val))
parent = js2SDL_Window(js,val);
SDL_SetWindowParent(w, parent);
return JS_UNDEFINED;
}
JSValue js_window_get_pixelDensity(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
return number2js(js, SDL_GetWindowPixelDensity(w));
}
JSValue js_window_get_displayScale(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
return number2js(js, SDL_GetWindowDisplayScale(w));
}
JSValue js_window_get_sizeInPixels(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
int width, height;
SDL_GetWindowSizeInPixels(w, &width, &height);
return vec22js(js, (HMM_Vec2){width,height});
}
JSValue js_window_get_flags(JSContext *js, JSValue self)
{
SDL_Window *w = js2SDL_Window(js,self);
return number2js(js, SDL_GetWindowFlags(w));
}
JSValue js_window_sync(JSContext *js, JSValue self, int argc, JSValue *argv)
{
SDL_Window *w = js2SDL_Window(js,self);
SDL_SyncWindow(w);
return JS_UNDEFINED;
}
@@ -438,11 +710,35 @@ static const JSCFunctionListEntry js_SDL_Window_funcs[] = {
MIST_FUNC_DEF(SDL_Window, keyboard_shown, 0),
MIST_FUNC_DEF(window, theme, 0),
MIST_FUNC_DEF(window, safe_area, 0),
MIST_FUNC_DEF(window, bordered, 1),
MIST_FUNC_DEF(window, set_icon, 1),
MIST_FUNC_DEF(window, raise, 0),
MIST_FUNC_DEF(window, restore, 0),
MIST_FUNC_DEF(window, flash, 1),
MIST_FUNC_DEF(window, destroy, 0),
MIST_FUNC_DEF(window, sync, 0),
CGETSET_ADD(window, title),
CGETSET_ADD(window, size),
MIST_FUNC_DEF(window, mouse_grab, 1),
CGETSET_ADD(window, position),
CGETSET_ADD(window, mouseGrab),
CGETSET_ADD(window, keyboardGrab),
CGETSET_ADD(window, opacity),
CGETSET_ADD(window, minimumSize),
CGETSET_ADD(window, maximumSize),
CGETSET_ADD(window, resizable),
CGETSET_ADD(window, bordered),
CGETSET_ADD(window, alwaysOnTop),
CGETSET_ADD(window, fullscreen),
CGETSET_ADD(window, focusable),
CGETSET_ADD(window, modal),
CGETSET_ADD(window, visible),
CGETSET_ADD(window, minimized),
CGETSET_ADD(window, maximized),
CGETSET_ADD(window, parent),
JS_CGETSET_DEF("id", js_window_get_id, NULL),
JS_CGETSET_DEF("pixelDensity", js_window_get_pixelDensity, NULL),
JS_CGETSET_DEF("displayScale", js_window_get_displayScale, NULL),
JS_CGETSET_DEF("sizeInPixels", js_window_get_sizeInPixels, NULL),
JS_CGETSET_DEF("flags", js_window_get_flags, NULL),
};
// Renderer functions