From 7c4f16a8d612795b2b27961b268bafd4c1c553fc Mon Sep 17 00:00:00 2001 From: Andres Vanegas Date: Mon, 27 May 2024 15:59:24 -0500 Subject: [PATCH 1/3] Improved auto start and force 16:9 aspect ratio features --- obs-zoom-to-mouse.lua | 68 +++++++++++++++++++++++++++++++++---------- 1 file changed, 53 insertions(+), 15 deletions(-) diff --git a/obs-zoom-to-mouse.lua b/obs-zoom-to-mouse.lua index 10def66..8c007ec 100644 --- a/obs-zoom-to-mouse.lua +++ b/obs-zoom-to-mouse.lua @@ -51,6 +51,8 @@ local osx_mouse_location = nil local use_auto_follow_mouse = true local use_follow_outside_bounds = false local is_following_mouse = false +local force_16_9 = true +local auto_start = false local follow_speed = 0.1 local follow_border = 0 local follow_safezone_sensitivity = 10 @@ -87,6 +89,8 @@ local m1, m2 = version:match("(%d+%.%d+)%.(%d+)") local major = tonumber(m1) or 0 local minor = tonumber(m2) or 0 +local __ar16_9__ = 16 / 9 + -- Define the mouse cursor functions for each platform if ffi.os == "Windows" then ffi.cdef([[ @@ -617,7 +621,7 @@ function refresh_sceneitem(find_newest) source_height = monitor_info.height else log("ERROR: Something went wrong determining source size.\n" .. - " Try using the 'Set manual source position' option and adding override values") + " Try using the 'Set manual source position' option and adding override values") end else log("Using source size: " .. source_width .. ", " .. source_height) @@ -784,7 +788,8 @@ function get_target_position(zoom) -- Remember that because we are using a crop/pad filter making the size smaller (dividing by zoom) means that we see less of the image -- in the same amount of space making it look bigger (aka zoomed in) local new_size = { - width = zoom.source_size.width / zoom.zoom_to, + -- if aspect ratio should be fixed to 16:9, compute width from height instead of getting directly from display size + width = (force_16_9 and (zoom.source_size.height * __ar16_9__) or zoom.source_size.width) / zoom.zoom_to, height = zoom.source_size.height / zoom.zoom_to } @@ -825,11 +830,27 @@ function on_toggle_follow(pressed) end end -function on_toggle_zoom(pressed) - if pressed then +function on_toggle_zoom(pressed, force_value) + if force_value or pressed then -- Check if we are in a safe state to zoom - if zoom_state == ZoomState.ZoomedIn or zoom_state == ZoomState.None then - if zoom_state == ZoomState.ZoomedIn then + if force_value or zoom_state == ZoomState.ZoomedIn or zoom_state == ZoomState.None then + local should_zoom + if force_value == nil then + should_zoom = zoom_state == ZoomState.ZoomedIn or zoom_state == ZoomState.None + else + should_zoom = force_value + end + + if should_zoom then + log("Zooming in") + -- To zoom in, we get a new target based on where the mouse was when zoom was clicked + zoom_state = ZoomState.ZoomingIn + zoom_info.zoom_to = zoom_value + zoom_time = 0 + locked_center = nil + locked_last_pos = nil + zoom_target = get_target_position(zoom_info) + else log("Zooming out") -- To zoom out, we set the target back to whatever it was originally zoom_state = ZoomState.ZoomingOut @@ -841,15 +862,6 @@ function on_toggle_zoom(pressed) is_following_mouse = false log("Tracking mouse is off (due to zoom out)") end - else - log("Zooming in") - -- To zoom in, we get a new target based on where the mouse was when zoom was clicked - zoom_state = ZoomState.ZoomingIn - zoom_info.zoom_to = zoom_value - zoom_time = 0 - locked_center = nil - locked_last_pos = nil - zoom_target = get_target_position(zoom_info) end -- Since we are zooming we need to start the timer for the animation and tracking @@ -1136,6 +1148,11 @@ function on_settings_modified(props, prop, settings) end end + if auto_start then + on_toggle_zoom(true, true) + else + on_toggle_zoom(true, false) + end return false end @@ -1164,6 +1181,8 @@ function log_current_settings() socket_port = socket_port, socket_poll = socket_poll, debug_logs = debug_logs, + force_16_9 = force_16_9, + auto_start = auto_start, version = VERSION } @@ -1183,6 +1202,7 @@ function on_print_help() "Zoom Factor: How much to zoom in by\n" .. "Zoom Speed: The speed of the zoom in/out animation\n" .. "Auto follow mouse: True to track the cursor while you are zoomed in\n" .. + "Force 16:9: True to get zoomed window as 16:9 (fixes problems with wide resolutions)\n" .. "Follow outside bounds: True to track the cursor even when it is outside the bounds of the source\n" .. "Follow Speed: The speed at which the zoomed area will follow the mouse when tracking\n" .. "Follow Border: The %distance from the edge of the source that will re-enable mouse tracking\n" .. @@ -1238,6 +1258,8 @@ function script_properties() -- Add the rest of the settings UI local zoom = obs.obs_properties_add_float(props, "zoom_value", "Zoom Factor", 1, 5, 0.5) local zoom_speed = obs.obs_properties_add_float_slider(props, "zoom_speed", "Zoom Speed", 0.01, 1, 0.01) + local auto_start = obs.obs_properties_add_bool(props, "auto_start", "Auto start ") + local force_16_9 = obs.obs_properties_add_bool(props, "force_16_9", "Force 16:9 aspect ratio ") local follow = obs.obs_properties_add_bool(props, "follow", "Auto follow mouse ") obs.obs_property_set_long_description(follow, "When enabled mouse traking will auto-start when zoomed in without waiting for tracking toggle hotkey") @@ -1373,6 +1395,8 @@ function script_load(settings) socket_port = obs.obs_data_get_int(settings, "socket_port") socket_poll = obs.obs_data_get_int(settings, "socket_poll") debug_logs = obs.obs_data_get_bool(settings, "debug_logs") + auto_start = obs.obs_data_get_bool(settings, "auto_start") + force_16_9 = obs.obs_data_get_bool(settings, "force_16_9") obs.obs_frontend_add_event_callback(on_frontend_event) @@ -1431,6 +1455,10 @@ function script_unload() if socket_server ~= nil then stop_server() end + + if auto_start then + on_toggle_zoom(true, false) + end end function script_defaults(settings) @@ -1457,6 +1485,8 @@ function script_defaults(settings) obs.obs_data_set_default_int(settings, "socket_port", 12345) obs.obs_data_set_default_int(settings, "socket_poll", 10) obs.obs_data_set_default_bool(settings, "debug_logs", false) + obs.obs_data_set_default_bool(settings, "force_16_9", true) + obs.obs_data_set_default_bool(settings, "auto_start", false) end function script_save(settings) @@ -1513,6 +1543,8 @@ function script_update(settings) socket_port = obs.obs_data_get_int(settings, "socket_port") socket_poll = obs.obs_data_get_int(settings, "socket_poll") debug_logs = obs.obs_data_get_bool(settings, "debug_logs") + force_16_9 = obs.obs_data_get_bool(settings, "force_16_9") + auto_start = obs.obs_data_get_bool(settings, "auto_start") -- Only do the expensive refresh if the user selected a new source if source_name ~= old_source_name and is_obs_loaded then @@ -1545,6 +1577,12 @@ function script_update(settings) stop_server() start_server() end + + if auto_start then + on_toggle_zoom(true, true) + else + on_toggle_zoom(true, false) + end end function populate_zoom_sources(list) From 3b8c18d7bf4b7cebf49960c4a9c5ccac7914270c Mon Sep 17 00:00:00 2001 From: Andres Vanegas Date: Fri, 7 Jun 2024 16:49:41 -0500 Subject: [PATCH 2/3] Improved obs startup. Bugfix --- obs-zoom-to-mouse.lua | 42 ++++++++++++++++++++++++++---------------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/obs-zoom-to-mouse.lua b/obs-zoom-to-mouse.lua index 8c007ec..fb133f2 100644 --- a/obs-zoom-to-mouse.lua +++ b/obs-zoom-to-mouse.lua @@ -52,7 +52,7 @@ local use_auto_follow_mouse = true local use_follow_outside_bounds = false local is_following_mouse = false local force_16_9 = true -local auto_start = false +local lock_in = false local follow_speed = 0.1 local follow_border = 0 local follow_safezone_sensitivity = 10 @@ -621,7 +621,7 @@ function refresh_sceneitem(find_newest) source_height = monitor_info.height else log("ERROR: Something went wrong determining source size.\n" .. - " Try using the 'Set manual source position' option and adding override values") + " Try using the 'Set manual source position' option and adding override values") end else log("Using source size: " .. source_width .. ", " .. source_height) @@ -1148,10 +1148,8 @@ function on_settings_modified(props, prop, settings) end end - if auto_start then - on_toggle_zoom(true, true) - else - on_toggle_zoom(true, false) + if lock_in ~= nil then + on_toggle_zoom(true, lock_in) end return false end @@ -1182,7 +1180,7 @@ function log_current_settings() socket_poll = socket_poll, debug_logs = debug_logs, force_16_9 = force_16_9, - auto_start = auto_start, + lock_in = lock_in, version = VERSION } @@ -1258,7 +1256,9 @@ function script_properties() -- Add the rest of the settings UI local zoom = obs.obs_properties_add_float(props, "zoom_value", "Zoom Factor", 1, 5, 0.5) local zoom_speed = obs.obs_properties_add_float_slider(props, "zoom_speed", "Zoom Speed", 0.01, 1, 0.01) - local auto_start = obs.obs_properties_add_bool(props, "auto_start", "Auto start ") + local lock_in = obs.obs_properties_add_bool(props, "lock_in", "Lock-In ") + obs.obs_property_set_long_description(lock_in, + "When enabled, auto zoom feature cannot be disabled manually, and auto zoom restarts with OBS too") local force_16_9 = obs.obs_properties_add_bool(props, "force_16_9", "Force 16:9 aspect ratio ") local follow = obs.obs_properties_add_bool(props, "follow", "Auto follow mouse ") obs.obs_property_set_long_description(follow, @@ -1395,7 +1395,7 @@ function script_load(settings) socket_port = obs.obs_data_get_int(settings, "socket_port") socket_poll = obs.obs_data_get_int(settings, "socket_poll") debug_logs = obs.obs_data_get_bool(settings, "debug_logs") - auto_start = obs.obs_data_get_bool(settings, "auto_start") + lock_in = obs.obs_data_get_bool(settings, "lock_in") force_16_9 = obs.obs_data_get_bool(settings, "force_16_9") obs.obs_frontend_add_event_callback(on_frontend_event) @@ -1456,7 +1456,7 @@ function script_unload() stop_server() end - if auto_start then + if lock_in then on_toggle_zoom(true, false) end end @@ -1486,7 +1486,7 @@ function script_defaults(settings) obs.obs_data_set_default_int(settings, "socket_poll", 10) obs.obs_data_set_default_bool(settings, "debug_logs", false) obs.obs_data_set_default_bool(settings, "force_16_9", true) - obs.obs_data_set_default_bool(settings, "auto_start", false) + obs.obs_data_set_default_bool(settings, "lock_in", false) end function script_save(settings) @@ -1544,7 +1544,7 @@ function script_update(settings) socket_poll = obs.obs_data_get_int(settings, "socket_poll") debug_logs = obs.obs_data_get_bool(settings, "debug_logs") force_16_9 = obs.obs_data_get_bool(settings, "force_16_9") - auto_start = obs.obs_data_get_bool(settings, "auto_start") + lock_in = obs.obs_data_get_bool(settings, "lock_in") -- Only do the expensive refresh if the user selected a new source if source_name ~= old_source_name and is_obs_loaded then @@ -1578,10 +1578,20 @@ function script_update(settings) start_server() end - if auto_start then - on_toggle_zoom(true, true) - else - on_toggle_zoom(true, false) + if lock_in ~= nil and source == nil then + local timer_interval = math.floor(obs.obs_get_frame_interval_ns() / 100000) + obs.timer_add(wait_for_auto_start, timer_interval) + elseif lock_in ~= nil and source ~= nil then + on_toggle_zoom(true, lock_in) + end +end + +function wait_for_auto_start() + local found_source = obs.obs_get_source_by_name(source_name) + if found_source ~= nil then + source = found_source + on_toggle_zoom(true, lock_in) + obs.remove_current_callback() end end From 09ffe6685ac757307de1af876a7cd8d3b87df498 Mon Sep 17 00:00:00 2001 From: Andres Vanegas Date: Sun, 6 Oct 2024 00:52:58 -0500 Subject: [PATCH 3/3] Fixed locked-in, fixed aspect ratio --- obs-zoom-to-mouse.lua | 202 +++++++++++++++++++++++++++++++----------- 1 file changed, 150 insertions(+), 52 deletions(-) diff --git a/obs-zoom-to-mouse.lua b/obs-zoom-to-mouse.lua index fb133f2..93c4bdc 100644 --- a/obs-zoom-to-mouse.lua +++ b/obs-zoom-to-mouse.lua @@ -51,8 +51,6 @@ local osx_mouse_location = nil local use_auto_follow_mouse = true local use_follow_outside_bounds = false local is_following_mouse = false -local force_16_9 = true -local lock_in = false local follow_speed = 0.1 local follow_border = 0 local follow_safezone_sensitivity = 10 @@ -89,7 +87,11 @@ local m1, m2 = version:match("(%d+%.%d+)%.(%d+)") local major = tonumber(m1) or 0 local minor = tonumber(m2) or 0 -local __ar16_9__ = 16 / 9 +local keep_shape = false +local auto_start = false +local auto_start_running = false +local aspect_ratio_w = 1 +local aspect_ratio_h = 1 -- Define the mouse cursor functions for each platform if ffi.os == "Windows" then @@ -300,6 +302,33 @@ function clamp(min, max, value) return math.max(min, math.min(max, value)) end +--- +-- Function to calculate GCD (Greatest Common Divisor) +--- @param a number +--- @param b number +function gcd(a, b) + while b ~= 0 do + local temp = b + b = a % b + a = temp + end + return a +end + +--- +-- Function to convert resolution to aspect ratio +--- @param width number the width of the resolution +--- @param height number the height of the resolution +--- @return number aspect_width, number aspect_height the simplified aspect ratio as two numbers +function resolution_to_aspect_ratio(width, height) + -- Calculate GCD of width and height + local divisor = gcd(width, height) + -- Simplify width and height using GCD + local aspect_width = width / divisor + local aspect_height = height / divisor + return aspect_width, aspect_height +end + --- -- Get the size and position of the monitor so that we know the top-left mouse point ---@param source any The OBS source @@ -462,6 +491,7 @@ function release_sceneitem() sceneitem_crop_orig = nil end + toggle_sceneitem_change_listener(false) obs.obs_sceneitem_release(sceneitem) sceneitem = nil end @@ -545,6 +575,7 @@ function refresh_sceneitem(find_newest) -- We start at the current scene and use a BFS to look into any nested scenes local current = obs.obs_scene_from_source(scene_source) sceneitem = find_scene_item_by_name(current) + toggle_sceneitem_change_listener(true) obs.obs_source_release(scene_source) end @@ -552,9 +583,11 @@ function refresh_sceneitem(find_newest) if not sceneitem then log("WARNING: Source not part of the current scene hierarchy.\n" .. " Try selecting a different zoom source or switching scenes.") + toggle_sceneitem_change_listener(false) obs.obs_sceneitem_release(sceneitem) obs.obs_source_release(source) + sceneitem = nil source = nil return @@ -788,8 +821,12 @@ function get_target_position(zoom) -- Remember that because we are using a crop/pad filter making the size smaller (dividing by zoom) means that we see less of the image -- in the same amount of space making it look bigger (aka zoomed in) local new_size = { - -- if aspect ratio should be fixed to 16:9, compute width from height instead of getting directly from display size - width = (force_16_9 and (zoom.source_size.height * __ar16_9__) or zoom.source_size.width) / zoom.zoom_to, + width = ( + -- if should keep shape, use aspect ratio to get new width + keep_shape and (zoom.source_size.height * (aspect_ratio_w / aspect_ratio_h)) + -- else use source resolution + or zoom.source_size.width + ) / zoom.zoom_to, height = zoom.source_size.height / zoom.zoom_to } @@ -831,26 +868,11 @@ function on_toggle_follow(pressed) end function on_toggle_zoom(pressed, force_value) - if force_value or pressed then + if pressed or force_value then -- Check if we are in a safe state to zoom - if force_value or zoom_state == ZoomState.ZoomedIn or zoom_state == ZoomState.None then - local should_zoom - if force_value == nil then - should_zoom = zoom_state == ZoomState.ZoomedIn or zoom_state == ZoomState.None - else - should_zoom = force_value - end - - if should_zoom then - log("Zooming in") - -- To zoom in, we get a new target based on where the mouse was when zoom was clicked - zoom_state = ZoomState.ZoomingIn - zoom_info.zoom_to = zoom_value - zoom_time = 0 - locked_center = nil - locked_last_pos = nil - zoom_target = get_target_position(zoom_info) - else + if zoom_state == ZoomState.ZoomedIn or zoom_state == ZoomState.None or force_value then + local should_zoom = (force_value ~= nil) and force_value or (zoom_state ~= ZoomState.ZoomedIn) + if not should_zoom then log("Zooming out") -- To zoom out, we set the target back to whatever it was originally zoom_state = ZoomState.ZoomingOut @@ -862,6 +884,18 @@ function on_toggle_zoom(pressed, force_value) is_following_mouse = false log("Tracking mouse is off (due to zoom out)") end + else + log("Zooming in") + -- To zoom in, we get a new target based on where the mouse was when zoom was clicked + if keep_shape then + update_aspect_ratio() + end + zoom_state = ZoomState.ZoomingIn + zoom_info.zoom_to = zoom_value + zoom_time = 0 + locked_center = nil + locked_last_pos = nil + zoom_target = get_target_position(zoom_info) end -- Since we are zooming we need to start the timer for the animation and tracking @@ -1081,6 +1115,53 @@ function on_transition_start(t) -- We need to remove the crop from the sceneitem as the transition starts to avoid -- a delay with the rendering where you see the old crop and jump to the new one release_sceneitem() + + --- + -- Ensure to restart filters on scene change back + --- + if source_name ~= "obs-zoom-to-mouse-none" and auto_start and not auto_start_running then + log("Auto starting") + auto_start_running = true + local timer_interval = math.floor(obs.obs_get_frame_interval_ns() / 100000) + obs.timer_add(wait_for_auto_start, timer_interval) + end +end + +function update_aspect_ratio() + if keep_shape == nil or not keep_shape or sceneitem == nil then + return + end + + sceneitem_info_current = obs.obs_transform_info() + obs.obs_sceneitem_get_info(sceneitem, sceneitem_info_current) + aspect_ratio_w, aspect_ratio_h = resolution_to_aspect_ratio( + sceneitem_info_current.bounds.x, sceneitem_info_current.bounds.y + ) +end + +function on_transform_update() + update_aspect_ratio() + if keep_shape then + if zoom_state == ZoomState.ZoomedIn then + -- Perform zoom again + zoom_state = ZoomState.ZoomingIn + zoom_info.zoom_to = zoom_value + zoom_time = 0 + zoom_target = get_target_position(zoom_info) + end + end +end + +function toggle_sceneitem_change_listener(value) + local scene = obs.obs_sceneitem_get_scene(sceneitem) + local scene_source = obs.obs_scene_get_source(scene) + local handler = obs.obs_source_get_signal_handler(scene_source) + if value then + update_aspect_ratio() + obs.signal_handler_connect(handler, "item_transform", on_transform_update) + else + obs.signal_handler_disconnect(handler, on_transform_update) + end end function on_frontend_event(event) @@ -1142,15 +1223,14 @@ function on_settings_modified(props, prop, settings) local sources_list = obs.obs_properties_get(props, "source") populate_zoom_sources(sources_list) return true + elseif name == "keep_shape" then + on_transform_update() elseif name == "debug_logs" then if obs.obs_data_get_bool(settings, "debug_logs") then log_current_settings() end end - if lock_in ~= nil then - on_toggle_zoom(true, lock_in) - end return false end @@ -1160,6 +1240,8 @@ function log_current_settings() local settings = { zoom_value = zoom_value, zoom_speed = zoom_speed, + auto_start = auto_start, + keep_shape = keep_shape, use_auto_follow_mouse = use_auto_follow_mouse, use_follow_outside_bounds = use_follow_outside_bounds, follow_speed = follow_speed, @@ -1179,8 +1261,6 @@ function log_current_settings() socket_port = socket_port, socket_poll = socket_poll, debug_logs = debug_logs, - force_16_9 = force_16_9, - lock_in = lock_in, version = VERSION } @@ -1199,8 +1279,9 @@ function on_print_help() "Zoom Source: The display capture in the current scene to use for zooming\n" .. "Zoom Factor: How much to zoom in by\n" .. "Zoom Speed: The speed of the zoom in/out animation\n" .. + "Zoomed at OBS startup: Start OBS with source zoomed\n" .. + "Dynamic Aspect Ratio: Adjusst zoom aspect ratio to canvas source size\n" .. "Auto follow mouse: True to track the cursor while you are zoomed in\n" .. - "Force 16:9: True to get zoomed window as 16:9 (fixes problems with wide resolutions)\n" .. "Follow outside bounds: True to track the cursor even when it is outside the bounds of the source\n" .. "Follow Speed: The speed at which the zoomed area will follow the mouse when tracking\n" .. "Follow Border: The %distance from the edge of the source that will re-enable mouse tracking\n" .. @@ -1256,10 +1337,15 @@ function script_properties() -- Add the rest of the settings UI local zoom = obs.obs_properties_add_float(props, "zoom_value", "Zoom Factor", 1, 5, 0.5) local zoom_speed = obs.obs_properties_add_float_slider(props, "zoom_speed", "Zoom Speed", 0.01, 1, 0.01) - local lock_in = obs.obs_properties_add_bool(props, "lock_in", "Lock-In ") - obs.obs_property_set_long_description(lock_in, - "When enabled, auto zoom feature cannot be disabled manually, and auto zoom restarts with OBS too") - local force_16_9 = obs.obs_properties_add_bool(props, "force_16_9", "Force 16:9 aspect ratio ") + + local auto_start = obs.obs_properties_add_bool(props, "auto_start", "Zoomed at OBS startup ") + obs.obs_property_set_long_description(auto_start, + "When enabled, auto zoom is activated on OBS start up as soon as possible") + + local keep_shape = obs.obs_properties_add_bool(props, "keep_shape", "Dynamic Aspect Ratio ") + obs.obs_property_set_long_description(keep_shape, + "When enabled, zoom will follow he aspect ratio of source in canvas") + local follow = obs.obs_properties_add_bool(props, "follow", "Auto follow mouse ") obs.obs_property_set_long_description(follow, "When enabled mouse traking will auto-start when zoomed in without waiting for tracking toggle hotkey") @@ -1375,7 +1461,6 @@ function script_load(settings) -- Load any other settings zoom_value = obs.obs_data_get_double(settings, "zoom_value") zoom_speed = obs.obs_data_get_double(settings, "zoom_speed") - use_auto_follow_mouse = obs.obs_data_get_bool(settings, "follow") use_follow_outside_bounds = obs.obs_data_get_bool(settings, "follow_outside_bounds") follow_speed = obs.obs_data_get_double(settings, "follow_speed") follow_border = obs.obs_data_get_int(settings, "follow_border") @@ -1395,8 +1480,8 @@ function script_load(settings) socket_port = obs.obs_data_get_int(settings, "socket_port") socket_poll = obs.obs_data_get_int(settings, "socket_poll") debug_logs = obs.obs_data_get_bool(settings, "debug_logs") - lock_in = obs.obs_data_get_bool(settings, "lock_in") - force_16_9 = obs.obs_data_get_bool(settings, "force_16_9") + auto_start = obs.obs_data_get_bool(settings, "auto_start") + keep_shape = obs.obs_data_get_bool(settings, "keep_shape") obs.obs_frontend_add_event_callback(on_frontend_event) @@ -1424,6 +1509,13 @@ function script_load(settings) source_name = "" use_socket = false is_script_loaded = true + + if source_name ~= "obs-zoom-to-mouse-none" and auto_start and not auto_start_running then + log("Auto starting") + auto_start_running = true + local timer_interval = math.floor(obs.obs_get_frame_interval_ns() / 100000) + obs.timer_add(wait_for_auto_start, timer_interval) + end end function script_unload() @@ -1455,10 +1547,6 @@ function script_unload() if socket_server ~= nil then stop_server() end - - if lock_in then - on_toggle_zoom(true, false) - end end function script_defaults(settings) @@ -1485,8 +1573,8 @@ function script_defaults(settings) obs.obs_data_set_default_int(settings, "socket_port", 12345) obs.obs_data_set_default_int(settings, "socket_poll", 10) obs.obs_data_set_default_bool(settings, "debug_logs", false) - obs.obs_data_set_default_bool(settings, "force_16_9", true) - obs.obs_data_set_default_bool(settings, "lock_in", false) + obs.obs_data_set_default_bool(settings, "auto_start", false) + obs.obs_data_set_default_bool(settings, "keep_shape", false) end function script_save(settings) @@ -1543,8 +1631,8 @@ function script_update(settings) socket_port = obs.obs_data_get_int(settings, "socket_port") socket_poll = obs.obs_data_get_int(settings, "socket_poll") debug_logs = obs.obs_data_get_bool(settings, "debug_logs") - force_16_9 = obs.obs_data_get_bool(settings, "force_16_9") - lock_in = obs.obs_data_get_bool(settings, "lock_in") + auto_start = obs.obs_data_get_bool(settings, "auto_start") + keep_shape = obs.obs_data_get_bool(settings, "keep_shape") -- Only do the expensive refresh if the user selected a new source if source_name ~= old_source_name and is_obs_loaded then @@ -1578,20 +1666,30 @@ function script_update(settings) start_server() end - if lock_in ~= nil and source == nil then + if source_name ~= "obs-zoom-to-mouse-none" and auto_start and not auto_start_running then + log("Auto starting") + auto_start_running = true local timer_interval = math.floor(obs.obs_get_frame_interval_ns() / 100000) obs.timer_add(wait_for_auto_start, timer_interval) - elseif lock_in ~= nil and source ~= nil then - on_toggle_zoom(true, lock_in) end end function wait_for_auto_start() - local found_source = obs.obs_get_source_by_name(source_name) - if found_source ~= nil then - source = found_source - on_toggle_zoom(true, lock_in) + if source_name == "obs-zoom-to-mouse-none" or not auto_start then obs.remove_current_callback() + auto_start_running = false + log("Auto start cancelled") + else + auto_start_running = true + local found_source = obs.obs_get_source_by_name(source_name) + if found_source ~= nil then + -- zoom_state = ZoomState.ZoomingIn + source = found_source + on_toggle_zoom(true, true) + obs.remove_current_callback() + auto_start_running = false + log("Auto start done") + end end end