C++ 如何防止我的应用程序';从s窗口转到另一个监视器(Electron&x2B;macOS)

C++ 如何防止我的应用程序';从s窗口转到另一个监视器(Electron&x2B;macOS),c++,swift,macos,electron,core-graphics,C++,Swift,Macos,Electron,Core Graphics,我有一个应用程序,可以通过编程在用户屏幕上移动窗口。我的问题是: 用户有两个物理监视器 用户在主监视器中启动应用程序 应用程序移动窗口,导致更多窗口“溢出”到辅助监视器中,而不是主监视器上 这会导致应用程序的窗口完全跳转到辅助监视器,并从主监视器中消失 我希望窗口保持在主监视器中,除非我希望它转到辅助监视器,或者某个定义点(例如,中心)进入辅助监视器,或者如果窗口被拆分并显示在两个监视器上,则它甚至可以。当窗口与辅助监视器相交更多时,是否有任何方法可以防止此跳转发生 重申一下,我正在以编程方式移

我有一个应用程序,可以通过编程在用户屏幕上移动窗口。我的问题是:

  • 用户有两个物理监视器
  • 用户在主监视器中启动应用程序
  • 应用程序移动窗口,导致更多窗口“溢出”到辅助监视器中,而不是主监视器上
  • 这会导致应用程序的窗口完全跳转到辅助监视器,并从主监视器中消失
  • 我希望窗口保持在主监视器中,除非我希望它转到辅助监视器,或者某个定义点(例如,中心)进入辅助监视器,或者如果窗口被拆分并显示在两个监视器上,则它甚至可以。当窗口与辅助监视器相交更多时,是否有任何方法可以防止此跳转发生

    重申一下,我正在以编程方式移动窗口,并在macOS上使用Electron

    此外,当我手动移动窗口时,这似乎不会发生,但我认为这是因为它没有使用其百分比规则,而是在鼠标点是否已进入辅助监视器时进行

    此外,我对任何类型的解决方案都持开放态度,包括C/C++或Swift

    编辑:以下是我当前移动窗口的方式:

    win.setPosition(x, y);
    
    其中
    win
    是Electron的
    浏览器窗口的一个实例


    所需的行为是将窗口移动到显示器上的任何位置。当前,如果某些窗口离开当前显示的边缘足够远,它将跳转到另一个显示。这是因为苹果的默认行为允许它自动将窗口移动到与之重叠最多的显示器上,并将其隐藏在所有其他显示器上。值得注意的是,这不是手动拖动窗口时的行为,而是以编程方式移动窗口时的行为。

    我不知道您如何移动此窗口,也不知道您希望窗口在碰到边缘时如何操作,但我将尽我所能为您提供一些解决方案

    我的第一个想法是在程序启动时创建屏幕边界。 因此,也许可以使用,或者这个伪代码有助于:

    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
    
    你应该检查一下这段代码。 或者看看我的照片,看看飞船和小行星是如何在屏幕上移动的

    此外,可以使用使窗口在接近中心时对边缘作出反应。(尽管如此,这也需要获得屏幕边界x和y。)

    希望有帮助

    编辑:
    我认为,如果你使用整个屏幕(两个显示器),你的窗口甚至不会意识到有一个边缘。话虽如此,我仍然不知道你的代码实际上做了什么。

    当你赢了
    win.setPosition(x,y)由于mac OS的行为。
    (我还尝试了electron quick start项目,即使是相同的electron版本6.0.5)

    我所做的是以编程方式模拟将应用程序的鼠标拖动到屏幕右侧。要做到这一点,你可以使用。您将看不到拖动效果,这与设置位置(x,y)非常接近
    当你安装它时,你可能会在启动应用程序时遇到问题。然后,您必须为您的electron版本重建RebootJS

    因此,您将尝试以编程方式执行以下操作:

    工作代码 main.js中的示例: 我使用这些版本:

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

    我的nodejs版本是v10.20.0

    也许这不是你想要的,但我有一个想法:为什么不调整窗口大小,而不是让它“溢出”到其他屏幕

    当您预测窗口将超出当前显示范围时,只需减小其大小

    可以通过以下方法实现:

    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
    将始终调整窗口大小,使其不会超出显示边界

    您可以修改/扩展它以允许窗口稍微超出边界并滚动窗口的内容(如果需要)

    我相信,通过一些调整,对于大多数用户来说,调整窗口大小并将其稍微移出屏幕,看起来或多或少会像是将窗口移出屏幕

    下面是一个使用以下代码随机移动窗口的演示:


    (我没有使用双屏幕进行测试,因为我现在只使用笔记本电脑。)

    您能展示一下如何通过编程方式移动窗口的代码吗?我想这就是修复的地方。刚刚添加了代码片段。你使用的是什么版本的Electron?版本是6.0.5>,这是因为苹果的默认行为是自动将窗口移动到与它重叠最多的显示器上,并将其隐藏在所有其他显示器上。作为一个用户,有人知道如何禁用这种行为吗?我不太想检测边缘。我试图在显示器上的任何地方移动我的窗口。在我上传的图像中,我希望窗口能够保持在该场景中的主显示中。根据图像中的显示布局,A)我的窗口中心不可能位于主显示器的右上角,B)窗口不可能跳转到辅助显示器。这是因为苹果的默认行为是将一个窗口跳转到与之相交最多的显示器上,并对所有其他窗口进行隐藏(当以编程方式移动时)。
    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);
    }