예제 #1
0
        /// <summary>
        ///     Returns the monitor a window intersects with the most.
        /// </summary>
        /// <param name="window">The window calculate the monitor for.</param>
        /// <returns>The monitor which the window intersects with the most.</returns>
        public static unsafe Monitor *GetMonitorFromWindow(Window *window)
        {
            if (!CheckCache())
            {
                throw new Exception("This method can only be called from the main GLFW thread.");
            }

            Rectangle windowArea;
            {
                int windowX, windowY, windowWidth, windowHeight;
                GLFW.GetWindowPos(window, out windowX, out windowY);
                GLFW.GetWindowSize(window, out windowWidth, out windowHeight);
                windowArea = new Rectangle(windowX, windowY, windowWidth, windowHeight);
            }

            var selectedIndex = 0;

            for (var i = 0; i < _dpiInfos.Count; i++)
            {
                if (
                    GetRectangleIntersectionArea(_dpiInfos[i].ClientArea, windowArea) >
                    GetRectangleIntersectionArea(_dpiInfos[selectedIndex].ClientArea, windowArea)
                    )
                {
                    selectedIndex = i;
                }
            }

            return(_dpiInfos[selectedIndex].Handle);
        }
예제 #2
0
    // ImGui_ImplGlfw_GetWindowPos
    private static Vector2 GetWindowPosManaged(ImGuiViewport *viewport)
    {
        ViewportData *viewportData = (ViewportData *)viewport->PlatformUserData;

        GLFW.GetWindowPos(viewportData->Window, out int x, out int y);
        return(new Vector2((float)x, (float)y));
    }
예제 #3
0
        public static void ImGui_ImplGlfw_GetWindowPos(out Vector2 position, ImGuiViewportPtr viewport)
        {
            var window = GetWindow(viewport);

            GLFW.GetWindowPos(window, out int x, out int y);
            position = new Vector2(x, y);
        }
예제 #4
0
            private void WinThreadWinSetFullscreen(CmdWinSetFullscreen cmd)
            {
                var ptr = (Window *)cmd.Window;

                GLFW.GetWindowSize(ptr, out var w, out var h);
                GLFW.GetWindowPos(ptr, out var x, out var y);

                var monitor = MonitorForWindow(ptr);
                var mode    = GLFW.GetVideoMode(monitor);

                GLFW.SetWindowMonitor(
                    ptr,
                    monitor,
                    0, 0,
                    mode->Width, mode->Height,
                    mode->RefreshRate);
            }
예제 #5
0
    private static void SetWindowSize(ImGuiViewport *viewport, Vector2 size)
    {
        ViewportData *viewportData = (ViewportData *)viewport->PlatformUserData;

        if (NeedMacOsSetWindowSizeWorkaround)
        {
            // Native OS windows are positioned from the bottom-left corner on macOS, whereas on other platforms they are
            // positioned from the upper-left corner. GLFW makes an effort to convert macOS style coordinates, however it
            // doesn't handle it when changing size. We are manually moving the window in order for changes of size to be based
            // on the upper-left corner.
            GLFW.GetWindowPos(viewportData->Window, out int x, out int y);
            GLFW.GetWindowSize(viewportData->Window, out int width, out int height);
            GLFW.SetWindowPos(viewportData->Window, x, y - height + (int)size.Y);
        }

        viewportData->IgnoreWindowSizeEventFrame = ImGui.GetFrameCount();
        GLFW.SetWindowSize(viewportData->Window, (int)size.X, (int)size.Y);
    }
예제 #6
0
            private GlfwWindowReg WinThreadSetupWindow(Window *window)
            {
                var reg = new GlfwWindowReg
                {
                    GlfwWindow = window,
                    Id         = new WindowId(_nextWindowId++)
                };
                var handle = new WindowHandle(_clyde, reg);

                reg.Handle = handle;

                LoadWindowIcon(window);

                GLFW.SetCharCallback(window, _charCallback);
                GLFW.SetKeyCallback(window, _keyCallback);
                GLFW.SetWindowCloseCallback(window, _windowCloseCallback);
                GLFW.SetCursorPosCallback(window, _cursorPosCallback);
                GLFW.SetCursorEnterCallback(window, _cursorEnterCallback);
                GLFW.SetWindowSizeCallback(window, _windowSizeCallback);
                GLFW.SetWindowPosCallback(window, _windowPosCallback);
                GLFW.SetScrollCallback(window, _scrollCallback);
                GLFW.SetMouseButtonCallback(window, _mouseButtonCallback);
                GLFW.SetWindowContentScaleCallback(window, _windowContentScaleCallback);
                GLFW.SetWindowIconifyCallback(window, _windowIconifyCallback);
                GLFW.SetWindowFocusCallback(window, _windowFocusCallback);

                GLFW.GetFramebufferSize(window, out var fbW, out var fbH);
                reg.FramebufferSize = (fbW, fbH);

                GLFW.GetWindowContentScale(window, out var scaleX, out var scaleY);
                reg.WindowScale = (scaleX, scaleY);

                GLFW.GetWindowSize(window, out var w, out var h);
                reg.PrevWindowSize = reg.WindowSize = (w, h);

                GLFW.GetWindowPos(window, out var x, out var y);
                reg.PrevWindowPos = (x, y);

                reg.PixelRatio = reg.FramebufferSize / reg.WindowSize;

                return(reg);
            }
예제 #7
0
            // glfwGetWindowMonitor only works for fullscreen windows.
            // Picks the monitor with the top-left corner of the window.
            private Monitor *MonitorForWindow(Window *window)
            {
                GLFW.GetWindowPos(window, out var winPosX, out var winPosY);
                var monitors = GLFW.GetMonitorsRaw(out var count);

                for (var i = 0; i < count; i++)
                {
                    var monitor = monitors[i];
                    GLFW.GetMonitorPos(monitor, out var monPosX, out var monPosY);
                    var videoMode = GLFW.GetVideoMode(monitor);

                    var box = Box2i.FromDimensions(monPosX, monPosY, videoMode->Width, videoMode->Height);
                    if (box.Contains(winPosX, winPosY))
                    {
                        return(monitor);
                    }
                }

                // Fallback
                return(GLFW.GetPrimaryMonitor());
            }
예제 #8
0
            private Window *CreateGlfwWindowForRenderer(
                GLContextSpec?spec,
                WindowCreateParameters parameters,
                Window *contextShare,
                Window *ownerWindow)
            {
                GLFW.WindowHint(WindowHintString.X11ClassName, "RobustToolbox");
                GLFW.WindowHint(WindowHintString.X11InstanceName, "RobustToolbox");
                GLFW.WindowHint(WindowHintBool.ScaleToMonitor, true);

                if (spec == null)
                {
                    // No OpenGL context requested.
                    GLFW.WindowHint(WindowHintClientApi.ClientApi, ClientApi.NoApi);
                }
                else
                {
                    var s = spec.Value;

#if DEBUG
                    GLFW.WindowHint(WindowHintBool.OpenGLDebugContext, true);
#endif

                    GLFW.WindowHint(WindowHintInt.ContextVersionMajor, s.Major);
                    GLFW.WindowHint(WindowHintInt.ContextVersionMinor, s.Minor);
                    GLFW.WindowHint(WindowHintBool.OpenGLForwardCompat, s.Profile != GLContextProfile.Compatibility);
                    GLFW.WindowHint(WindowHintBool.SrgbCapable, true);

                    switch (s.Profile)
                    {
                    case GLContextProfile.Compatibility:
                        GLFW.WindowHint(WindowHintOpenGlProfile.OpenGlProfile, OpenGlProfile.Any);
                        GLFW.WindowHint(WindowHintClientApi.ClientApi, ClientApi.OpenGlApi);
                        break;

                    case GLContextProfile.Core:
                        GLFW.WindowHint(WindowHintOpenGlProfile.OpenGlProfile, OpenGlProfile.Core);
                        GLFW.WindowHint(WindowHintClientApi.ClientApi, ClientApi.OpenGlApi);
                        break;

                    case GLContextProfile.Es:
                        GLFW.WindowHint(WindowHintOpenGlProfile.OpenGlProfile, OpenGlProfile.Any);
                        GLFW.WindowHint(WindowHintClientApi.ClientApi, ClientApi.OpenGlEsApi);
                        break;
                    }

                    GLFW.WindowHint(WindowHintContextApi.ContextCreationApi,
                                    s.CreationApi == GLContextCreationApi.Egl
                            ? ContextApi.EglContextApi
                            : ContextApi.NativeContextApi);

#if !FULL_RELEASE
                    if (s.CreationApi == GLContextCreationApi.Egl && !_eglLoaded && OperatingSystem.IsWindows())
                    {
                        // On non-published builds (so, development), GLFW can't find libEGL.dll
                        // because it'll be in runtimes/<rid>/native/ instead of next to the actual executable.
                        // We manually preload the library here so that GLFW will find it when it does its thing.
                        NativeLibrary.TryLoad(
                            "libEGL.dll",
                            typeof(Clyde).Assembly,
                            DllImportSearchPath.SafeDirectories,
                            out _);

                        _eglLoaded = true;
                    }
#endif
                }

                Monitor *monitor = null;
                if (parameters.Monitor != null &&
                    _winThreadMonitors.TryGetValue(parameters.Monitor.Id, out var monitorReg))
                {
                    monitor = monitorReg.Ptr;
                    var mode = GLFW.GetVideoMode(monitor);
                    // Set refresh rate to monitor's so that GLFW doesn't manually select one.
                    GLFW.WindowHint(WindowHintInt.RefreshRate, mode->RefreshRate);
                }
                else
                {
                    GLFW.WindowHint(WindowHintInt.RefreshRate, -1);
                }

                GLFW.WindowHint(WindowHintBool.Visible, false);

                GLFW.WindowHint(WindowHintInt.RedBits, 8);
                GLFW.WindowHint(WindowHintInt.GreenBits, 8);
                GLFW.WindowHint(WindowHintInt.BlueBits, 8);
                GLFW.WindowHint(WindowHintInt.AlphaBits, 8);
                GLFW.WindowHint(WindowHintInt.StencilBits, 8);

                var window = GLFW.CreateWindow(
                    parameters.Width, parameters.Height,
                    parameters.Title,
                    parameters.Fullscreen ? monitor : null,
                    contextShare);

                // Check if window failed to create.
                if (window == null)
                {
                    return(null);
                }

                if (parameters.Maximized)
                {
                    GLFW.GetMonitorPos(monitor, out var x, out var y);
                    GLFW.SetWindowPos(window, x, y);
                    GLFW.MaximizeWindow(window);
                }

                if ((parameters.Styles & OSWindowStyles.NoTitleOptions) != 0)
                {
                    if (OperatingSystem.IsWindows())
                    {
                        var hWnd = (HWND)GLFW.GetWin32Window(window);
                        DebugTools.Assert(hWnd != HWND.NULL);

                        Windows.SetWindowLongPtrW(
                            hWnd,
                            GWL.GWL_STYLE,
                            // Cast to long here to work around a bug in rider with nint bitwise operators.
                            (nint)((long)Windows.GetWindowLongPtrW(hWnd, GWL.GWL_STYLE) & ~WS.WS_SYSMENU));
                    }
                    else
                    {
                        _sawmill.Warning("OSWindowStyles.NoTitleOptions not implemented on this platform");
                    }
                }

                if (ownerWindow != null)
                {
                    if (OperatingSystem.IsWindows())
                    {
                        var hWnd      = (HWND)GLFW.GetWin32Window(window);
                        var ownerHWnd = (HWND)GLFW.GetWin32Window(ownerWindow);
                        DebugTools.Assert(hWnd != HWND.NULL);

                        Windows.SetWindowLongPtrW(
                            hWnd,
                            GWLP.GWLP_HWNDPARENT,
                            ownerHWnd);
                    }
                    else
                    {
                        _sawmill.Warning("owner windows not implemented on this platform");
                    }


                    if (parameters.StartupLocation == WindowStartupLocation.CenterOwner)
                    {
                        // TODO: Maybe include window frames in size calculations here?
                        // Figure out frame sizes of both windows.
                        GLFW.GetWindowPos(ownerWindow, out var ownerX, out var ownerY);
                        GLFW.GetWindowSize(ownerWindow, out var ownerW, out var ownerH);

                        // Re-fetch this in case DPI scaling is changing it I guess.
                        GLFW.GetWindowSize(window, out var thisW, out var thisH);

                        GLFW.SetWindowPos(window, ownerX + (ownerW - thisW) / 2, ownerY + (ownerH - thisH) / 2);
                    }
                }

                if (parameters.Visible)
                {
                    GLFW.ShowWindow(window);
                }

                return(window);
            }