mirror of
				https://github.com/glfw/glfw.git
				synced 2025-10-31 04:32:26 +00:00 
			
		
		
		
	Add glfwSetWindowMonitor
This adds the ability to switch between windowed and full screen modes, move a full screen window between monitors and update its desired resolution and refresh rate. Fixes #43.
This commit is contained in:
		
							parent
							
								
									fb8a31ba3f
								
							
						
					
					
						commit
						6570d0c4b7
					
				| @ -77,6 +77,8 @@ does not find Doxygen, the documentation will not be generated. | ||||
|  - Added `glfwVulkanSupported`, `glfwGetRequiredInstanceExtensions`, | ||||
|    `glfwGetInstanceProcAddress`, `glfwGetPhysicalDevicePresentationSupport` and | ||||
|    `glfwCreateWindowSurface` for platform independent Vulkan support | ||||
|  - Added `glfwSetWindowMonitor` for switching between windowed and full screen | ||||
|    modes and updating the monitor and desired video mode of full screen windows | ||||
|  - Added `glfwMaximizeWindow` and `GLFW_MAXIMIZED` for window maximization | ||||
|  - Added `glfwFocusWindow` for giving windows input focus | ||||
|  - Added `glfwSetWindowSizeLimits` and `glfwSetWindowAspectRatio` for setting | ||||
|  | ||||
| @ -95,8 +95,9 @@ a gamma ramp. | ||||
| @subsection monitor_modes Video modes | ||||
| 
 | ||||
| GLFW generally does a good job selecting a suitable video mode when you create | ||||
| a full screen window, but it is sometimes useful to know exactly which video | ||||
| modes are supported. | ||||
| a full screen window, change its video mode or or make a windowed one full | ||||
| screen, but it is sometimes useful to know exactly which video modes are | ||||
| supported. | ||||
| 
 | ||||
| Video modes are represented as @ref GLFWvidmode structures.  You can get an | ||||
| array of the video modes supported by a monitor with @ref glfwGetVideoModes. | ||||
|  | ||||
| @ -26,6 +26,13 @@ Vulkan header inclusion can be selected with | ||||
| [GLFW_INCLUDE_VULKAN](@ref build_macros). | ||||
| 
 | ||||
| 
 | ||||
| @subsection news_32_setwindowmonitor Window mode switching | ||||
| 
 | ||||
| GLFW now supports switching between windowed and full screen modes and updating | ||||
| the monitor and desired resolution and refresh rate of full screen windows with | ||||
| @ref glfwSetWindowMonitor. | ||||
| 
 | ||||
| 
 | ||||
| @subsection news_32_maximize Window maxmimization support | ||||
| 
 | ||||
| GLFW now supports window maximization with @ref glfwMaximizeWindow and the | ||||
|  | ||||
| @ -56,6 +56,10 @@ GLFWwindow* window = glfwCreateWindow(640, 480, "My Title", glfwGetPrimaryMonito | ||||
| Full screen windows cover the entire display area of a monitor, have no border | ||||
| or decorations. | ||||
| 
 | ||||
| Windowed mode windows can be made full screen by setting a monitor with @ref | ||||
| glfwSetWindowMonitor, and full screen ones can be made windowed by unsetting it | ||||
| with the same function. | ||||
| 
 | ||||
| Each field of the @ref GLFWvidmode structure corresponds to a function parameter | ||||
| or window hint and combine to form the _desired video mode_ for that window. | ||||
| The supported video mode most closely matching the desired video mode will be | ||||
| @ -71,9 +75,11 @@ GLFWvidmode.greenBits   | `GLFW_GREEN_BITS` hint | ||||
| GLFWvidmode.blueBits    | `GLFW_BLUE_BITS` hint | ||||
| GLFWvidmode.refreshRate | `GLFW_REFRESH_RATE` hint | ||||
| 
 | ||||
| Once you have a full screen window, you can change its resolution with @ref | ||||
| glfwSetWindowSize.  The new video mode will be selected and set the same way as | ||||
| the video mode chosen by @ref glfwCreateWindow. | ||||
| Once you have a full screen window, you can change its resolution, refresh rate | ||||
| and monitor with @ref glfwSetWindowMonitor.  If you just need change its | ||||
| resolution you can also call @ref glfwSetWindowSize.  In all cases, the new | ||||
| video mode will be selected the same way as the video mode chosen by @ref | ||||
| glfwCreateWindow. | ||||
| 
 | ||||
| By default, the original video mode of the monitor will be restored and the | ||||
| window iconified if it loses input focus, to allow the user to switch back to | ||||
| @ -101,6 +107,18 @@ glfwWindowHint(GLFW_REFRESH_RATE, mode->refreshRate); | ||||
| GLFWwindow* window = glfwCreateWindow(mode->width, mode->height, "My Title", monitor, NULL); | ||||
| @endcode | ||||
| 
 | ||||
| This also works for windowed mode windows that are made full screen. | ||||
| 
 | ||||
| @code | ||||
| const GLFWvidmode* mode = glfwGetVideoMode(monitor); | ||||
| 
 | ||||
| glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate); | ||||
| @endcode | ||||
| 
 | ||||
| Note that @ref glfwGetVideoMode returns the _current_ video mode of a monitor, | ||||
| so if you already have a full screen window on that monitor that you want to | ||||
| make windowed full screen, you need to have saved the desktop resolution before. | ||||
| 
 | ||||
| 
 | ||||
| @subsection window_destruction Window destruction | ||||
| 
 | ||||
| @ -423,7 +441,7 @@ glfwSetWindowSize(window, 640, 480); | ||||
| @endcode | ||||
| 
 | ||||
| For full screen windows, the specified size becomes the new resolution of the | ||||
| window's *desired video mode*.  The video mode most closely matching the new | ||||
| window's desired video mode.  The video mode most closely matching the new | ||||
| desired video mode is set immediately.  The window is resized to fit the | ||||
| resolution of the set video mode. | ||||
| 
 | ||||
| @ -648,8 +666,31 @@ GLFWmonitor* monitor = glfwGetWindowMonitor(window); | ||||
| 
 | ||||
| This monitor handle is one of those returned by @ref glfwGetMonitors. | ||||
| 
 | ||||
| For windowed mode windows, this function returns `NULL`.  This is the | ||||
| recommended way to tell full screen windows from windowed mode windows. | ||||
| For windowed mode windows, this function returns `NULL`.  This is how to tell | ||||
| full screen windows from windowed mode windows. | ||||
| 
 | ||||
| You can move windows between monitors or between full screen and windowed mode | ||||
| with @ref glfwSetWindowMonitor.  When making a window full screen on the same or | ||||
| on a different monitor, specify the desired monitor, resolution and refresh | ||||
| rate.  The position arguments are ignored. | ||||
| 
 | ||||
| @code | ||||
| const GLFWvidmode* mode = glfwGetVideoMode(monitor); | ||||
| 
 | ||||
| glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate); | ||||
| @endcode | ||||
| 
 | ||||
| When making the window windowed, specify the desired position and size.  The | ||||
| refresh rate argument is ignored. | ||||
| 
 | ||||
| @code | ||||
| glfwSetWindowMonitor(window, NULL, xpos, ypos, width, height, 0); | ||||
| @endcode | ||||
| 
 | ||||
| This restores any previous window settings such as whether it is decorated, | ||||
| floating, resizable, has size or aspect ratio limits, etc..  To restore a window | ||||
| that was originally windowed to its original size and position, save these | ||||
| before making it full screen and then pass them in as above. | ||||
| 
 | ||||
| 
 | ||||
| @subsection window_iconify Window iconification | ||||
|  | ||||
| @ -89,6 +89,7 @@ typedef enum { DRAW_BALL, DRAW_BALL_SHADOW } DRAW_BALL_ENUM; | ||||
| typedef struct {float x; float y; float z;} vertex_t; | ||||
| 
 | ||||
| /* Global vars */ | ||||
| int windowed_xpos, windowed_ypos, windowed_width, windowed_height; | ||||
| int width, height; | ||||
| GLfloat deg_rot_y       = 0.f; | ||||
| GLfloat deg_rot_y_inc   = 2.f; | ||||
| @ -238,6 +239,26 @@ void key_callback( GLFWwindow* window, int key, int scancode, int action, int mo | ||||
| { | ||||
|     if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) | ||||
|         glfwSetWindowShouldClose(window, GLFW_TRUE); | ||||
|     if (key == GLFW_KEY_ENTER && action == GLFW_PRESS && mods == GLFW_MOD_ALT) | ||||
|     { | ||||
|         if (glfwGetWindowMonitor(window)) | ||||
|         { | ||||
|             glfwSetWindowMonitor(window, NULL, | ||||
|                                  windowed_xpos, windowed_ypos, | ||||
|                                  windowed_width, windowed_height, 0); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             GLFWmonitor* monitor = glfwGetPrimaryMonitor(); | ||||
|             if (monitor) | ||||
|             { | ||||
|                 const GLFWvidmode* mode = glfwGetVideoMode(monitor); | ||||
|                 glfwGetWindowPos(window, &windowed_xpos, &windowed_ypos); | ||||
|                 glfwGetWindowSize(window, &windowed_width, &windowed_height); | ||||
|                 glfwSetWindowMonitor(window, monitor, 0, 0, mode->width, mode->height, mode->refreshRate); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| static void set_ball_pos ( GLfloat x, GLfloat y ) | ||||
|  | ||||
| @ -1718,17 +1718,17 @@ GLFWAPI void glfwWindowHint(int hint, int value); | ||||
|  *  glfwGetWindowAttrib, @ref glfwGetWindowSize and @ref glfwGetFramebufferSize. | ||||
|  * | ||||
|  *  To create a full screen window, you need to specify the monitor the window | ||||
|  *  will cover.  If no monitor is specified, windowed mode will be used.  Unless | ||||
|  *  you have a way for the user to choose a specific monitor, it is recommended | ||||
|  *  that you pick the primary monitor.  For more information on how to query | ||||
|  *  connected monitors, see @ref monitor_monitors. | ||||
|  *  will cover.  If no monitor is specified, the window will be windowed mode. | ||||
|  *  Unless you have a way for the user to choose a specific monitor, it is | ||||
|  *  recommended that you pick the primary monitor.  For more information on how | ||||
|  *  to query connected monitors, see @ref monitor_monitors. | ||||
|  * | ||||
|  *  For full screen windows, the specified size becomes the resolution of the | ||||
|  *  window's _desired video mode_.  As long as a full screen window has input | ||||
|  *  focus, the supported video mode most closely matching the desired video mode | ||||
|  *  is set for the specified monitor.  For more information about full screen | ||||
|  *  windows, including the creation of so called _windowed full screen_ or | ||||
|  *  _borderless full screen_ windows, see @ref window_windowed_full_screen. | ||||
|  *  window's _desired video mode_.  As long as a full screen window is not | ||||
|  *  iconified, the supported video mode most closely matching the desired video | ||||
|  *  mode is set for the specified monitor.  For more information about full | ||||
|  *  screen windows, including the creation of so called _windowed full screen_ | ||||
|  *  or _borderless full screen_ windows, see @ref window_windowed_full_screen. | ||||
|  * | ||||
|  *  By default, newly created windows use the placement recommended by the | ||||
|  *  window system.  To create the window at a specific position, make it | ||||
| @ -1736,8 +1736,8 @@ GLFWAPI void glfwWindowHint(int hint, int value); | ||||
|  *  hint, set its [position](@ref window_pos) and then [show](@ref window_hide) | ||||
|  *  it. | ||||
|  * | ||||
|  *  If a full screen window has input focus, the screensaver is prohibited from | ||||
|  *  starting. | ||||
|  *  As long as at least one full screen window is not iconified, the screensaver | ||||
|  *  is prohibited from starting. | ||||
|  * | ||||
|  *  Window systems put limits on window sizes.  Very large or very small window | ||||
|  *  dimensions may be overridden by the window system on creation.  Check the | ||||
| @ -1751,7 +1751,7 @@ GLFWAPI void glfwWindowHint(int hint, int value); | ||||
|  *  @param[in] height The desired height, in screen coordinates, of the window. | ||||
|  *  This must be greater than zero. | ||||
|  *  @param[in] title The initial, UTF-8 encoded window title. | ||||
|  *  @param[in] monitor The monitor to use for full screen mode, or `NULL` to use | ||||
|  *  @param[in] monitor The monitor to use for full screen mode, or `NULL` for | ||||
|  *  windowed mode. | ||||
|  *  @param[in] share The window whose context to share resources with, or `NULL` | ||||
|  *  to not share resources. | ||||
| @ -2044,11 +2044,12 @@ GLFWAPI void glfwGetWindowSize(GLFWwindow* window, int* width, int* height); | ||||
| /*! @brief Sets the size limits of the specified window.
 | ||||
|  * | ||||
|  *  This function sets the size limits of the client area of the specified | ||||
|  *  window.  If the window is full screen or not resizable, this function does | ||||
|  *  nothing. | ||||
|  *  window.  If the window is full screen, the size limits only take effect if | ||||
|  *  once it is made windowed.  If the window is not resizable, this function | ||||
|  *  does nothing. | ||||
|  * | ||||
|  *  The size limits are applied immediately and may cause the window to be | ||||
|  *  resized. | ||||
|  *  The size limits are applied immediately to a windowed mode window and may | ||||
|  *  cause it to be resized. | ||||
|  * | ||||
|  *  @param[in] window The window to set limits for. | ||||
|  *  @param[in] minwidth The minimum width, in screen coordinates, of the client | ||||
| @ -2080,7 +2081,8 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe | ||||
| /*! @brief Sets the aspect ratio of the specified window.
 | ||||
|  * | ||||
|  *  This function sets the required aspect ratio of the client area of the | ||||
|  *  specified window.  If the window is full screen or not resizable, this | ||||
|  *  specified window.  If the window is full screen, the aspect ratio only takes | ||||
|  *  effect once it is made windowed.  If the window is not resizable, this | ||||
|  *  function does nothing. | ||||
|  * | ||||
|  *  The aspect ratio is specified as a numerator and a denominator and both | ||||
| @ -2090,8 +2092,8 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* window, int minwidth, int minhe | ||||
|  *  If the numerator and denominator is set to `GLFW_DONT_CARE` then the aspect | ||||
|  *  ratio limit is disabled. | ||||
|  * | ||||
|  *  The aspect ratio is applied immediately and may cause the window to be | ||||
|  *  resized. | ||||
|  *  The aspect ratio is applied immediately to a windowed mode window and may | ||||
|  *  cause it to be resized. | ||||
|  * | ||||
|  *  @param[in] window The window to set limits for. | ||||
|  *  @param[in] numer The numerator of the desired aspect ratio, or | ||||
| @ -2121,17 +2123,22 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); | ||||
|  *  This function sets the size, in screen coordinates, of the client area of | ||||
|  *  the specified window. | ||||
|  * | ||||
|  *  For full screen windows, this function selects and switches to the resolution | ||||
|  *  closest to the specified size, without affecting the window's context.  As | ||||
|  *  the context is unaffected, the bit depths of the framebuffer remain | ||||
|  *  unchanged. | ||||
|  *  For full screen windows, this function updates the resolution of its desired | ||||
|  *  video mode and switches to the video mode closest to it, without affecting | ||||
|  *  the window's context.  As the context is unaffected, the bit depths of the | ||||
|  *  framebuffer remain unchanged. | ||||
|  * | ||||
|  *  If you wish to update the refresh rate of the desired video mode in addition | ||||
|  *  to its resolution, see @ref glfwSetWindowMonitor. | ||||
|  * | ||||
|  *  The window manager may put limits on what sizes are allowed.  GLFW cannot | ||||
|  *  and should not override these limits. | ||||
|  * | ||||
|  *  @param[in] window The window to resize. | ||||
|  *  @param[in] width The desired width of the specified window. | ||||
|  *  @param[in] height The desired height of the specified window. | ||||
|  *  @param[in] width The desired width, in screen coordinates, of the window | ||||
|  *  client area. | ||||
|  *  @param[in] height The desired height, in screen coordinates, of the window | ||||
|  *  client area. | ||||
|  * | ||||
|  *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref | ||||
|  *  GLFW_PLATFORM_ERROR. | ||||
| @ -2140,6 +2147,7 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* window, int numer, int denom); | ||||
|  * | ||||
|  *  @sa @ref window_size | ||||
|  *  @sa glfwGetWindowSize | ||||
|  *  @sa glfwSetWindowMonitor | ||||
|  * | ||||
|  *  @since Added in version 1.0. | ||||
|  *  @glfw3 Added window handle parameter. | ||||
| @ -2376,6 +2384,7 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* window); | ||||
|  *  @thread_safety This function must only be called from the main thread. | ||||
|  * | ||||
|  *  @sa @ref window_monitor | ||||
|  *  @sa glfwSetWindowMonitor | ||||
|  * | ||||
|  *  @since Added in version 3.0. | ||||
|  * | ||||
| @ -2383,6 +2392,54 @@ GLFWAPI void glfwFocusWindow(GLFWwindow* window); | ||||
|  */ | ||||
| GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* window); | ||||
| 
 | ||||
| /*! @brief Sets the mode, monitor, video mode and placement of a window.
 | ||||
|  * | ||||
|  *  This function sets the monitor that the window uses for full screen mode or, | ||||
|  *  if the monitor is `NULL`, makes it windowed mode. | ||||
|  * | ||||
|  *  When setting a monitor, this function updates the width, height and refresh | ||||
|  *  rate of the desired video mode and switches to the video mode closest to it. | ||||
|  *  The window position is ignored when setting a monitor. | ||||
|  * | ||||
|  *  When the monitor is `NULL`, the position, width and height are used to | ||||
|  *  place the window client area.  The refresh rate is ignored when no monitor | ||||
|  *  is specified. | ||||
|  * | ||||
|  *  If you only wish to update the resolution of a full screen window or the | ||||
|  *  size of a windowed mode window, see @ref glfwSetWindowSize. | ||||
|  * | ||||
|  *  When a window transitions from full screen to windowed mode, this function | ||||
|  *  restores any previous window settings such as whether it is decorated, | ||||
|  *  floating, resizable, has size or aspect ratio limits, etc.. | ||||
|  * | ||||
|  *  @param[in] window The window whose monitor, size or video mode to set. | ||||
|  *  @param[in] monitor The desired monitor, or `NULL` to set windowed mode. | ||||
|  *  @param[in] xpos The desired x-coordinate of the upper-left corner of the | ||||
|  *  client area. | ||||
|  *  @param[in] ypos The desired y-coordinate of the upper-left corner of the | ||||
|  *  client area. | ||||
|  *  @param[in] width The desired with, in screen coordinates, of the client area | ||||
|  *  or video mode. | ||||
|  *  @param[in] height The desired height, in screen coordinates, of the client | ||||
|  *  area or video mode. | ||||
|  *  @param[in] refreshRate The desired refresh rate, in Hz, of the video mode. | ||||
|  * | ||||
|  *  @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref | ||||
|  *  GLFW_PLATFORM_ERROR. | ||||
|  * | ||||
|  *  @thread_safety This function must only be called from the main thread. | ||||
|  * | ||||
|  *  @sa @ref window_monitor | ||||
|  *  @sa @ref window_full_screen | ||||
|  *  @sa glfwGetWindowMonitor | ||||
|  *  @sa glfwSetWindowSize | ||||
|  * | ||||
|  *  @since Added in version 3.2. | ||||
|  * | ||||
|  *  @ingroup window | ||||
|  */ | ||||
| GLFWAPI void glfwSetWindowMonitor(GLFWwindow* window, GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate); | ||||
| 
 | ||||
| /*! @brief Returns an attribute of the specified window.
 | ||||
|  * | ||||
|  *  This function returns the value of an attribute of the specified window or | ||||
|  | ||||
| @ -56,6 +56,26 @@ static NSCursor* getStandardCursor(int shape) | ||||
|     return nil; | ||||
| } | ||||
| 
 | ||||
| // Returns the style mask corresponding to the window settings | ||||
| // | ||||
| static NSUInteger getStyleMask(_GLFWwindow* window) | ||||
| { | ||||
|     NSUInteger styleMask = 0; | ||||
| 
 | ||||
|     if (window->monitor || !window->decorated) | ||||
|         styleMask |= NSBorderlessWindowMask; | ||||
|     else | ||||
|     { | ||||
|         styleMask |= NSTitledWindowMask | NSClosableWindowMask | | ||||
|                      NSMiniaturizableWindowMask; | ||||
| 
 | ||||
|         if (window->resizable) | ||||
|             styleMask |= NSResizableWindowMask; | ||||
|     } | ||||
| 
 | ||||
|     return styleMask; | ||||
| } | ||||
| 
 | ||||
| // Center the cursor in the view of the window | ||||
| // | ||||
| static void centerCursor(_GLFWwindow *window) | ||||
| @ -86,7 +106,6 @@ static GLFWbool acquireMonitor(_GLFWwindow* window) | ||||
| 
 | ||||
|     [window->ns.object setFrame:frame display:YES]; | ||||
| 
 | ||||
|     _glfwPlatformFocusWindow(window); | ||||
|     _glfwInputMonitorWindowChange(window->monitor, window); | ||||
|     return status; | ||||
| } | ||||
| @ -908,19 +927,6 @@ static GLFWbool createWindow(_GLFWwindow* window, | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
| 
 | ||||
|     unsigned int styleMask = 0; | ||||
| 
 | ||||
|     if (window->monitor || !wndconfig->decorated) | ||||
|         styleMask = NSBorderlessWindowMask; | ||||
|     else | ||||
|     { | ||||
|         styleMask = NSTitledWindowMask | NSClosableWindowMask | | ||||
|                     NSMiniaturizableWindowMask; | ||||
| 
 | ||||
|         if (wndconfig->resizable) | ||||
|             styleMask |= NSResizableWindowMask; | ||||
|     } | ||||
| 
 | ||||
|     NSRect contentRect; | ||||
| 
 | ||||
|     if (window->monitor) | ||||
| @ -938,7 +944,7 @@ static GLFWbool createWindow(_GLFWwindow* window, | ||||
| 
 | ||||
|     window->ns.object = [[GLFWWindow alloc] | ||||
|         initWithContentRect:contentRect | ||||
|                   styleMask:styleMask | ||||
|                   styleMask:getStyleMask(window) | ||||
|                     backing:NSBackingStoreBuffered | ||||
|                       defer:NO]; | ||||
| 
 | ||||
| @ -948,15 +954,15 @@ static GLFWbool createWindow(_GLFWwindow* window, | ||||
|         return GLFW_FALSE; | ||||
|     } | ||||
| 
 | ||||
|     if (wndconfig->resizable) | ||||
|         [window->ns.object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; | ||||
| 
 | ||||
|     if (window->monitor) | ||||
|         [window->ns.object setLevel:NSMainMenuWindowLevel + 1]; | ||||
|     else | ||||
|     { | ||||
|         [window->ns.object center]; | ||||
| 
 | ||||
|         if (wndconfig->resizable) | ||||
|             [window->ns.object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; | ||||
| 
 | ||||
|         if (wndconfig->floating) | ||||
|             [window->ns.object setLevel:NSFloatingWindowLevel]; | ||||
| 
 | ||||
| @ -1005,6 +1011,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, | ||||
|     if (window->monitor) | ||||
|     { | ||||
|         _glfwPlatformShowWindow(window); | ||||
|         _glfwPlatformFocusWindow(window); | ||||
|         if (!acquireMonitor(window)) | ||||
|             return GLFW_FALSE; | ||||
|     } | ||||
| @ -1076,7 +1083,10 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) | ||||
| void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) | ||||
| { | ||||
|     if (window->monitor) | ||||
|         acquireMonitor(window); | ||||
|     { | ||||
|         if (window->monitor->window == window) | ||||
|             acquireMonitor(window); | ||||
|     } | ||||
|     else | ||||
|         [window->ns.object setContentSize:NSMakeSize(width, height)]; | ||||
| } | ||||
| @ -1174,6 +1184,103 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window) | ||||
|     [window->ns.object makeKeyAndOrderFront:nil]; | ||||
| } | ||||
| 
 | ||||
| void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, | ||||
|                                    _GLFWmonitor* monitor, | ||||
|                                    int xpos, int ypos, | ||||
|                                    int width, int height, | ||||
|                                    int refreshRate) | ||||
| { | ||||
|     if (window->monitor == monitor) | ||||
|     { | ||||
|         if (monitor) | ||||
|         { | ||||
|             if (monitor->window == window) | ||||
|                 acquireMonitor(window); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             const NSRect contentRect = | ||||
|                 NSMakeRect(xpos, transformY(ypos + height), width, height); | ||||
|             const NSRect frameRect = | ||||
|                 [window->ns.object frameRectForContentRect:contentRect | ||||
|                                                  styleMask:getStyleMask(window)]; | ||||
| 
 | ||||
|             [window->ns.object setFrame:frameRect display:YES]; | ||||
|         } | ||||
| 
 | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (window->monitor) | ||||
|         releaseMonitor(window); | ||||
| 
 | ||||
|     _glfwInputWindowMonitorChange(window, monitor); | ||||
| 
 | ||||
|     const NSUInteger styleMask = getStyleMask(window); | ||||
|     [window->ns.object setStyleMask:styleMask]; | ||||
|     [window->ns.object makeFirstResponder:window->ns.view]; | ||||
| 
 | ||||
|     NSRect contentRect; | ||||
| 
 | ||||
|     if (monitor) | ||||
|     { | ||||
|         GLFWvidmode mode; | ||||
| 
 | ||||
|         _glfwPlatformGetVideoMode(window->monitor, &mode); | ||||
|         _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos); | ||||
| 
 | ||||
|         contentRect = NSMakeRect(xpos, transformY(ypos + mode.height), | ||||
|                                     mode.width, mode.height); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         contentRect = NSMakeRect(xpos, transformY(ypos + height), | ||||
|                                     width, height); | ||||
|     } | ||||
| 
 | ||||
|     NSRect frameRect = [window->ns.object frameRectForContentRect:contentRect | ||||
|                                                         styleMask:styleMask]; | ||||
|     [window->ns.object setFrame:frameRect display:YES]; | ||||
| 
 | ||||
|     if (monitor) | ||||
|     { | ||||
|         [window->ns.object setLevel:NSMainMenuWindowLevel + 1]; | ||||
|         [window->ns.object setHasShadow:NO]; | ||||
| 
 | ||||
|         acquireMonitor(window); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (window->numer != GLFW_DONT_CARE && | ||||
|             window->denom != GLFW_DONT_CARE) | ||||
|         { | ||||
|             [window->ns.object setContentAspectRatio:NSMakeSize(window->numer, | ||||
|                                                                 window->denom)]; | ||||
|         } | ||||
| 
 | ||||
|         if (window->minwidth != GLFW_DONT_CARE && | ||||
|             window->minheight != GLFW_DONT_CARE) | ||||
|         { | ||||
|             [window->ns.object setContentMinSize:NSMakeSize(window->minwidth, | ||||
|                                                             window->minheight)]; | ||||
|         } | ||||
| 
 | ||||
|         if (window->maxwidth != GLFW_DONT_CARE && | ||||
|             window->maxheight != GLFW_DONT_CARE) | ||||
|         { | ||||
|             [window->ns.object setContentMaxSize:NSMakeSize(window->maxwidth, | ||||
|                                                             window->maxheight)]; | ||||
|         } | ||||
| 
 | ||||
|         if (window->floating) | ||||
|             [window->ns.object setLevel:NSFloatingWindowLevel]; | ||||
|         else | ||||
|             [window->ns.object setLevel:NSNormalWindowLevel]; | ||||
| 
 | ||||
|         [window->ns.object setHasShadow:YES]; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| int _glfwPlatformWindowFocused(_GLFWwindow* window) | ||||
| { | ||||
|     return [window->ns.object isKeyWindow]; | ||||
|  | ||||
| @ -339,6 +339,10 @@ struct _GLFWwindow | ||||
|     _GLFWmonitor*       monitor; | ||||
|     _GLFWcursor*        cursor; | ||||
| 
 | ||||
|     int                 minwidth, minheight; | ||||
|     int                 maxwidth, maxheight; | ||||
|     int                 numer, denom; | ||||
| 
 | ||||
|     // Window input state
 | ||||
|     GLFWbool            stickyKeys; | ||||
|     GLFWbool            stickyMouseButtons; | ||||
| @ -694,6 +698,11 @@ void _glfwPlatformHideWindow(_GLFWwindow* window); | ||||
|  */ | ||||
| void _glfwPlatformFocusWindow(_GLFWwindow* window); | ||||
| 
 | ||||
| /*! @copydoc glfwSetWindowMonitor
 | ||||
|  *  @ingroup platform | ||||
|  */ | ||||
| void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, _GLFWmonitor* monitor, int xpos, int ypos, int width, int height, int refreshRate); | ||||
| 
 | ||||
| /*! @brief Returns whether the window is focused.
 | ||||
|  *  @ingroup platform | ||||
|  */ | ||||
| @ -856,6 +865,8 @@ void _glfwInputWindowDamage(_GLFWwindow* window); | ||||
|  */ | ||||
| void _glfwInputWindowCloseRequest(_GLFWwindow* window); | ||||
| 
 | ||||
| void _glfwInputWindowMonitorChange(_GLFWwindow* window, _GLFWmonitor* monitor); | ||||
| 
 | ||||
| /*! @brief Notifies shared code of a physical key event.
 | ||||
|  *  @param[in] window The window that received the event. | ||||
|  *  @param[in] key The key that was pressed or released. | ||||
|  | ||||
| @ -508,6 +508,16 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window) | ||||
|                     "Mir: Unsupported function %s", __PRETTY_FUNCTION__); | ||||
| } | ||||
| 
 | ||||
| void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, | ||||
|                                    _GLFWmonitor* monitor, | ||||
|                                    int xpos, int ypos, | ||||
|                                    int width, int height, | ||||
|                                    int refreshRate) | ||||
| { | ||||
|     _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|                     "Mir: Unsupported function %s", __PRETTY_FUNCTION__); | ||||
| } | ||||
| 
 | ||||
| int _glfwPlatformWindowFocused(_GLFWwindow* window) | ||||
| { | ||||
|     _glfwInputError(GLFW_PLATFORM_ERROR, | ||||
|  | ||||
| @ -126,7 +126,11 @@ void _glfwInputMonitorChange(void) | ||||
|         for (window = _glfw.windowListHead;  window;  window = window->next) | ||||
|         { | ||||
|             if (window->monitor == monitors[i]) | ||||
|                 window->monitor = NULL; | ||||
|             { | ||||
|                 int width, height; | ||||
|                 _glfwPlatformGetWindowSize(window, &width, &height); | ||||
|                 _glfwPlatformSetWindowMonitor(window, NULL, 0, 0, width, height, 0); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (_glfw.callbacks.monitor) | ||||
|  | ||||
| @ -197,10 +197,6 @@ typedef struct _GLFWwindowWin32 | ||||
|     GLFWbool            cursorTracked; | ||||
|     GLFWbool            iconified; | ||||
| 
 | ||||
|     int                 minwidth, minheight; | ||||
|     int                 maxwidth, maxheight; | ||||
|     int                 numer, denom; | ||||
| 
 | ||||
|     // The last received cursor position, regardless of source
 | ||||
|     int                 cursorPosX, cursorPosY; | ||||
| 
 | ||||
|  | ||||
| @ -42,15 +42,20 @@ static DWORD getWindowStyle(const _GLFWwindow* window) | ||||
| { | ||||
|     DWORD style = WS_CLIPSIBLINGS | WS_CLIPCHILDREN; | ||||
| 
 | ||||
|     if (window->decorated && !window->monitor) | ||||
|     { | ||||
|         style |= WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; | ||||
| 
 | ||||
|         if (window->resizable) | ||||
|             style |= WS_MAXIMIZEBOX | WS_SIZEBOX; | ||||
|     } | ||||
|     else | ||||
|     if (window->monitor) | ||||
|         style |= WS_POPUP; | ||||
|     else | ||||
|     { | ||||
|         if (window->decorated) | ||||
|         { | ||||
|             style |= WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; | ||||
| 
 | ||||
|             if (window->resizable) | ||||
|                 style |= WS_MAXIMIZEBOX | WS_THICKFRAME; | ||||
|         } | ||||
|         else | ||||
|             style |= WS_POPUP; | ||||
|     } | ||||
| 
 | ||||
|     return style; | ||||
| } | ||||
| @ -61,8 +66,8 @@ static DWORD getWindowExStyle(const _GLFWwindow* window) | ||||
| { | ||||
|     DWORD style = WS_EX_APPWINDOW; | ||||
| 
 | ||||
|     if (window->decorated && !window->monitor) | ||||
|         style |= WS_EX_WINDOWEDGE; | ||||
|     if (window->monitor || window->floating) | ||||
|         style |= WS_EX_TOPMOST; | ||||
| 
 | ||||
|     return style; | ||||
| } | ||||
| @ -190,8 +195,7 @@ static void getFullWindowSize(DWORD style, DWORD exStyle, | ||||
| static void applyAspectRatio(_GLFWwindow* window, int edge, RECT* area) | ||||
| { | ||||
|     int xoff, yoff; | ||||
|     const float ratio = (float) window->win32.numer / | ||||
|                         (float) window->win32.denom; | ||||
|     const float ratio = (float) window->numer / (float) window->denom; | ||||
| 
 | ||||
|     getFullWindowSize(getWindowStyle(window), getWindowExStyle(window), | ||||
|                       0, 0, &xoff, &yoff); | ||||
| @ -342,7 +346,8 @@ static GLFWbool acquireMonitor(_GLFWwindow* window) | ||||
|     _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos); | ||||
| 
 | ||||
|     SetWindowPos(window->win32.handle, HWND_TOPMOST, | ||||
|                  xpos, ypos, mode.width, mode.height, SWP_NOCOPYBITS); | ||||
|                  xpos, ypos, mode.width, mode.height, | ||||
|                  SWP_NOACTIVATE | SWP_NOCOPYBITS); | ||||
| 
 | ||||
|     _glfwInputMonitorWindowChange(window->monitor, window); | ||||
|     return status; | ||||
| @ -639,8 +644,8 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, | ||||
| 
 | ||||
|         case WM_SIZING: | ||||
|         { | ||||
|             if (window->win32.numer == GLFW_DONT_CARE || | ||||
|                 window->win32.denom == GLFW_DONT_CARE) | ||||
|             if (window->numer == GLFW_DONT_CARE || | ||||
|                 window->denom == GLFW_DONT_CARE) | ||||
|             { | ||||
|                 break; | ||||
|             } | ||||
| @ -654,21 +659,24 @@ static LRESULT CALLBACK windowProc(HWND hWnd, UINT uMsg, | ||||
|             int xoff, yoff; | ||||
|             MINMAXINFO* mmi = (MINMAXINFO*) lParam; | ||||
| 
 | ||||
|             if (window->monitor) | ||||
|                 break; | ||||
| 
 | ||||
|             getFullWindowSize(getWindowStyle(window), getWindowExStyle(window), | ||||
|                               0, 0, &xoff, &yoff); | ||||
| 
 | ||||
|             if (window->win32.minwidth != GLFW_DONT_CARE && | ||||
|                 window->win32.minheight != GLFW_DONT_CARE) | ||||
|             if (window->minwidth != GLFW_DONT_CARE && | ||||
|                 window->minheight != GLFW_DONT_CARE) | ||||
|             { | ||||
|                 mmi->ptMinTrackSize.x = window->win32.minwidth + xoff; | ||||
|                 mmi->ptMinTrackSize.y = window->win32.minheight + yoff; | ||||
|                 mmi->ptMinTrackSize.x = window->minwidth + xoff; | ||||
|                 mmi->ptMinTrackSize.y = window->minheight + yoff; | ||||
|             } | ||||
| 
 | ||||
|             if (window->win32.maxwidth != GLFW_DONT_CARE && | ||||
|                 window->win32.maxheight != GLFW_DONT_CARE) | ||||
|             if (window->maxwidth != GLFW_DONT_CARE && | ||||
|                 window->maxheight != GLFW_DONT_CARE) | ||||
|             { | ||||
|                 mmi->ptMaxTrackSize.x = window->win32.maxwidth + xoff; | ||||
|                 mmi->ptMaxTrackSize.y = window->win32.maxheight + yoff; | ||||
|                 mmi->ptMaxTrackSize.x = window->maxwidth + xoff; | ||||
|                 mmi->ptMaxTrackSize.y = window->maxheight + yoff; | ||||
|             } | ||||
| 
 | ||||
|             return 0; | ||||
| @ -827,23 +835,8 @@ static int createWindow(_GLFWwindow* window, const _GLFWwndconfig* wndconfig) | ||||
|                                           WM_COPYGLOBALDATA, MSGFLT_ALLOW, NULL); | ||||
|     } | ||||
| 
 | ||||
|     if (wndconfig->floating && !window->monitor) | ||||
|     { | ||||
|         SetWindowPos(window->win32.handle, | ||||
|                      HWND_TOPMOST, | ||||
|                      0, 0, 0, 0, | ||||
|                      SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); | ||||
|     } | ||||
| 
 | ||||
|     DragAcceptFiles(window->win32.handle, TRUE); | ||||
| 
 | ||||
|     window->win32.minwidth  = GLFW_DONT_CARE; | ||||
|     window->win32.minheight = GLFW_DONT_CARE; | ||||
|     window->win32.maxwidth  = GLFW_DONT_CARE; | ||||
|     window->win32.maxheight = GLFW_DONT_CARE; | ||||
|     window->win32.numer     = GLFW_DONT_CARE; | ||||
|     window->win32.denom     = GLFW_DONT_CARE; | ||||
| 
 | ||||
|     return GLFW_TRUE; | ||||
| } | ||||
| 
 | ||||
| @ -976,6 +969,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, | ||||
|     if (window->monitor) | ||||
|     { | ||||
|         _glfwPlatformShowWindow(window); | ||||
|         _glfwPlatformFocusWindow(window); | ||||
|         if (!acquireMonitor(window)) | ||||
|             return GLFW_FALSE; | ||||
|     } | ||||
| @ -1093,15 +1087,17 @@ void _glfwPlatformGetWindowSize(_GLFWwindow* window, int* width, int* height) | ||||
| void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) | ||||
| { | ||||
|     if (window->monitor) | ||||
|         acquireMonitor(window); | ||||
|     { | ||||
|         if (window->monitor->window == window) | ||||
|             acquireMonitor(window); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         int fullWidth, fullHeight; | ||||
|         getFullWindowSize(getWindowStyle(window), getWindowExStyle(window), | ||||
|                           width, height, &fullWidth, &fullHeight); | ||||
| 
 | ||||
|         RECT rect = { 0, 0, width, height }; | ||||
|         AdjustWindowRectEx(&rect, getWindowStyle(window), | ||||
|                            FALSE, getWindowExStyle(window)); | ||||
|         SetWindowPos(window->win32.handle, HWND_TOP, | ||||
|                      0, 0, fullWidth, fullHeight, | ||||
|                      0, 0, rect.right - rect.left, rect.bottom - rect.top, | ||||
|                      SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOZORDER); | ||||
|     } | ||||
| } | ||||
| @ -1112,11 +1108,6 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, | ||||
| { | ||||
|     RECT area; | ||||
| 
 | ||||
|     window->win32.minwidth  = minwidth; | ||||
|     window->win32.minheight = minheight; | ||||
|     window->win32.maxwidth  = maxwidth; | ||||
|     window->win32.maxheight = maxheight; | ||||
| 
 | ||||
|     if ((minwidth == GLFW_DONT_CARE || minheight == GLFW_DONT_CARE) && | ||||
|         (maxwidth == GLFW_DONT_CARE || maxheight == GLFW_DONT_CARE)) | ||||
|     { | ||||
| @ -1134,9 +1125,6 @@ void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom | ||||
| { | ||||
|     RECT area; | ||||
| 
 | ||||
|     window->win32.numer = numer; | ||||
|     window->win32.denom = denom; | ||||
| 
 | ||||
|     if (numer == GLFW_DONT_CARE || denom == GLFW_DONT_CARE) | ||||
|         return; | ||||
| 
 | ||||
| @ -1207,6 +1195,92 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window) | ||||
|     SetFocus(window->win32.handle); | ||||
| } | ||||
| 
 | ||||
| void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, | ||||
|                                    _GLFWmonitor* monitor, | ||||
|                                    int xpos, int ypos, | ||||
|                                    int width, int height, | ||||
|                                    int refreshRate) | ||||
| { | ||||
|     if (window->monitor == monitor) | ||||
|     { | ||||
|         if (monitor) | ||||
|         { | ||||
|             if (monitor->window == window) | ||||
|                 acquireMonitor(window); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             RECT rect = { xpos, ypos, xpos + width, ypos + height }; | ||||
|             AdjustWindowRectEx(&rect, getWindowStyle(window), | ||||
|                                FALSE, getWindowExStyle(window)); | ||||
|             SetWindowPos(window->win32.handle, HWND_TOP, | ||||
|                          rect.left, rect.top, | ||||
|                          rect.right - rect.left, rect.bottom - rect.top, | ||||
|                          SWP_NOCOPYBITS | SWP_NOACTIVATE | SWP_NOZORDER); | ||||
|         } | ||||
| 
 | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (window->monitor) | ||||
|         releaseMonitor(window); | ||||
| 
 | ||||
|     _glfwInputWindowMonitorChange(window, monitor); | ||||
| 
 | ||||
|     if (monitor) | ||||
|     { | ||||
|         GLFWvidmode mode; | ||||
|         DWORD style = GetWindowLongPtrW(window->win32.handle, GWL_STYLE); | ||||
|         UINT flags = SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOCOPYBITS; | ||||
| 
 | ||||
|         if (window->decorated) | ||||
|         { | ||||
|             style &= ~WS_OVERLAPPEDWINDOW; | ||||
|             style |= getWindowStyle(window); | ||||
|             SetWindowLongPtrW(window->win32.handle, GWL_STYLE, style); | ||||
| 
 | ||||
|             flags |= SWP_FRAMECHANGED; | ||||
|         } | ||||
| 
 | ||||
|         _glfwPlatformGetVideoMode(monitor, &mode); | ||||
|         _glfwPlatformGetMonitorPos(monitor, &xpos, &ypos); | ||||
| 
 | ||||
|         SetWindowPos(window->win32.handle, HWND_TOPMOST, | ||||
|                      xpos, ypos, mode.width, mode.height, | ||||
|                      flags); | ||||
| 
 | ||||
|         acquireMonitor(window); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         HWND after; | ||||
|         RECT rect = { xpos, ypos, xpos + width, ypos + height }; | ||||
|         DWORD style = GetWindowLongPtrW(window->win32.handle, GWL_STYLE); | ||||
|         UINT flags = SWP_NOACTIVATE | SWP_NOCOPYBITS; | ||||
| 
 | ||||
|         if (window->decorated) | ||||
|         { | ||||
|             style &= ~WS_POPUP; | ||||
|             style |= getWindowStyle(window); | ||||
|             SetWindowLongPtrW(window->win32.handle, GWL_STYLE, style); | ||||
| 
 | ||||
|             flags |= SWP_FRAMECHANGED; | ||||
|         } | ||||
| 
 | ||||
|         if (window->floating) | ||||
|             after = HWND_TOPMOST; | ||||
|         else | ||||
|             after = HWND_NOTOPMOST; | ||||
| 
 | ||||
|         AdjustWindowRectEx(&rect, getWindowStyle(window), | ||||
|                            FALSE, getWindowExStyle(window)); | ||||
|         SetWindowPos(window->win32.handle, after, | ||||
|                      rect.left, rect.top, | ||||
|                      rect.right - rect.left, rect.bottom - rect.top, | ||||
|                      flags); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| int _glfwPlatformWindowFocused(_GLFWwindow* window) | ||||
| { | ||||
|     return window->win32.handle == GetActiveWindow(); | ||||
|  | ||||
							
								
								
									
										55
									
								
								src/window.c
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								src/window.c
									
									
									
									
									
								
							| @ -110,6 +110,11 @@ void _glfwInputWindowCloseRequest(_GLFWwindow* window) | ||||
|         window->callbacks.close((GLFWwindow*) window); | ||||
| } | ||||
| 
 | ||||
| void _glfwInputWindowMonitorChange(_GLFWwindow* window, _GLFWmonitor* monitor) | ||||
| { | ||||
|     window->monitor = monitor; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| //////////////////////////////////////////////////////////////////////////
 | ||||
| //////                        GLFW public API                       //////
 | ||||
| @ -154,13 +159,6 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (monitor) | ||||
|     { | ||||
|         wndconfig.resizable = GLFW_TRUE; | ||||
|         wndconfig.visible   = GLFW_TRUE; | ||||
|         wndconfig.focused   = GLFW_TRUE; | ||||
|     } | ||||
| 
 | ||||
|     if (!_glfwIsValidContextConfig(&ctxconfig)) | ||||
|         return NULL; | ||||
| 
 | ||||
| @ -182,6 +180,13 @@ GLFWAPI GLFWwindow* glfwCreateWindow(int width, int height, | ||||
|     window->floating    = wndconfig.floating; | ||||
|     window->cursorMode  = GLFW_CURSOR_NORMAL; | ||||
| 
 | ||||
|     window->minwidth    = GLFW_DONT_CARE; | ||||
|     window->minheight   = GLFW_DONT_CARE; | ||||
|     window->maxwidth    = GLFW_DONT_CARE; | ||||
|     window->maxheight   = GLFW_DONT_CARE; | ||||
|     window->numer       = GLFW_DONT_CARE; | ||||
|     window->denom       = GLFW_DONT_CARE; | ||||
| 
 | ||||
|     // Save the currently current context so it can be restored later
 | ||||
|     previous = _glfwPlatformGetCurrentContext(); | ||||
| 
 | ||||
| @ -510,11 +515,8 @@ GLFWAPI void glfwSetWindowSize(GLFWwindow* handle, int width, int height) | ||||
| 
 | ||||
|     _GLFW_REQUIRE_INIT(); | ||||
| 
 | ||||
|     if (window->monitor) | ||||
|     { | ||||
|         window->videoMode.width  = width; | ||||
|         window->videoMode.height = height; | ||||
|     } | ||||
|     window->videoMode.width  = width; | ||||
|     window->videoMode.height = height; | ||||
| 
 | ||||
|     _glfwPlatformSetWindowSize(window, width, height); | ||||
| } | ||||
| @ -528,6 +530,11 @@ GLFWAPI void glfwSetWindowSizeLimits(GLFWwindow* handle, | ||||
| 
 | ||||
|     _GLFW_REQUIRE_INIT(); | ||||
| 
 | ||||
|     window->minwidth  = minwidth; | ||||
|     window->minheight = minheight; | ||||
|     window->maxwidth  = maxwidth; | ||||
|     window->maxheight = maxheight; | ||||
| 
 | ||||
|     if (window->monitor || !window->resizable) | ||||
|         return; | ||||
| 
 | ||||
| @ -543,6 +550,9 @@ GLFWAPI void glfwSetWindowAspectRatio(GLFWwindow* handle, int numer, int denom) | ||||
| 
 | ||||
|     _GLFW_REQUIRE_INIT(); | ||||
| 
 | ||||
|     window->numer = numer; | ||||
|     window->denom = denom; | ||||
| 
 | ||||
|     if (window->monitor || !window->resizable) | ||||
|         return; | ||||
| 
 | ||||
| @ -709,6 +719,27 @@ GLFWAPI GLFWmonitor* glfwGetWindowMonitor(GLFWwindow* handle) | ||||
|     return (GLFWmonitor*) window->monitor; | ||||
| } | ||||
| 
 | ||||
| GLFWAPI void glfwSetWindowMonitor(GLFWwindow* wh, | ||||
|                                   GLFWmonitor* mh, | ||||
|                                   int xpos, int ypos, | ||||
|                                   int width, int height, | ||||
|                                   int refreshRate) | ||||
| { | ||||
|     _GLFWwindow* window = (_GLFWwindow*) wh; | ||||
|     _GLFWmonitor* monitor = (_GLFWmonitor*) mh; | ||||
|     assert(window); | ||||
| 
 | ||||
|     _GLFW_REQUIRE_INIT(); | ||||
| 
 | ||||
|     window->videoMode.width       = width; | ||||
|     window->videoMode.height      = height; | ||||
|     window->videoMode.refreshRate = refreshRate; | ||||
| 
 | ||||
|     _glfwPlatformSetWindowMonitor(window, monitor, | ||||
|                                   xpos, ypos, width, height, | ||||
|                                   refreshRate); | ||||
| } | ||||
| 
 | ||||
| GLFWAPI void glfwSetWindowUserPointer(GLFWwindow* handle, void* pointer) | ||||
| { | ||||
|     _GLFWwindow* window = (_GLFWwindow*) handle; | ||||
|  | ||||
| @ -489,6 +489,16 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window) | ||||
|     fprintf(stderr, "_glfwPlatformFocusWindow not implemented yet\n"); | ||||
| } | ||||
| 
 | ||||
| void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, | ||||
|                                    _GLFWmonitor* monitor, | ||||
|                                    int xpos, int ypos, | ||||
|                                    int width, int height, | ||||
|                                    int refreshRate) | ||||
| { | ||||
|     // TODO
 | ||||
|     fprintf(stderr, "_glfwPlatformSetWindowMonitor not implemented yet\n"); | ||||
| } | ||||
| 
 | ||||
| int _glfwPlatformWindowFocused(_GLFWwindow* window) | ||||
| { | ||||
|     // TODO
 | ||||
|  | ||||
							
								
								
									
										438
									
								
								src/x11_window.c
									
									
									
									
									
								
							
							
						
						
									
										438
									
								
								src/x11_window.c
									
									
									
									
									
								
							| @ -199,6 +199,145 @@ static void sendEventToWM(_GLFWwindow* window, Atom type, | ||||
|                &event); | ||||
| } | ||||
| 
 | ||||
| // Updates the normal hints according to the window settings
 | ||||
| //
 | ||||
| static void updateNormalHints(_GLFWwindow* window) | ||||
| { | ||||
|     XSizeHints* hints = XAllocSizeHints(); | ||||
| 
 | ||||
|     if (!window->monitor) | ||||
|     { | ||||
|         if (window->resizable) | ||||
|         { | ||||
|             if (window->minwidth != GLFW_DONT_CARE && | ||||
|                 window->minwidth != GLFW_DONT_CARE && | ||||
|                 window->maxwidth != GLFW_DONT_CARE && | ||||
|                 window->maxwidth != GLFW_DONT_CARE) | ||||
|             { | ||||
|                 hints->flags |= (PMinSize | PMaxSize); | ||||
|                 hints->min_width  = window->minwidth; | ||||
|                 hints->min_height = window->minheight; | ||||
|                 hints->max_width  = window->maxwidth; | ||||
|                 hints->max_height = window->maxheight; | ||||
|             } | ||||
| 
 | ||||
|             if (window->numer != GLFW_DONT_CARE && | ||||
|                 window->denom != GLFW_DONT_CARE) | ||||
|             { | ||||
|                 hints->flags |= PAspect; | ||||
|                 hints->min_aspect.x = hints->max_aspect.x = window->numer; | ||||
|                 hints->min_aspect.y = hints->max_aspect.y = window->denom; | ||||
|             } | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             int width, height; | ||||
|             _glfwPlatformGetWindowSize(window, &width, &height); | ||||
| 
 | ||||
|             hints->flags |= (PMinSize | PMaxSize); | ||||
|             hints->min_width  = hints->max_width  = width; | ||||
|             hints->min_height = hints->max_height = height; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); | ||||
|     XFree(hints); | ||||
| } | ||||
| 
 | ||||
| // Updates the full screen status of the window
 | ||||
| //
 | ||||
| static void updateWindowMode(_GLFWwindow* window) | ||||
| { | ||||
|     updateNormalHints(window); | ||||
| 
 | ||||
|     if (window->monitor) | ||||
|     { | ||||
|         if (_glfw.x11.xinerama.available && | ||||
|             _glfw.x11.NET_WM_FULLSCREEN_MONITORS) | ||||
|         { | ||||
|             sendEventToWM(window, | ||||
|                           _glfw.x11.NET_WM_FULLSCREEN_MONITORS, | ||||
|                           window->monitor->x11.index, | ||||
|                           window->monitor->x11.index, | ||||
|                           window->monitor->x11.index, | ||||
|                           window->monitor->x11.index, | ||||
|                           0); | ||||
|         } | ||||
| 
 | ||||
|         if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN) | ||||
|         { | ||||
|             sendEventToWM(window, | ||||
|                           _glfw.x11.NET_WM_STATE, | ||||
|                           _NET_WM_STATE_ADD, | ||||
|                           _glfw.x11.NET_WM_STATE_FULLSCREEN, | ||||
|                           0, 1, 0); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             // This is the butcher's way of removing window decorations
 | ||||
|             // Setting the override-redirect attribute on a window makes the
 | ||||
|             // window manager ignore the window completely (ICCCM, section 4)
 | ||||
|             // The good thing is that this makes undecorated full screen windows
 | ||||
|             // easy to do; the bad thing is that we have to do everything
 | ||||
|             // manually and some things (like iconify/restore) won't work at
 | ||||
|             // all, as those are tasks usually performed by the window manager
 | ||||
| 
 | ||||
|             XSetWindowAttributes attributes; | ||||
|             attributes.override_redirect = True; | ||||
|             XChangeWindowAttributes(_glfw.x11.display, | ||||
|                                     window->x11.handle, | ||||
|                                     CWOverrideRedirect, | ||||
|                                     &attributes); | ||||
| 
 | ||||
|             window->x11.overrideRedirect = GLFW_TRUE; | ||||
|         } | ||||
| 
 | ||||
|         if (_glfw.x11.NET_WM_BYPASS_COMPOSITOR) | ||||
|         { | ||||
|             const unsigned long value = 1; | ||||
| 
 | ||||
|             XChangeProperty(_glfw.x11.display,  window->x11.handle, | ||||
|                             _glfw.x11.NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32, | ||||
|                             PropModeReplace, (unsigned char*) &value, 1); | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (_glfw.x11.xinerama.available && | ||||
|             _glfw.x11.NET_WM_FULLSCREEN_MONITORS) | ||||
|         { | ||||
|             XDeleteProperty(_glfw.x11.display, window->x11.handle, | ||||
|                             _glfw.x11.NET_WM_FULLSCREEN_MONITORS); | ||||
|         } | ||||
| 
 | ||||
|         if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN) | ||||
|         { | ||||
|             sendEventToWM(window, | ||||
|                           _glfw.x11.NET_WM_STATE, | ||||
|                           _NET_WM_STATE_REMOVE, | ||||
|                           _glfw.x11.NET_WM_STATE_FULLSCREEN, | ||||
|                           0, 1, 0); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             XSetWindowAttributes attributes; | ||||
|             attributes.override_redirect = False; | ||||
|             XChangeWindowAttributes(_glfw.x11.display, | ||||
|                                     window->x11.handle, | ||||
|                                     CWOverrideRedirect, | ||||
|                                     &attributes); | ||||
| 
 | ||||
|             window->x11.overrideRedirect = GLFW_FALSE; | ||||
|         } | ||||
| 
 | ||||
|         if (_glfw.x11.NET_WM_BYPASS_COMPOSITOR) | ||||
|         { | ||||
|             XDeleteProperty(_glfw.x11.display, window->x11.handle, | ||||
|                             _glfw.x11.NET_WM_BYPASS_COMPOSITOR); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Splits and translates a text/uri-list into separate file paths
 | ||||
| // NOTE: This function destroys the provided string
 | ||||
| //
 | ||||
| @ -300,84 +439,57 @@ static GLFWbool createWindow(_GLFWwindow* window, | ||||
|                      (XPointer) window); | ||||
|     } | ||||
| 
 | ||||
|     if (window->monitor) | ||||
|     if (!wndconfig->decorated) | ||||
|     { | ||||
|         if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_FULLSCREEN) | ||||
|         struct | ||||
|         { | ||||
|             // This is the butcher's way of removing window decorations
 | ||||
|             // Setting the override-redirect attribute on a window makes the
 | ||||
|             // window manager ignore the window completely (ICCCM, section 4)
 | ||||
|             // The good thing is that this makes undecorated full screen windows
 | ||||
|             // easy to do; the bad thing is that we have to do everything
 | ||||
|             // manually and some things (like iconify/restore) won't work at
 | ||||
|             // all, as those are tasks usually performed by the window manager
 | ||||
|             unsigned long flags; | ||||
|             unsigned long functions; | ||||
|             unsigned long decorations; | ||||
|             long input_mode; | ||||
|             unsigned long status; | ||||
|         } hints; | ||||
| 
 | ||||
|             XSetWindowAttributes attributes; | ||||
|             attributes.override_redirect = True; | ||||
|             XChangeWindowAttributes(_glfw.x11.display, | ||||
|                                     window->x11.handle, | ||||
|                                     CWOverrideRedirect, | ||||
|                                     &attributes); | ||||
|         hints.flags = 2;       // Set decorations
 | ||||
|         hints.decorations = 0; // No decorations
 | ||||
| 
 | ||||
|             window->x11.overrideRedirect = GLFW_TRUE; | ||||
|         XChangeProperty(_glfw.x11.display, window->x11.handle, | ||||
|                         _glfw.x11.MOTIF_WM_HINTS, | ||||
|                         _glfw.x11.MOTIF_WM_HINTS, 32, | ||||
|                         PropModeReplace, | ||||
|                         (unsigned char*) &hints, | ||||
|                         sizeof(hints) / sizeof(long)); | ||||
|     } | ||||
| 
 | ||||
|     if (wndconfig->floating) | ||||
|     { | ||||
|         if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_ABOVE) | ||||
|         { | ||||
|             Atom value = _glfw.x11.NET_WM_STATE_ABOVE; | ||||
|             XChangeProperty(_glfw.x11.display, window->x11.handle, | ||||
|                             _glfw.x11.NET_WM_STATE, XA_ATOM, 32, | ||||
|                             PropModeReplace, (unsigned char*) &value, 1); | ||||
|         } | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (!wndconfig->decorated) | ||||
|         { | ||||
|             struct | ||||
|             { | ||||
|                 unsigned long flags; | ||||
|                 unsigned long functions; | ||||
|                 unsigned long decorations; | ||||
|                 long input_mode; | ||||
|                 unsigned long status; | ||||
|             } hints; | ||||
| 
 | ||||
|             hints.flags = 2;       // Set decorations
 | ||||
|             hints.decorations = 0; // No decorations
 | ||||
|     if (wndconfig->maximized && !window->monitor) | ||||
|     { | ||||
|         if (_glfw.x11.NET_WM_STATE && | ||||
|             _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT && | ||||
|             _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ) | ||||
|         { | ||||
|             const Atom states[2] = | ||||
|             { | ||||
|                 _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT, | ||||
|                 _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ | ||||
|             }; | ||||
| 
 | ||||
|             XChangeProperty(_glfw.x11.display, window->x11.handle, | ||||
|                             _glfw.x11.MOTIF_WM_HINTS, | ||||
|                             _glfw.x11.MOTIF_WM_HINTS, 32, | ||||
|                             PropModeReplace, | ||||
|                             (unsigned char*) &hints, | ||||
|                             sizeof(hints) / sizeof(long)); | ||||
|         } | ||||
| 
 | ||||
|         if (wndconfig->floating) | ||||
|         { | ||||
|             if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_ABOVE) | ||||
|             { | ||||
|                 sendEventToWM(window, | ||||
|                               _glfw.x11.NET_WM_STATE, | ||||
|                               _NET_WM_STATE_ADD, | ||||
|                               _glfw.x11.NET_WM_STATE_ABOVE, | ||||
|                               0, 1, 0); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (wndconfig->maximized) | ||||
|         { | ||||
|             if (_glfw.x11.NET_WM_STATE && | ||||
|                 _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT && | ||||
|                 _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ) | ||||
|             { | ||||
|                 const Atom states[2] = | ||||
|                 { | ||||
|                     _glfw.x11.NET_WM_STATE_MAXIMIZED_VERT, | ||||
|                     _glfw.x11.NET_WM_STATE_MAXIMIZED_HORZ | ||||
|                 }; | ||||
| 
 | ||||
|                 XChangeProperty(_glfw.x11.display, window->x11.handle, | ||||
|                                 _glfw.x11.NET_WM_STATE, XA_ATOM, 32, | ||||
|                                 PropModeReplace, (unsigned char*) &states, 2); | ||||
|             } | ||||
|                             _glfw.x11.NET_WM_STATE, XA_ATOM, 32, | ||||
|                             PropModeReplace, (unsigned char*) &states, 2); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
|     // Declare the WM protocols supported by GLFW
 | ||||
|     { | ||||
|         int count = 0; | ||||
| @ -436,27 +548,7 @@ static GLFWbool createWindow(_GLFWwindow* window, | ||||
|         XFree(hints); | ||||
|     } | ||||
| 
 | ||||
|     // Set ICCCM WM_NORMAL_HINTS property (even if no parts are set)
 | ||||
|     { | ||||
|         XSizeHints* hints = XAllocSizeHints(); | ||||
|         hints->flags = 0; | ||||
| 
 | ||||
|         if (window->monitor) | ||||
|         { | ||||
|             hints->flags |= PPosition; | ||||
|             _glfwPlatformGetMonitorPos(window->monitor, &hints->x, &hints->y); | ||||
|         } | ||||
| 
 | ||||
|         if (!wndconfig->resizable) | ||||
|         { | ||||
|             hints->flags |= (PMinSize | PMaxSize); | ||||
|             hints->min_width  = hints->max_width  = wndconfig->width; | ||||
|             hints->min_height = hints->max_height = wndconfig->height; | ||||
|         } | ||||
| 
 | ||||
|         XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); | ||||
|         XFree(hints); | ||||
|     } | ||||
|     updateNormalHints(window); | ||||
| 
 | ||||
|     // Set ICCCM WM_CLASS property
 | ||||
|     // HACK: Until a mechanism for specifying the application name is added, the
 | ||||
| @ -731,24 +823,17 @@ static GLFWbool acquireMonitor(_GLFWwindow* window) | ||||
|                         DefaultExposures); | ||||
|     } | ||||
| 
 | ||||
|     _glfw.x11.saver.count++; | ||||
|     if (!window->monitor->window) | ||||
|         _glfw.x11.saver.count++; | ||||
| 
 | ||||
|     status = _glfwSetVideoModeX11(window->monitor, &window->videoMode); | ||||
| 
 | ||||
|     if (_glfw.x11.NET_WM_BYPASS_COMPOSITOR) | ||||
|     { | ||||
|         const unsigned long value = 1; | ||||
| 
 | ||||
|         XChangeProperty(_glfw.x11.display,  window->x11.handle, | ||||
|                         _glfw.x11.NET_WM_BYPASS_COMPOSITOR, XA_CARDINAL, 32, | ||||
|                         PropModeReplace, (unsigned char*) &value, 1); | ||||
|     } | ||||
| 
 | ||||
|     // Position the window over its monitor
 | ||||
|     if (window->x11.overrideRedirect) | ||||
|     { | ||||
|         int xpos, ypos; | ||||
|         GLFWvidmode mode; | ||||
| 
 | ||||
|         // Manually position the window over its monitor
 | ||||
|         _glfwPlatformGetMonitorPos(window->monitor, &xpos, &ypos); | ||||
|         _glfwPlatformGetVideoMode(window->monitor, &mode); | ||||
| 
 | ||||
| @ -756,31 +841,6 @@ static GLFWbool acquireMonitor(_GLFWwindow* window) | ||||
|                           xpos, ypos, mode.width, mode.height); | ||||
|     } | ||||
| 
 | ||||
|     if (_glfw.x11.xinerama.available && _glfw.x11.NET_WM_FULLSCREEN_MONITORS) | ||||
|     { | ||||
|         sendEventToWM(window, | ||||
|                       _glfw.x11.NET_WM_FULLSCREEN_MONITORS, | ||||
|                       window->monitor->x11.index, | ||||
|                       window->monitor->x11.index, | ||||
|                       window->monitor->x11.index, | ||||
|                       window->monitor->x11.index, | ||||
|                       0); | ||||
|     } | ||||
| 
 | ||||
|     _glfwPlatformFocusWindow(window); | ||||
| 
 | ||||
|     if (_glfw.x11.NET_WM_STATE && _glfw.x11.NET_WM_STATE_FULLSCREEN) | ||||
|     { | ||||
|         // Ask the window manager to make the GLFW window a full screen window
 | ||||
|         // Full screen windows are undecorated and, when focused, are kept
 | ||||
|         // on top of all other windows
 | ||||
|         sendEventToWM(window, | ||||
|                       _glfw.x11.NET_WM_STATE, | ||||
|                       _NET_WM_STATE_ADD, | ||||
|                       _glfw.x11.NET_WM_STATE_FULLSCREEN, | ||||
|                       0, 1, 0); | ||||
|     } | ||||
| 
 | ||||
|     _glfwInputMonitorWindowChange(window->monitor, window); | ||||
|     return status; | ||||
| } | ||||
| @ -1124,9 +1184,6 @@ static void processEvent(XEvent *event) | ||||
| 
 | ||||
|         case ConfigureNotify: | ||||
|         { | ||||
|             if (!window->x11.overrideRedirect && !event->xany.send_event) | ||||
|                 return; | ||||
| 
 | ||||
|             if (event->xconfigure.width != window->x11.width || | ||||
|                 event->xconfigure.height != window->x11.height) | ||||
|             { | ||||
| @ -1145,12 +1202,15 @@ static void processEvent(XEvent *event) | ||||
|             if (event->xconfigure.x != window->x11.xpos || | ||||
|                 event->xconfigure.y != window->x11.ypos) | ||||
|             { | ||||
|                 _glfwInputWindowPos(window, | ||||
|                                     event->xconfigure.x, | ||||
|                                     event->xconfigure.y); | ||||
|                 if (window->x11.overrideRedirect || event->xany.send_event) | ||||
|                 { | ||||
|                     _glfwInputWindowPos(window, | ||||
|                                         event->xconfigure.x, | ||||
|                                         event->xconfigure.y); | ||||
| 
 | ||||
|                 window->x11.xpos = event->xconfigure.x; | ||||
|                 window->x11.ypos = event->xconfigure.y; | ||||
|                     window->x11.xpos = event->xconfigure.x; | ||||
|                     window->x11.ypos = event->xconfigure.y; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return; | ||||
| @ -1459,6 +1519,7 @@ int _glfwPlatformCreateWindow(_GLFWwindow* window, | ||||
|     if (window->monitor) | ||||
|     { | ||||
|         _glfwPlatformShowWindow(window); | ||||
|         updateWindowMode(window); | ||||
|         if (!acquireMonitor(window)) | ||||
|             return GLFW_FALSE; | ||||
|     } | ||||
| @ -1654,31 +1715,13 @@ void _glfwPlatformSetWindowSize(_GLFWwindow* window, int width, int height) | ||||
| { | ||||
|     if (window->monitor) | ||||
|     { | ||||
|         _glfwSetVideoModeX11(window->monitor, &window->videoMode); | ||||
| 
 | ||||
|         if (!_glfw.x11.NET_WM_STATE || !_glfw.x11.NET_WM_STATE_FULLSCREEN) | ||||
|         { | ||||
|             GLFWvidmode mode; | ||||
|             _glfwPlatformGetVideoMode(window->monitor, &mode); | ||||
|             XResizeWindow(_glfw.x11.display, window->x11.handle, | ||||
|                           mode.width, mode.height); | ||||
|         } | ||||
|         if (window->monitor->window == window) | ||||
|             acquireMonitor(window); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         if (!window->resizable) | ||||
|         { | ||||
|             // Update window size restrictions to match new window size
 | ||||
| 
 | ||||
|             XSizeHints* hints = XAllocSizeHints(); | ||||
| 
 | ||||
|             hints->flags |= (PMinSize | PMaxSize); | ||||
|             hints->min_width  = hints->max_width  = width; | ||||
|             hints->min_height = hints->max_height = height; | ||||
| 
 | ||||
|             XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); | ||||
|             XFree(hints); | ||||
|         } | ||||
|             updateNormalHints(window); | ||||
| 
 | ||||
|         XResizeWindow(_glfw.x11.display, window->x11.handle, width, height); | ||||
|     } | ||||
| @ -1690,55 +1733,14 @@ void _glfwPlatformSetWindowSizeLimits(_GLFWwindow* window, | ||||
|                                       int minwidth, int minheight, | ||||
|                                       int maxwidth, int maxheight) | ||||
| { | ||||
|     long supplied; | ||||
|     XSizeHints* hints = XAllocSizeHints(); | ||||
| 
 | ||||
|     if (XGetWMNormalHints(_glfw.x11.display, window->x11.handle, hints, &supplied)) | ||||
|     { | ||||
|         if (minwidth == GLFW_DONT_CARE || minwidth == GLFW_DONT_CARE) | ||||
|             hints->flags &= ~PMinSize; | ||||
|         else | ||||
|         { | ||||
|             hints->flags |= PMinSize; | ||||
|             hints->min_width  = minwidth; | ||||
|             hints->min_height = minheight; | ||||
|         } | ||||
| 
 | ||||
|         if (maxwidth == GLFW_DONT_CARE || maxwidth == GLFW_DONT_CARE) | ||||
|             hints->flags &= ~PMaxSize; | ||||
|         else | ||||
|         { | ||||
|             hints->flags |= PMaxSize; | ||||
|             hints->max_width  = maxwidth; | ||||
|             hints->max_height = maxheight; | ||||
|         } | ||||
| 
 | ||||
|         XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); | ||||
|     } | ||||
| 
 | ||||
|     XFree(hints); | ||||
|     updateNormalHints(window); | ||||
|     XFlush(_glfw.x11.display); | ||||
| } | ||||
| 
 | ||||
| void _glfwPlatformSetWindowAspectRatio(_GLFWwindow* window, int numer, int denom) | ||||
| { | ||||
|     long supplied; | ||||
|     XSizeHints* hints = XAllocSizeHints(); | ||||
| 
 | ||||
|     if (XGetWMNormalHints(_glfw.x11.display, window->x11.handle, hints, &supplied)) | ||||
|     { | ||||
|         if (numer == GLFW_DONT_CARE || denom == GLFW_DONT_CARE) | ||||
|             hints->flags &= ~PAspect; | ||||
|         else | ||||
|         { | ||||
|             hints->flags |= PAspect; | ||||
|             hints->min_aspect.x = hints->max_aspect.x = numer; | ||||
|             hints->min_aspect.y = hints->max_aspect.y = denom; | ||||
|         } | ||||
| 
 | ||||
|         XSetWMNormalHints(_glfw.x11.display, window->x11.handle, hints); | ||||
|     } | ||||
| 
 | ||||
|     XFree(hints); | ||||
|     updateNormalHints(window); | ||||
|     XFlush(_glfw.x11.display); | ||||
| } | ||||
| 
 | ||||
| void _glfwPlatformGetFramebufferSize(_GLFWwindow* window, int* width, int* height) | ||||
| @ -1907,6 +1909,48 @@ void _glfwPlatformFocusWindow(_GLFWwindow* window) | ||||
|     XFlush(_glfw.x11.display); | ||||
| } | ||||
| 
 | ||||
| void _glfwPlatformSetWindowMonitor(_GLFWwindow* window, | ||||
|                                    _GLFWmonitor* monitor, | ||||
|                                    int xpos, int ypos, | ||||
|                                    int width, int height, | ||||
|                                    int refreshRate) | ||||
| { | ||||
|     if (window->monitor == monitor) | ||||
|     { | ||||
|         if (monitor) | ||||
|         { | ||||
|             if (monitor->window == window) | ||||
|                 acquireMonitor(window); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             XMoveResizeWindow(_glfw.x11.display, window->x11.handle, | ||||
|                               xpos, ypos, width, height); | ||||
|         } | ||||
| 
 | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (window->monitor) | ||||
|         releaseMonitor(window); | ||||
| 
 | ||||
|     _glfwInputWindowMonitorChange(window, monitor); | ||||
|     updateWindowMode(window); | ||||
| 
 | ||||
|     if (window->monitor) | ||||
|     { | ||||
|         XMapRaised(_glfw.x11.display, window->x11.handle); | ||||
|         acquireMonitor(window); | ||||
|     } | ||||
|     else | ||||
|     { | ||||
|         XMoveResizeWindow(_glfw.x11.display, window->x11.handle, | ||||
|                           xpos, ypos, width, height); | ||||
|     } | ||||
| 
 | ||||
|     XFlush(_glfw.x11.display); | ||||
| } | ||||
| 
 | ||||
| int _glfwPlatformWindowFocused(_GLFWwindow* window) | ||||
| { | ||||
|     Window focused; | ||||
|  | ||||
| @ -36,6 +36,8 @@ | ||||
| 
 | ||||
| #include "getopt.h" | ||||
| 
 | ||||
| static int windowed_xpos, windowed_ypos, windowed_width, windowed_height; | ||||
| 
 | ||||
| static void usage(void) | ||||
| { | ||||
|     printf("Usage: iconify [-h] [-f [-a] [-n]]\n"); | ||||
| @ -74,6 +76,34 @@ static void key_callback(GLFWwindow* window, int key, int scancode, int action, | ||||
|         case GLFW_KEY_ESCAPE: | ||||
|             glfwSetWindowShouldClose(window, GLFW_TRUE); | ||||
|             break; | ||||
|         case GLFW_KEY_ENTER: | ||||
|         { | ||||
|             if (mods != GLFW_MOD_ALT) | ||||
|                 return; | ||||
| 
 | ||||
|             if (glfwGetWindowMonitor(window)) | ||||
|             { | ||||
|                 glfwSetWindowMonitor(window, NULL, | ||||
|                                      windowed_xpos, windowed_ypos, | ||||
|                                      windowed_width, windowed_height, | ||||
|                                      0); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 GLFWmonitor* monitor = glfwGetPrimaryMonitor(); | ||||
|                 if (monitor) | ||||
|                 { | ||||
|                     const GLFWvidmode* mode = glfwGetVideoMode(monitor); | ||||
|                     glfwGetWindowPos(window, &windowed_xpos, &windowed_ypos); | ||||
|                     glfwGetWindowSize(window, &windowed_width, &windowed_height); | ||||
|                     glfwSetWindowMonitor(window, monitor, | ||||
|                                          0, 0, mode->width, mode->height, | ||||
|                                          mode->refreshRate); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user