|
|
|
02-12-2017, 04:04 PM
|
#1
|
Human being with feelings
Join Date: Sep 2008
Location: Calgary, AB, Canada
Posts: 6,551
|
API: Getting coordinates with multiple monitors
I'm having trouble getting a window to open at the mouse cursor when the user has two monitors; it always opens on the main screen, regardless of which one the mouse is on.
My current code looks roughly like:
Code:
x, y, w, h = Window dimensions and offset from the cursor
Get the screen size:
__, __, scr_w, scr_h = reaper.my_getViewport(x, y, x + w, y + h, x, y, x + w, y + h, 1)
Get the mouse position:
ax, ay = reaper.GetMousePosition()
Center the window to the mouse:
x, y = ax + x - (w / 2), ay + y - (h / 2)
Make sure every edge of the window would be on-screen:
l, t, r, b = x, y, x + w, y + h
if l < 0 then x = 0 end
if r > scr_w then x = (scr_w - w - 16) end
if t < 0 then y = 0 end
if b > scr_h then y = (scr_h - h - 40) end
return x, y
I suspect the issue lies with reaper.my_getViewport - since there's zero documentation for it, the values I'm using are complete guesses that have happened to work up until this point.
Any insight would be appreciated.
(Note that I'm handling the "make sure we're completely on-screen" adjustments myself because reaper.EnsureNotCompletelyOffscreen() is suffering from a lack of documentation AND a lack of parameters to be given)
Last edited by Lokasenna; 02-12-2017 at 04:13 PM.
|
|
|
12-30-2019, 05:30 AM
|
#2
|
Human being with feelings
Join Date: Aug 2012
Location: Finland
Posts: 2,668
|
Any news about this?
On Win 8.1, when setting wantWorkArea to "true", the window's toolbar size is subtracted from return values.
Code:
reaper.my_getViewport(numberr.left, numberr.top, numberr.right, numberr.bot, number sr.left, number sr.top, number sr.right, number sr.bot, boolean wantWorkArea)
Code:
local left, top, right, bottom = reaper.my_getViewport(0, 0, 0, 0, 0, 0, 0, 0, true)
And this related function...
Code:
Lua: gfx.dock(v[,wx,wy,ww,wh])
Call with v=-1 to query docked state, otherwise v>=0 to set docked state. State is &1 if docked, second byte is docker index (or last docker index if undocked). If wx-wh specified, additional values will be returned with the undocked window position/size
... what does gfx.dock(-1,0,0,0,0) return on multi-monitor setup? Is wy flipped on macOS?
|
|
|
12-30-2019, 08:27 AM
|
#3
|
Human being with feelings
Join Date: Aug 2012
Location: Finland
Posts: 2,668
|
Quote:
Originally Posted by spk77
And this related function...
Code:
Lua: gfx.dock(v[,wx,wy,ww,wh])
Call with v=-1 to query docked state, otherwise v>=0 to set docked state. State is &1 if docked, second byte is docker index (or last docker index if undocked). If wx-wh specified, additional values will be returned with the undocked window position/size
... what does gfx.dock(-1,0,0,0,0) return on multi-monitor setup? Is wy flipped on macOS?
|
So, it seems that gfx.dock really returns y-position relative to the bottom-left corner of screen on macOS...This is really confusing:
(see the green text "Window_top" in the gif)
https://forum.cockos.com/showpost.ph...&postcount=221
|
|
|
12-30-2019, 01:39 PM
|
#5
|
Human being with feelings
Join Date: Aug 2012
Location: Finland
Posts: 2,668
|
Quote:
Originally Posted by nofish
|
Thanks!
This is still a bit unclear:
On macOS, does gfx.dock(-1,0,0,0,0) return the y-position as "the bottom edge of a script window"?
Do I need to do something like this:
Code:
local left, top, right, bottom = reaper.my_getViewport(0, 0, 0, 0, 0, 0, 0, 0, true)
local dock, window_left, window_top, window_w, window_h = gfx.dock(-1,0,0,0,0)
if OS == "OSX32" or OS == "OSX64" then
window_top = bottom-window_h-window_top
end
Here's a script for testing it. I would be very happy if someone could test it on macOS
Code:
local reaper = reaper
local abs = math.abs
local OS = reaper.GetOS()
local GUI = {}
GUI.dock = 0
GUI.win_x, GUI.win_y, GUI.win_w, GUI.win_h = 0, 0, 0, 0
GUI.drag = false
-- window moving is triggered when lmb is down and cursor is moved by this many pixels:
GUI.drag_start_offset = 40
local script = {title = "Get window and mouse positions"}
local mouse = {
cap = 0,
last_cap = 0,
x = -1,
y = -1,
last_x = -1,
last_y = -1,
x_screen = -1,
y_screen = -1,
last_x_screen = -1,
last_y_screen = -1,
ctrl = false,
shift = false,
alt = false,
lmb_down = false,
lmb_down_time = 0,
rmb_down = false,
rmb_down_time = 0,
lmb_up_time = 0,
rmb_up_time = 0,
wheel = 0,
ox = -1,
oy = -1,
ox_screen = -1,
oy_screen = -1
}
-----------------------------------------------------------------------
------------------------------------------------------------
function on_lmb_down()
if mouse.last_cap&1 == 0 then
local curr_time = os.clock()
mouse.lmb_down_time = curr_time
mouse.ox, mouse.oy = mouse.x, mouse.y -- click position on script window
mouse.ox_screen, mouse.oy_screen = mouse.x_screen, mouse.y_screen -- click position on screen
_, GUI.win_x, GUI.win_y, GUI.win_w, GUI.win_h = gfx.dock(-1,0,0,0,0)
elseif mouse.moved and (mouse.x_screen ~= mouse.ox_screen or mouse.y_screen ~= mouse.oy_screen) then
if not GUI.drag and(abs(mouse.x_screen - mouse.ox_screen) > GUI.drag_start_offset or
abs(mouse.y_screen - mouse.oy_screen) > GUI.drag_start_offset) then
GUI.drag = true
-- update mouse click positions (to prevent the window from jumping by "GUI.drag_start_offset" pixels)
mouse.ox_screen = mouse.x_screen
mouse.oy_screen = mouse.y_screen
end
if GUI.drag then
if gfx.dock(-1)&1 == 1 then
gfx.dock(0) -- ...undock it
-- move the undocked window to mouse position (centered to mouse cursor)
GUI.win_x, GUI.win_y = mouse.x_screen-0.5*GUI.win_w, mouse.y_screen-0.5*GUI.win_h
gfx.init("", GUI.win_w, GUI.win_h, 0, GUI.win_x, GUI.win_y) -- move window to new position
elseif gfx.dock(-1)&1 == 0 then
-- calculate new window position
local new_x = GUI.win_x-mouse.ox_screen+mouse.x_screen
local new_y = GUI.win_y-mouse.oy_screen+mouse.y_screen
gfx.init("", GUI.win_w, GUI.win_h, 0, new_x, new_y) -- move window to new position
-- move_window(mouse.x_screen, mouse.y_screen) -- needs JS reascript API
end
end
end
end
-----------------------------------------------------------------------
function on_lmb_up()
mouse.lmb_up_time = os.clock()
if GUI.drag then
GUI.drag = false
end
end
-----------------------------------------------------------------------
function get_mod_keys()
mouse.ctrl = mouse.cap&4==4
mouse.shift = mouse.cap&8==8
mouse.alt = mouse.cap&16==16
end
-----------------------------------------------------------------------
function get_mouse_btn_states()
get_mod_keys()
-- left btn down right btn down middle btn down
return mouse.cap&1==1, mouse.cap&2==2, mouse.cap&64==64
end
------------------------------------------------------------
function get_mouse_state()
mouse.x, mouse.y = gfx.mouse_x, gfx.mouse_y
mouse.wheel = gfx.mouse_wheel
mouse.x_screen, mouse.y_screen = reaper.GetMousePosition()
mouse.moved = mouse.x_screen ~= mouse.last_x_screen or mouse.y_screen ~= mouse.last_y_screen
mouse.cap = gfx.mouse_cap
mouse.lmb_down, mouse.rmb_down = get_mouse_btn_states()
if mouse.lmb_down then
on_lmb_down()
elseif mouse.last_cap&1 == 1 then
on_lmb_up()
end
end
-----------------------------------------------------------------------
function get_all_script_window_handles()
--if gfx.dock(-1)&1 == 0 then
local hWnd_array = reaper.new_array({}, 20)
local num_script_windows = reaper.JS_Window_ArrayFind(script.title, true, hWnd_array)
local handles = hWnd_array.table()
--end
return handles
end
------------------------------------------------------------
function init()
gfx.init(script.title, 800, 600)
--GUI.x, GUI.y, GUI.w, GUI.h = 0, 0, gfx.w, gfx.h
gfx.set(1,1,1,1)
gfx.setfont(1, "Arial", 20)
end
------------------------------------------------------------
function main()
get_mouse_state() -- update mouse table
gfx.x = 10
gfx.y = 10
gfx.set(1,1,1,1)
for k,v in pairs(mouse) do
if gfx.mouse_cap&1 == 1 then
if k == "x" or k == "y" or k == "ox" or k == "oy"
or k == "ox_screen" or k == "oy_screen"
or k == "x_screen" or k == "y_screen" or k == "oy_screen"
or k == "lmb_down_time" or k == "rmb_down_time" or k == "oy_screen"
then gfx.set(0,1,1,1)
elseif mouse[tostring(k)] == false then
gfx.set(1,0,0,1)
else
gfx.set(0,1,0,1)
end
end
gfx.drawstr("mouse." .. tostring(k) .. " = " .. tostring(v))
gfx.x = 10
gfx.y = gfx.y+gfx.texth
end
gfx.x = 350
gfx.y = 10
gfx.set(1,1,1,1)
for k,v in pairs(GUI) do
if gfx.mouse_cap&1 == 1 and k == "drag" then
if GUI.drag then
gfx.set(0,1,0,1)
else
gfx.set(1,0,0,1)
end
else
gfx.set(1,1,1,1)
end
gfx.drawstr("GUI." .. tostring(k) .. " = " .. tostring(v))
gfx.x = 350
gfx.y = gfx.y+gfx.texth
end
local left, top, right, bottom = reaper.my_getViewport(0, 0, 0, 0, 0, 0, 0, 0, true)
local dock, window_left, window_top, window_w, window_h = gfx.dock(-1,0,0,0,0)
if OS == "OSX32" or OS == "OSX64" then
window_top = bottom-window_h-window_top
end
gfx.set(0,1,0,1)
gfx.x = 350
gfx.y = gfx.y+gfx.texth
gfx.drawstr("dock: " .. tostring(dock))
gfx.x = 350
gfx.y = gfx.y+gfx.texth
gfx.drawstr("window_left: " .. tostring(window_left))
gfx.x = 350
gfx.y = gfx.y+gfx.texth
gfx.drawstr("window_top: " .. tostring(window_top))
gfx.x = 350
gfx.y = gfx.y+gfx.texth
gfx.drawstr("window_w: " .. tostring(window_w))
gfx.x = 350
gfx.y = gfx.y+gfx.texth
gfx.drawstr("window_h: " .. tostring(window_h))
gfx.set(0,1,1,1)
gfx.x = 350
gfx.y = gfx.y+2*gfx.texth
gfx.drawstr("reaper.my_getViewport left: " .. tostring(left))
gfx.x = 350
gfx.y = gfx.y+gfx.texth
gfx.drawstr("reaper.my_getViewport top: " .. tostring(top))
gfx.x = 350
gfx.y = gfx.y+gfx.texth
gfx.drawstr("reaper.my_getViewport right: " .. tostring(right))
gfx.x = 350
gfx.y = gfx.y+gfx.texth
gfx.drawstr("reaper.my_getViewport bottom: " .. tostring(bottom))
gfx.set(0,1,1,1)
gfx.x = 350
gfx.y = gfx.y+2*gfx.texth
local is_at_right = window_left + window_w >= right
if not is_at_right then
gfx.set(1,0,0,1)
else
gfx.set(0,1,0,1)
end
gfx.drawstr("Right edge >= screen right: " .. tostring(is_at_right))
gfx.x = 350
gfx.y = gfx.y+gfx.texth
local is_at_top = window_top <= top
if not is_at_top then
gfx.set(1,0,0,1)
else
gfx.set(0,1,0,1)
end
gfx.drawstr("Top edge <= screen top: " .. tostring(is_at_top))
gfx.x = 350
gfx.y = gfx.y+gfx.texth
local is_at_left = window_left <= left
if not is_at_left then
gfx.set(1,0,0,1)
else
gfx.set(0,1,0,1)
end
gfx.drawstr("Left edge <= screen left: " .. tostring(is_at_left))
gfx.x = 350
gfx.y = gfx.y+gfx.texth
--gfx.drawstr("Bottom edge >= screen left: " .. tostring(window_top + window_h >= bottom))
mouse.last_cap = mouse.cap
mouse.last_x = mouse.x
mouse.last_y = mouse.y
mouse.last_x_screen = mouse.x_screen
mouse.last_y_screen = mouse.y_screen
if char~=-1 then reaper.defer(main) end
gfx.update()
end
init()
main()
There's a red text - " Top edge <= screen top: false" that should turn green when the script window is at the top of the screen, like this:
|
|
|
12-30-2019, 05:49 PM
|
#6
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
|
I can't make ""Top edge <= screen top: false" turn green here, if that helps.
|
|
|
12-31-2019, 02:00 AM
|
#7
|
Human being with feelings
Join Date: Aug 2012
Location: Finland
Posts: 2,668
|
@nofish
Thanks for testing it! I see that the code is working correctly ("window_top" gets lower values when moving the window upwards)
So, it isn't possible to drag script windows past the bottom edge of reaper's titlebar on macOS?
That's why "Top edge <= screen top" is never true...
I'm using the same code for "drag'n'drop docking" -feature in Track Tags and I really like it, but I don't know if I'll ever get it working on macOS:
- drag from the title bar: window can be positioned freely
- drag from the client area: certain positions "trigger" gfx.dock -function when lmb is released
|
|
|
12-31-2019, 09:49 AM
|
#8
|
Human being with feelings
Join Date: Oct 2007
Location: home is where the heart is
Posts: 12,096
|
Quote:
Originally Posted by spk77
So, it isn't possible to drag script windows past the bottom edge of reaper's titlebar on macOS?
|
Admittedly that screencap was done on a virtual machine I'm firing up rather rarely (mostly for development purposes) so I'm not that familiar with macOS either, but apparently no, not possible to to drag script windows past the bottom edge of Reaper's titlebar. As can be seen in the gif, it's a bit different on Mac, the application's title bar sort of becomes the 'system' title bar and attaches to top even when an application isn't fully maximised.
|
|
|
12-31-2019, 09:57 AM
|
#9
|
Human being with feelings
Join Date: Aug 2012
Location: Finland
Posts: 2,668
|
Quote:
Originally Posted by nofish
Admittedly that screencap was done on a virtual machine I'm firing up rather rarely (mostly for development purposes) so I'm not that familiar with macOS either, but apparently no, not possible to to drag script windows past the bottom edge of Reaper's titlebar. As can be seen in the gif, it's a bit different on Mac, the application's title bar sort of becomes the 'system' title bar and attaches to top even when an application isn't fully maximised.
|
Thanks!
I guess it would be better to use reaper's client area edges as "trigger" points for the docking feature in Track Tags. Getting client area should be possible with Js_ReaScriptAPI extension.
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 11:54 AM.
|