Как предотвратить переход окна моего приложения на другой монитор (Electron + macOS) - PullRequest
4 голосов
/ 08 апреля 2020

enter image description here

У меня есть приложение, которое программно перемещает свое окно по экрану пользователя. Моя проблема:

  1. У пользователя два физических монитора
  2. Пользователь запускает приложение на основном мониторе
  3. Приложение перемещает окно, в результате чего большая его часть «переполняется» на дополнительном мониторе монитор, который находится на основном мониторе
  4. Это заставляет окно приложения полностью перейти на этот дополнительный монитор и исчезнуть с основного монитора.

Я бы хотел, чтобы окно оставалось в основной монитор, если я не хочу, чтобы он был go для дополнительного монитора, или какая-то определенная точка (например, центр) переходит на дополнительный монитор, или было бы даже хорошо, если бы окно было разделено и отображалось на обоих. Есть ли способ предотвратить этот скачок, как только окно пересекается с дополнительным монитором?

Повторяю, я перемещаю окно программно и использую Electron на macOS.

Кроме того, этого не происходит, когда я перемещаю окно вручную, но я думаю, что это происходит потому, что он не использует свое процентное правило, а работает независимо от того, вошла ли точка мыши в дополнительный монитор.

Кроме того, я открыт для любого решения, включая C / C ++ или Swift.

РЕДАКТИРОВАТЬ: Вот как я сейчас перемещаю окно:

win.setPosition(x, y);

, где win это экземпляр Electron BrowserWindow.

. Требуемое поведение - переместить окно в любое место на дисплее. В настоящее время, если какое-то окно выходит за границы текущего дисплея, оно переходит к другому дисплею. Это связано с тем, что по умолчанию Apple использует автоматическое перемещение окна на экран, с которым оно перекрывается больше всего, и скрытие его на всех других дисплеях. Стоит отметить, что это не поведение при перетаскивании окна вручную, а только при его программном перемещении.

Ответы [ 3 ]

0 голосов
/ 14 апреля 2020

Это не работает, когда вы делаете win.setPosition(x, y); из-за поведения ОС c.
(Я также пытался с электронным проектом быстрого запуска https://github.com/electron/electron-quick-start, даже с той же электронной версией 6.0 .5)

Я программно смоделировал перетаскивание мышью вашего приложения в правой части экрана. Для этого вы можете использовать робот js. Вы не увидите эффект перетаскивания, который довольно близок к выполнению setPosition (x, y)
Когда вы устанавливаете его, у вас могут возникнуть проблемы при запуске приложения. Затем вам нужно пересобрать ребут JS для вашей версии электрона. https://github.com/octalmage/robotjs/wiki/Electron

То, что вы попытаетесь сделать программно, это:

enter image description here

Рабочий код

      // get your app bounds and screen bounds
      const windowBounds = mainWindow.getBounds()                         
      const displayBounds = electron.screen.getPrimaryDisplay().bounds   

      setTimeout(() => {                                                  
        // 1. move mouse upon the top left corner your app
        robot.moveMouse(windowBounds.x + 100, windowBounds.y + 5);        
        // 2. mouse left key, 'down'
        robot.mouseToggle("down", "left");                               
        // 3. drag window to (100, 100) from default 
        robot.dragMouse(displayBounds.width, 0);                         
        // 4. mouse left key toggle 'up'
        robot.mouseToggle("up", "left");                                 
      }, 100);

Пример в основном. js: https://playcode.io/electron

Я использую эти версии:

  "devDependencies": {
    "electron": "^6.0.5"
  },
  "dependencies": {
    "robotjs": "^0.6.0"
  }

и мой муссон nodejs v10.20.0

0 голосов
/ 17 апреля 2020

Может быть, это не совсем то, что вы просили, но вот мысль: почему бы не изменить размер окна, вместо того, чтобы оно «переполнялось» на другие экраны?

Когда вы прогнозируете, что окно будет go выходить за границы текущего отображения, просто уменьшите его размер.

Это может быть сделано с помощью чего-то такого:

const winWidth = 800;
const winHeight = 600;

const SAFETY_MARGINS = 10;

let mainWindow;

// setPosition //////////////////////////////////////////////////////////////////////////

function setPosition(x, y) {
  const displayBounds = screen.getPrimaryDisplay().bounds
  const fixedX = Math.min(
    displayBounds.x + displayBounds.width,
    Math.max(x, displayBounds.x)
  );
  const fixedY = Math.min(
    displayBounds.y + displayBounds.height,
    Math.max(y, displayBounds.y)
  );
  mainWindow.setPosition(fixedX, fixedY);

  const fixedWidth = Math.max(SAFETY_MARGINS, Math.min(winWidth, displayBounds.width + displayBounds.x - x, winWidth - displayBounds.x + x));
  const fixedHeight = Math.max(SAFETY_MARGINS, Math.min(winHeight, displayBounds.height + displayBounds.y - y, winHeight - displayBounds.y + y));
  mainWindow.setSize(fixedWidth, fixedHeight);
}

Эта версия setPosition всегда будет изменять размер вашего окна, чтобы оно выиграло ' t go за пределами экрана.

Вы можете изменить / расширить его, чтобы разрешить окну немного выходить за пределы go и прокручивать содержимое окна (при необходимости).

I Поверьте, что при некоторых настройках для большинства пользователей изменение размера и перемещение окна чуть-чуть за пределы экрана будет более или менее похоже на фактическое перемещение окна за пределы экрана.

Вот демонстрационная программа, перемещающая окно случайным образом с использованием этот код: https://github.com/yoava/so-61092503

(я не тестировал с двумя экранами, так как сейчас я только с моим ноутбуком.)

0 голосов
/ 11 апреля 2020

Я не знаю, как вы перемещаете это окно, или как вы хотите, чтобы окно действовало, когда оно достигает края, но я сделаю все возможное, чтобы дать вам некоторые решения.

Моя первая мысль был для вас, чтобы создать границы экрана при запуске программы. Поэтому, возможно, используйте GetSystemMetrics () , screen.getPrimaryDisplay () , или, возможно, этот псевдокод поможет:

var canvas = GetWindowSize()
var canvasWidth = canvas.width
var canvasHeight = canvas.height
if myWindow.x  + mywindow.width > canvasWidth
//if you want it to bounce off the edge
then myWindow.direction = oppositeDirection 
//if you want it to wrap to the other side of the screen
then myWindow.X -= canvasWidth

Вы должны проверить этот код прыгающий DVD Lo go. Или посмотрите на мою игру Астероиды , чтобы увидеть, как движутся корабли и астероиды на экране.

Кроме того, вы можете использовать формулу расстояния , чтобы окно реагировало на край, когда центр приближается. (Хотя это также потребовало бы, чтобы вы получили границы экрана x и y.)

Надеюсь, это поможет!

РЕДАКТИРОВАТЬ: Я думаю, что если вы как-то использовать весь экран, (оба мониторы) ваше окно даже не узнает, что есть преимущество. При этом я до сих пор не знаю, что на самом деле делает ваш код.

...