@@ -51,6 +51,8 @@ local osx_mouse_location = nil
5151local use_auto_follow_mouse = true
5252local use_follow_outside_bounds = false
5353local is_following_mouse = false
54+ local force_16_9 = true
55+ local auto_start = false
5456local follow_speed = 0.1
5557local follow_border = 0
5658local follow_safezone_sensitivity = 10
@@ -87,6 +89,8 @@ local m1, m2 = version:match("(%d+%.%d+)%.(%d+)")
8789local major = tonumber (m1 ) or 0
8890local minor = tonumber (m2 ) or 0
8991
92+ local __ar16_9__ = 16 / 9
93+
9094-- Define the mouse cursor functions for each platform
9195if ffi .os == " Windows" then
9296 ffi .cdef ([[
@@ -617,7 +621,7 @@ function refresh_sceneitem(find_newest)
617621 source_height = monitor_info .height
618622 else
619623 log (" ERROR: Something went wrong determining source size.\n " ..
620- " Try using the 'Set manual source position' option and adding override values" )
624+ " Try using the 'Set manual source position' option and adding override values" )
621625 end
622626 else
623627 log (" Using source size: " .. source_width .. " , " .. source_height )
@@ -784,7 +788,8 @@ function get_target_position(zoom)
784788 -- 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
785789 -- in the same amount of space making it look bigger (aka zoomed in)
786790 local new_size = {
787- width = zoom .source_size .width / zoom .zoom_to ,
791+ -- if aspect ratio should be fixed to 16:9, compute width from height instead of getting directly from display size
792+ width = (force_16_9 and (zoom .source_size .height * __ar16_9__ ) or zoom .source_size .width ) / zoom .zoom_to ,
788793 height = zoom .source_size .height / zoom .zoom_to
789794 }
790795
@@ -825,11 +830,27 @@ function on_toggle_follow(pressed)
825830 end
826831end
827832
828- function on_toggle_zoom (pressed )
829- if pressed then
833+ function on_toggle_zoom (pressed , force_value )
834+ if force_value or pressed then
830835 -- Check if we are in a safe state to zoom
831- if zoom_state == ZoomState .ZoomedIn or zoom_state == ZoomState .None then
832- if zoom_state == ZoomState .ZoomedIn then
836+ if force_value or zoom_state == ZoomState .ZoomedIn or zoom_state == ZoomState .None then
837+ local should_zoom
838+ if force_value == nil then
839+ should_zoom = zoom_state == ZoomState .ZoomedIn or zoom_state == ZoomState .None
840+ else
841+ should_zoom = force_value
842+ end
843+
844+ if should_zoom then
845+ log (" Zooming in" )
846+ -- To zoom in, we get a new target based on where the mouse was when zoom was clicked
847+ zoom_state = ZoomState .ZoomingIn
848+ zoom_info .zoom_to = zoom_value
849+ zoom_time = 0
850+ locked_center = nil
851+ locked_last_pos = nil
852+ zoom_target = get_target_position (zoom_info )
853+ else
833854 log (" Zooming out" )
834855 -- To zoom out, we set the target back to whatever it was originally
835856 zoom_state = ZoomState .ZoomingOut
@@ -841,15 +862,6 @@ function on_toggle_zoom(pressed)
841862 is_following_mouse = false
842863 log (" Tracking mouse is off (due to zoom out)" )
843864 end
844- else
845- log (" Zooming in" )
846- -- To zoom in, we get a new target based on where the mouse was when zoom was clicked
847- zoom_state = ZoomState .ZoomingIn
848- zoom_info .zoom_to = zoom_value
849- zoom_time = 0
850- locked_center = nil
851- locked_last_pos = nil
852- zoom_target = get_target_position (zoom_info )
853865 end
854866
855867 -- 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)
11361148 end
11371149 end
11381150
1151+ if auto_start then
1152+ on_toggle_zoom (true , true )
1153+ else
1154+ on_toggle_zoom (true , false )
1155+ end
11391156 return false
11401157end
11411158
@@ -1164,6 +1181,8 @@ function log_current_settings()
11641181 socket_port = socket_port ,
11651182 socket_poll = socket_poll ,
11661183 debug_logs = debug_logs ,
1184+ force_16_9 = force_16_9 ,
1185+ auto_start = auto_start ,
11671186 version = VERSION
11681187 }
11691188
@@ -1183,6 +1202,7 @@ function on_print_help()
11831202 " Zoom Factor: How much to zoom in by\n " ..
11841203 " Zoom Speed: The speed of the zoom in/out animation\n " ..
11851204 " Auto follow mouse: True to track the cursor while you are zoomed in\n " ..
1205+ " Force 16:9: True to get zoomed window as 16:9 (fixes problems with wide resolutions)\n " ..
11861206 " Follow outside bounds: True to track the cursor even when it is outside the bounds of the source\n " ..
11871207 " Follow Speed: The speed at which the zoomed area will follow the mouse when tracking\n " ..
11881208 " Follow Border: The %distance from the edge of the source that will re-enable mouse tracking\n " ..
@@ -1238,6 +1258,8 @@ function script_properties()
12381258 -- Add the rest of the settings UI
12391259 local zoom = obs .obs_properties_add_float (props , " zoom_value" , " Zoom Factor" , 1 , 5 , 0.5 )
12401260 local zoom_speed = obs .obs_properties_add_float_slider (props , " zoom_speed" , " Zoom Speed" , 0.01 , 1 , 0.01 )
1261+ local auto_start = obs .obs_properties_add_bool (props , " auto_start" , " Auto start " )
1262+ local force_16_9 = obs .obs_properties_add_bool (props , " force_16_9" , " Force 16:9 aspect ratio " )
12411263 local follow = obs .obs_properties_add_bool (props , " follow" , " Auto follow mouse " )
12421264 obs .obs_property_set_long_description (follow ,
12431265 " When enabled mouse traking will auto-start when zoomed in without waiting for tracking toggle hotkey" )
@@ -1373,6 +1395,8 @@ function script_load(settings)
13731395 socket_port = obs .obs_data_get_int (settings , " socket_port" )
13741396 socket_poll = obs .obs_data_get_int (settings , " socket_poll" )
13751397 debug_logs = obs .obs_data_get_bool (settings , " debug_logs" )
1398+ auto_start = obs .obs_data_get_bool (settings , " auto_start" )
1399+ force_16_9 = obs .obs_data_get_bool (settings , " force_16_9" )
13761400
13771401 obs .obs_frontend_add_event_callback (on_frontend_event )
13781402
@@ -1431,6 +1455,10 @@ function script_unload()
14311455 if socket_server ~= nil then
14321456 stop_server ()
14331457 end
1458+
1459+ if auto_start then
1460+ on_toggle_zoom (true , false )
1461+ end
14341462end
14351463
14361464function script_defaults (settings )
@@ -1457,6 +1485,8 @@ function script_defaults(settings)
14571485 obs .obs_data_set_default_int (settings , " socket_port" , 12345 )
14581486 obs .obs_data_set_default_int (settings , " socket_poll" , 10 )
14591487 obs .obs_data_set_default_bool (settings , " debug_logs" , false )
1488+ obs .obs_data_set_default_bool (settings , " force_16_9" , true )
1489+ obs .obs_data_set_default_bool (settings , " auto_start" , false )
14601490end
14611491
14621492function script_save (settings )
@@ -1513,6 +1543,8 @@ function script_update(settings)
15131543 socket_port = obs .obs_data_get_int (settings , " socket_port" )
15141544 socket_poll = obs .obs_data_get_int (settings , " socket_poll" )
15151545 debug_logs = obs .obs_data_get_bool (settings , " debug_logs" )
1546+ force_16_9 = obs .obs_data_get_bool (settings , " force_16_9" )
1547+ auto_start = obs .obs_data_get_bool (settings , " auto_start" )
15161548
15171549 -- Only do the expensive refresh if the user selected a new source
15181550 if source_name ~= old_source_name and is_obs_loaded then
@@ -1545,6 +1577,12 @@ function script_update(settings)
15451577 stop_server ()
15461578 start_server ()
15471579 end
1580+
1581+ if auto_start then
1582+ on_toggle_zoom (true , true )
1583+ else
1584+ on_toggle_zoom (true , false )
1585+ end
15481586end
15491587
15501588function populate_zoom_sources (list )
0 commit comments