prevent windows from opening offscreen

Need help with a script? This is the place to discuss how to get your code running!

prevent windows from opening offscreen

Postby taroface » Fri Oct 06, 2017 8:38 am

There must be an obvious solution to this, but I can't find it in search...

How would one detect that most/all of a window has opened offscreen, and automatically adjust its position to place its edge at the border? I don't want to default to using screenLoc as I don't want too many windows to pile up there.

Thanks for any help...!
taroface
 
Posts: 4
Joined: Sun Jul 30, 2017 2:02 pm

Re: prevent windows from opening offscreen

Postby codegreen » Fri Oct 06, 2017 10:21 am

Depending on whether you want to move your wd if it's mostly or just partially offscreen (and assuming it will actually fit), one of these should help:

Code: Select all
on openWindow
  if not windowIsMostlyVisible() then pinWindow
  -- if not wdIsCompletelyVisible() then pinWindow
end openWindow

function windowIsMostlyVisible
  local sr = the screenRect
  if vis of menuBar then add 45 to item 2 of sr
  return the loc of this wd = pinRect(sr, the loc of this wd)
end windowIsMostlyVisible

function wdIsCompletelyVisible
  local sr = the screenRect, tl = the topLeft of this wd, br = the botRight of this wd
  if vis of menuBar then add 45 to item 2 of sr
  return tl = pinRect(sr, tl) and br = pinRect(sr, br)
end wdIsCompletelyVisible

on pinWindow
  local sr = the screenRect
  if vis of menuBar then add 45 to item 2 of sr
  enum l = item 1 of sr, t = item 2 of sr, r = item 3 of sr, b = item 4 of sr
  hide this wd
  if the left of this wd < l then set the left of this wd to l + 1
  if the top of this wd < t then set the top of this wd to t + 1
  if the right of this wd > r then set the right of this wd to r - 1
  if the bottom of this wd > b then set the bottom of this wd to b - 1
  show this wd
end pinWindow

If you have multiple monitors and you want to change the top 'pin' value depending on whether the window is on a monitor that has a menu bar, I think that might require an external...

-Mark
codegreen
 
Posts: 1490
Joined: Mon Jul 14, 2008 11:03 pm

Re: prevent windows from opening offscreen

Postby codegreen » Fri Oct 06, 2017 2:27 pm

Some minor tweaks to the above:

Code: Select all
on pinWindow
  local sr = availableBounds()
  enum l = item 1 of sr, t = item 2 of sr, r = item 3 of sr, b = item 4 of sr
  hide this wd
  if the left of this wd < l then set the left of this wd to l + 1
  if the top of this wd < t then set the top of this wd to t + 1
  if the right of this wd > r then set the right of this wd to r - 1
  if the bottom of this wd > b then set the bottom of this wd to b - 1
  show this wd
end pinWindow

function windowIsMostlyVisible
  return the loc of this wd = pinRect(availableBounds(), the loc of this wd)
end windowIsMostlyVisible

function wdIsCompletelyVisible
  local r = availableBounds(), tl = the topLeft of this wd, br = the botRight of this wd
  return tl = pinRect(r, tl) and br = pinRect(r, br)
end wdIsCompletelyVisible

function availableBounds
  local r = the screenRect
  add iif(vis of menuBar and screenRect(1) = r, 43, 22) to item 2 of r
  return r
end availableBounds

It should now properly position standard windows on all displays (whether they contain the menu bar or not). If your client has no title bar, you'll want to adjust availableBounds accordingly. You could add a function easily enough automate that calculation based on the window type too if you feel frisky...

HTH,
-Mark
codegreen
 
Posts: 1490
Joined: Mon Jul 14, 2008 11:03 pm

Re: prevent windows from opening offscreen

Postby codegreen » Fri Oct 06, 2017 3:01 pm

Or even better:

Code: Select all
on pinWindow
  local sr = the maximumRect of this wd
  enum l = item 1 of sr, t = item 2 of sr, r = item 3 of sr, b = item 4 of sr
  hide this wd
  if the left of this wd < l then set the left of this wd to l
  if the top of this wd < t then set the top of this wd to t
  if the right of this wd > r then set the right of this wd to r
  if the bottom of this wd > b then set the bottom of this wd to b
  show this wd
end pinWindow

function windowIsMostlyVisible
  return the loc of this wd = pinRect(the maximumRect of this wd, the loc of this wd)
end windowIsMostlyVisible

function wdIsCompletelyVisible
  local r = the maximumRect of this wd, tl = the topLeft of this wd, ¬
    br = the botRight of this wd
  return tl = pinRect(r, tl) and br = pinRect(r, br)
end wdIsCompletelyVisible

I totally forgot that handy property existed...

:oops:
-Mark
codegreen
 
Posts: 1490
Joined: Mon Jul 14, 2008 11:03 pm

Re: prevent windows from opening offscreen

Postby codegreen » Fri Oct 06, 2017 4:12 pm

This is all well and good I suppose, but it still feels too clever by half for something xtalk scripters might commonly need to do (i.e., constrain a window to the screen). And it doesn't even account for the obvious edge case of a window being too big to fit without resizing...

So I just added a command to automate it all:

Code: Select all
  constrain <wdDesc> [to [main] monitor|screen [<index>]]

This breaks down to four forms:

Code: Select all
  constrain <wdDesc>

  constrain <wdDesc> to monitor|screen

  constrain <wdDesc> to main monitor|screen

  constrain <wdDesc> to monitor|screen <monitorNumber>

The device specifier is optional, but you can add to monitor|screen for readability even if you just want the default. If none is supplied, the device that contains the largest portion of the window (or if the window is completely offscreen, the one with the menu bar) is used.

You can specify the target device using either main or its one-based index (i.e., monitor <N>).

The window's structure widths (which vary by OS version) are automatically accounted for. If the window is too big to fit, it will be resized.

If the window is already contained entirely on one display, the command does nothing.

The target window must be open for this all to work. If it's not then no script error is thrown, but the command is ignored and the result is set to "Window not open."

HTH,
-Mark
codegreen
 
Posts: 1490
Joined: Mon Jul 14, 2008 11:03 pm

Re: prevent windows from opening offscreen

Postby taroface » Mon Oct 09, 2017 3:07 pm

Amazing, thank you very much! I’ll try this out soon :)
taroface
 
Posts: 4
Joined: Sun Jul 30, 2017 2:02 pm


Return to Scripting in SuperTalk

Who is online

Users browsing this forum: No registered users and 1 guest

cron