A Defold extension for advanced window features on Windows.
- Custom window shapes and colors
- Window transparency
- Lock aspect ratio for resize
- Hook for custom function of close button
- Flashing of the taskbar button
- Progress bar
- Dark mode
- Right-to-left window
- Drag window
This asset can be added as a library dependency in your project.
Add this link to your dependencies: https://github.com/HalfstarDev/DefWin/archive/master.zip
This extension works only on Windows, with some features only working on Windows 11. On other systems defwin will be nil, so you can safely handle multiplatform releases like this:
if defwin then
defwin.set_alpha_color()
endSet which color should be rendered transparent by the window, and removes the window border. The transparent areas will also be click-through.
You can either use the clear color of your project by calling it without arguments, or use manual RGB colors in [0.0, 1.0].
So while simply calling
defwin.set_alpha_color()on init once would make the shape of the window to that of what you rendered over the clear color, that would also remove all pixels that you rendered that happen to be the clear color. To prevent that from happening, use the safealpha render script, that will make sure that your game never renders the clear color after clear.
Set the transparency of the whole window, including the border. Can't be used together with set_alpha_color.
number alpha: Opacity in [0.0, 1.0]. 0.0 = fully transparent, 1.0 = fully opaque.
defwin.set_alpha(0.8)Remove the window transparency, restoring the original opaque window.
defwin.reset_alpha()Set a listener that is called instead of quitting the game when the close button is pressed.
function listener: Called when a close is requested. Pass nil to clear the listener and restore default close behaviour.
defwin.set_close_listener(function(self)
if ask_before_quit then
show_close_popup()
else
defwin.quit()
end
end)Set the time after a close request until the game exits automatically.
number delay: Time in seconds before the game exits. 0 closes as soon as the close button is pressed. Pass nil for no automatic close, leaving the close listener fully in control.
defwin.set_close_delay(2)If enabled and a close delay is set, the master sound group gain is faded out over the delay duration until shutdown.
defwin.set_close_sound_fadeout(true)Quit the game, respecting the configured close delay and sound fade-out settings, but ignoring the close listener.
defwin.set_close_listener(function(self)
if ask_before_quit then
show_close_popup()
else
defwin.quit()
end
end)Request to quit the game, behaving as if the user pressed the close button or Alt+F4. Triggers the close listener and delay handling.
if gui.pick_node(gui.get_node("my_close_button"), x, y) then
defwin.request_quit()
endCancel an in-progress close attempt. Until this is called again on a future close, further attempts to close the window will not re-trigger the listener or restart the delay.
defwin.cancel_close()Set the window style to dark mode on true, and to light mode on false.
Get the preference for dark mode of the current user. You can use it to apply dark mode to the window, or to use a dark theme by default in your game.
return:
trueif dark mode is preferredfalseif light mode is preferrednilif the preference is unknown
local preference = defwin.get_dark_mode_preference()
if preference ~= nil then
defwin.set_dark_mode(preference)
endSet the corner style of the window frame to rounded, if available.
defwin.set_corners_rounded()Set the corner style of the window frame to slightly rounded, if available.
defwin.set_corners_rounded_small()Set the corner style of the window frame to not rounded.
defwin.set_corners_not_rounded()Set the corner style of the window frame to the default.
defwin.set_corners_default()Set window border color, with RGB in [0.0, 1.0].
defwin.set_border_color(nil) for default color.
defwin.set_border_color(1.0, 0.0, 0.0)Set the window border color to be transparent.
defwin.set_border_color_none()Set window caption color, with RGB in [0.0, 1.0].
defwin.set_caption_color(nil) for default color.
defwin.set_caption_color(0.0, 1.0, 1.0)Set window caption text color, with RGB in [0.0, 1.0].
defwin.set_caption_text_color(nil) for default color.
defwin.set_caption_text_color(1.0, 0.0, 0.0)Get the opaque color of the window caption.
return: vmath.vector4 color = vmath.vector4(r, g, b, 1) with r, g, b in [0.0, 1.0]
local color = defwin.get_caption_color()
gui.set_color(gui.get_node("window"), color)Set window bar layout to right-to-left, affecting buttons, title, and icon
if language == "arabic" then
defwin.set_rtl_layout(true)
else
defwin.set_rtl_layout(false)
endTurns the window into a tool window, or turn it back into a normal window. Tool windows are not shown on taskbar and Alt-Tab, and have no minimize and maximize buttons or icon.
defwin.set_tool_window(true)Lock the aspect ratio of the window when the user drags its border.
number ratio: The aspect ratio to lock (width / height). If omitted, the aspect ratio of the default resolution in game.project is used.
defwin.lock_ratio()Remove the aspect ratio lock set by lock_ratio.
defwin.unlock_ratio()Set the minimum size a window is allowed to have when resized.
defwin.set_minimum_window_size(192, 128)Fit the window to the given aspect ratio by resizing only the height.
number ratio: The aspect ratio to fit to (width / height). If omitted, the aspect ratio from the display size ingame.projectis used.
defwin.fit_vertical()Like defwin.fit_vertical, but only resizing width.
defwin.fit_horizontal()Uses defwin.fit_vertical or defwin.fit_horizontal, depending on which increases the window size.
defwin.fit_grow()Uses defwin.fit_vertical or defwin.fit_horizontal, depending on which decreases the window size.
defwin.fit_shrink()Reposition and resize the window so that no part of it is outside of the screen.
defwin.fit_screen()Flash the window a limited number of times.
bool taskbar: Should the taskbar button flashbool caption: Should the window caption flashnumber count: How many times to flash (default 1)number timeout: Time between flashes, in seconds (default platform cursor blink rate)
defwin.flash(true, true, 3)Start flashing the window until manually stopped or until the window regains focus.
bool taskbar: Should the taskbar button flashbool caption: Should the window caption flashbool until_focused: Iftrue, focusing the window stops the flash. Iffalse, it flashes untilstop_flash()is called.number timeout: Time between flashes, in seconds (default platform cursor blink rate)
defwin.start_flash(true, false)Stop the flashing of the window. As the current flash will still be completed, it can take a few seconds to disappear.
defwin.stop_flash()Set the progress bar on the taskbar button.
number value: progress in [0.0, 1.0]
defwin.set_progress(downloaded/total)Set the progress bar on the taskbar button to an error state, turning it red.
defwin.set_progress_error()Set the progress bar on the taskbar button to an indeterminate loading state.
defwin.set_progress_load()Pauses the progress bar on the taskbar button, turning it yellow until a new value or state is set.
defwin.pause_progress()Hide the progress bar on the taskbar button, until a new value or state is set.
defwin.hide_progress()Start dragging the window along the cursor. Must be paired with repeated calls to update_drag() to have any effect.
Update one frame of the window drag started with start_drag(). Should be called every frame (e.g. from an on_input or update callback) while dragging is active.
Stop dragging the window along the cursor.
function on_input(self, action_id, action)
if action_id == hash("touch") then
if action.pressed and gui.pick_node(gui.get_node("drag"), action.x, action.y) then
defwin.start_drag()
end
defwin.update_drag()
if action.released then
defwin.stop_drag()
end
end
endKeep the window active to prevent the system from going to sleep while enabled.
-- On start of cutscene:
defwin.prevent_sleep(true)
-- On end of cutscene:
defwin.prevent_sleep(false)The safealpha render script will make sure that you don't accidently render the clear color above the original clear, by shifting matching fragments just far enough to not set the window transparent.
To use it, add safealpha.go to your root collection, and set the render file in game.project to /defwin/safealpha/render/safealpha.render, or integrate it into your own render pipeline.
You can set some of the setting to be applied automatically in game.project:
[defwin]
lock_aspect_ratio = 0 | 1
use_dark_mode_preference = 0 | 1
set_clear_transparent = 0 | 1
rtl_layout = 0 | 1
disable_border = 0 | 1
minimum_width = 0+
minimum_height = 0+
rounded_corners = DEFAULT | ROUND | ROUNDSMALL | DONOTROUND
