glfw: add Window.setFocusCallback

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
Stephen Gutekanst 2021-10-18 00:33:28 -07:00 committed by Stephen Gutekanst
parent 692ce9d6c0
commit 0297426f3b

View file

@ -40,6 +40,7 @@ pub const InternalUserPointer = struct {
setSizeCallback: ?fn (window: Window, width: isize, height: isize) void, setSizeCallback: ?fn (window: Window, width: isize, height: isize) void,
setCloseCallback: ?fn (window: Window) void, setCloseCallback: ?fn (window: Window) void,
setRefreshCallback: ?fn (window: Window) void, setRefreshCallback: ?fn (window: Window) void,
setFocusCallback: ?fn (window: Window, focused: bool) void,
}; };
/// Resets all window hints to their default values. /// Resets all window hints to their default values.
@ -1102,8 +1103,6 @@ fn setRefreshCallbackWrapper(handle: ?*c.GLFWwindow) callconv(.C) void {
// /// @param[in] window The window whose callback to set. // /// @param[in] window The window whose callback to set.
// /// @param[in] callback The new callback, or null to remove the currently set // /// @param[in] callback The new callback, or null to remove the currently set
// /// callback. // /// callback.
// /// @return The previously set callback, or null if no callback was set or the
// /// library had not been [initialized](@ref intro_init).
// /// // ///
// /// @callback_param `window` the window whose content needs to be refreshed. // /// @callback_param `window` the window whose content needs to be refreshed.
// /// // ///
@ -1113,7 +1112,7 @@ fn setRefreshCallbackWrapper(handle: ?*c.GLFWwindow) callconv(.C) void {
// GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun callback); // GLFWAPI GLFWwindowrefreshfun glfwSetWindowRefreshCallback(GLFWwindow* window, GLFWwindowrefreshfun callback);
pub inline fn setRefreshCallback(self: Window, callback: ?fn (window: Window) void) void { pub inline fn setRefreshCallback(self: Window, callback: ?fn (window: Window) void) void {
var internal = self.getInternal(); var internal = self.getInternal();
internal.setCloseCallback = callback; internal.setRefreshCallback = callback;
_ = c.glfwSetWindowRefreshCallback(self.handle, if (callback != null) setRefreshCallbackWrapper else null); _ = c.glfwSetWindowRefreshCallback(self.handle, if (callback != null) setRefreshCallbackWrapper else null);
// The only error this could return would be glfw.Error.NotInitialized, which should // The only error this could return would be glfw.Error.NotInitialized, which should
@ -1122,32 +1121,45 @@ pub inline fn setRefreshCallback(self: Window, callback: ?fn (window: Window) vo
getError() catch {}; getError() catch {};
} }
fn setFocusCallbackWrapper(handle: ?*c.GLFWwindow, focused: c_int) callconv(.C) void {
const window = from(handle.?) catch unreachable;
const internal = window.getInternal();
internal.setFocusCallback.?(window, if (focused == c.GLFW_TRUE) true else false);
}
/// Sets the focus callback for the specified window.
///
/// This function sets the focus callback of the specified window, which is
/// called when the window gains or loses input focus.
///
/// After the focus callback is called for a window that lost input focus,
/// synthetic key and mouse button release events will be generated for all such
/// that had been pressed. For more information, see @ref glfwSetKeyCallback
/// and @ref glfwSetMouseButtonCallback.
///
/// @param[in] window The window whose callback to set.
/// @param[in] callback The new callback, or null to remove the currently set
/// callback.
///
/// @callback_param `window` the window whose input focus has changed.
/// @callback_param `focused` `true` if the window was given input focus, or `false` if it lost it.
///
/// @thread_safety This function must only be called from the main thread.
///
/// see also: window_focus
pub inline fn setFocusCallback(self: Window, callback: ?fn (window: Window, focused: bool) void) void {
var internal = self.getInternal();
internal.setFocusCallback = callback;
_ = c.glfwSetWindowFocusCallback(self.handle, if (callback != null) setFocusCallbackWrapper else null);
// The only error this could return would be glfw.Error.NotInitialized, which should
// definitely have occurred before calls to this. Returning an error here makes the API
// awkward to use, so we discard it instead.
getError() catch {};
}
// TODO(window): // TODO(window):
// /// Sets the focus callback for the specified window.
// ///
// /// This function sets the focus callback of the specified window, which is
// /// called when the window gains or loses input focus.
// ///
// /// After the focus callback is called for a window that lost input focus,
// /// synthetic key and mouse button release events will be generated for all such
// /// that had been pressed. For more information, see @ref glfwSetKeyCallback
// /// and @ref glfwSetMouseButtonCallback.
// ///
// /// @param[in] window The window whose callback to set.
// /// @param[in] callback The new callback, or null to remove the currently set
// /// callback.
// /// @return The previously set callback, or null if no callback was set or the
// /// library had not been [initialized](@ref intro_init).
// ///
// /// @callback_param `window` the window whose content needs to be refreshed.
// /// @callback_param `focused` `true` if the window was given input focus, or `false` if it lost it.
// ///
// /// @thread_safety This function must only be called from the main thread.
// ///
// /// see also: window_focus
// GLFWAPI GLFWwindowfocusfun glfwSetWindowFocusCallback(GLFWwindow* window, GLFWwindowfocusfun callback);
// /// Sets the iconify callback for the specified window. // /// Sets the iconify callback for the specified window.
// /// // ///
// /// This function sets the iconification callback of the specified window, which // /// This function sets the iconification callback of the specified window, which
@ -1156,8 +1168,6 @@ pub inline fn setRefreshCallback(self: Window, callback: ?fn (window: Window) vo
// /// @param[in] window The window whose callback to set. // /// @param[in] window The window whose callback to set.
// /// @param[in] callback The new callback, or null to remove the currently set // /// @param[in] callback The new callback, or null to remove the currently set
// /// callback. // /// callback.
// /// @return The previously set callback, or null if no callback was set or the
// /// library had not been [initialized](@ref intro_init).
// /// // ///
// /// @callback_param `window` the window which was iconified or restored. // /// @callback_param `window` the window which was iconified or restored.
// /// @callback_param `focused` `true` if the window was iconified, or `false` if it was restored. // /// @callback_param `focused` `true` if the window was iconified, or `false` if it was restored.
@ -1178,8 +1188,6 @@ pub inline fn setRefreshCallback(self: Window, callback: ?fn (window: Window) vo
// /// @param[in] window The window whose callback to set. // /// @param[in] window The window whose callback to set.
// /// @param[in] callback The new callback, or null to remove the currently set // /// @param[in] callback The new callback, or null to remove the currently set
// /// callback. // /// callback.
// /// @return The previously set callback, or null if no callback was set or the
// /// library had not been [initialized](@ref intro_init).
// /// // ///
// /// @callback_param `window` the window which was maximized or restored. // /// @callback_param `window` the window which was maximized or restored.
// /// @callback_param `maximized` `true` if the window was maximized, or `false` if it was restored. // /// @callback_param `maximized` `true` if the window was maximized, or `false` if it was restored.
@ -1197,8 +1205,6 @@ pub inline fn setRefreshCallback(self: Window, callback: ?fn (window: Window) vo
// /// @param[in] window The window whose callback to set. // /// @param[in] window The window whose callback to set.
// /// @param[in] callback The new callback, or null to remove the currently set // /// @param[in] callback The new callback, or null to remove the currently set
// /// callback. // /// callback.
// /// @return The previously set callback, or null if no callback was set or the
// /// library had not been [initialized](@ref intro_init).
// /// // ///
// /// @callback_param `window` the window whose framebuffer was resized. // /// @callback_param `window` the window whose framebuffer was resized.
// /// @callback_param `width` the new width, in pixels, of the framebuffer. // /// @callback_param `width` the new width, in pixels, of the framebuffer.
@ -1217,8 +1223,6 @@ pub inline fn setRefreshCallback(self: Window, callback: ?fn (window: Window) vo
// /// @param[in] window The window whose callback to set. // /// @param[in] window The window whose callback to set.
// /// @param[in] callback The new callback, or null to remove the currently set // /// @param[in] callback The new callback, or null to remove the currently set
// /// callback. // /// callback.
// /// @return The previously set callback, or null if no callback was set or the
// /// library had not been [initialized](@ref intro_init).
// /// // ///
// /// @callback_param `window` the window whose content scale changed. // /// @callback_param `window` the window whose content scale changed.
// /// @callback_param `xscale` the new x-axis content scale of the window. // /// @callback_param `xscale` the new x-axis content scale of the window.
@ -1854,3 +1858,24 @@ test "setRefreshCallback" {
} }
}).callback); }).callback);
} }
test "setFocusCallback" {
const glfw = @import("main.zig");
try glfw.init();
defer glfw.terminate();
const window = glfw.Window.create(640, 480, "Hello, Zig!", null, null) catch |err| {
// return without fail, because most of our CI environments are headless / we cannot open
// windows on them.
std.debug.print("note: failed to create window: {}\n", .{err});
return;
};
defer window.destroy();
window.setFocusCallback((struct {
fn callback(_window: Window, focused: bool) void {
_ = _window;
_ = focused;
}
}).callback);
}