Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

settings: made monitors selectable in fullscreen modes #17648

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion OpenRA.Game/Graphics/PlatformInterfaces.cs
Expand Up @@ -17,7 +17,7 @@ namespace OpenRA
{
public interface IPlatform
{
IPlatformWindow CreateWindow(Size size, WindowMode windowMode, float scaleModifier, int batchSize);
IPlatformWindow CreateWindow(Size size, WindowMode windowMode, float scaleModifier, int batchSize, int videoDisplay);
ISoundEngine CreateSound(string device);
IFont CreateFont(byte[] data);
}
Expand All @@ -44,6 +44,8 @@ public interface IPlatformWindow : IDisposable
float NativeWindowScale { get; }
float EffectiveWindowScale { get; }
Size SurfaceSize { get; }
int DisplayCount { get; }
int CurrentDisplay { get; }

event Action<float, float, float, float> OnWindowScaleChanged;

Expand Down
12 changes: 11 additions & 1 deletion OpenRA.Game/Renderer.cs
Expand Up @@ -66,7 +66,7 @@ public Renderer(IPlatform platform, GraphicSettings graphicSettings)
this.platform = platform;
var resolution = GetResolution(graphicSettings);

Window = platform.CreateWindow(new Size(resolution.Width, resolution.Height), graphicSettings.Mode, graphicSettings.UIScale, graphicSettings.BatchSize);
Window = platform.CreateWindow(new Size(resolution.Width, resolution.Height), graphicSettings.Mode, graphicSettings.UIScale, graphicSettings.BatchSize, graphicSettings.VideoDisplay);
Context = Window.Context;

TempBufferSize = graphicSettings.BatchSize;
Expand Down Expand Up @@ -478,5 +478,15 @@ public IFont CreateFont(byte[] data)
{
return platform.CreateFont(data);
}

public int DisplayCount
{
get { return Window.DisplayCount; }
}

public int CurrentDisplay
{
get { return Window.CurrentDisplay; }
}
}
}
3 changes: 3 additions & 0 deletions OpenRA.Game/Settings.cs
Expand Up @@ -176,6 +176,9 @@ public class GraphicSettings
[Desc("Use OpenGL ES if both ES and regular OpenGL are available.")]
public bool PreferGLES = false;

[Desc("Display index to use in a multi-monitor fullscreen setup.")]
public int VideoDisplay = 0;

public int BatchSize = 8192;
public int SheetSize = 2048;

Expand Down
3 changes: 3 additions & 0 deletions OpenRA.Mods.Common/LoadScreens/BlankLoadScreen.cs
Expand Up @@ -121,6 +121,9 @@ public virtual bool BeforeLoad()
Game.Renderer.SetUIScale(1.0f);
}

// Saved settings may have been invalidated by a hardware change
Game.Settings.Graphics.VideoDisplay = Game.Renderer.CurrentDisplay;

// If a ModContent section is defined then we need to make sure that the
// required content is installed or switch to the defined content installer.
if (!ModData.Manifest.Contains<ModContent>())
Expand Down
30 changes: 29 additions & 1 deletion OpenRA.Mods.Common/Widgets/Logic/SettingsLogic.cs
Expand Up @@ -23,6 +23,7 @@ public class SettingsLogic : ChromeLogic
{
enum PanelType { Display, Audio, Input, Hotkeys, Advanced }

static readonly int OriginalVideoDisplay;
static readonly string OriginalSoundDevice;
static readonly WindowMode OriginalGraphicsMode;
static readonly int2 OriginalGraphicsWindowedSize;
Expand Down Expand Up @@ -52,6 +53,7 @@ static SettingsLogic()
var original = Game.Settings;
OriginalSoundDevice = original.Sound.Device;
OriginalGraphicsMode = original.Graphics.Mode;
OriginalVideoDisplay = original.Graphics.VideoDisplay;
OriginalGraphicsWindowedSize = original.Graphics.WindowedSize;
OriginalGraphicsFullscreenSize = original.Graphics.FullscreenSize;
OriginalServerDiscoverNatDevices = original.Server.DiscoverNatDevices;
Expand Down Expand Up @@ -92,6 +94,7 @@ public SettingsLogic(Widget widget, Action onExit, ModData modData, WorldRendere
Action closeAndExit = () => { Ui.CloseWindow(); onExit(); };
if (current.Sound.Device != OriginalSoundDevice ||
current.Graphics.Mode != OriginalGraphicsMode ||
current.Graphics.VideoDisplay != OriginalVideoDisplay ||
current.Graphics.WindowedSize != OriginalGraphicsWindowedSize ||
current.Graphics.FullscreenSize != OriginalGraphicsFullscreenSize ||
current.Server.DiscoverNatDevices != OriginalServerDiscoverNatDevices)
Expand Down Expand Up @@ -250,7 +253,14 @@ Action InitDisplayPanel(Widget panel)
"Windowed" : ds.Mode == WindowMode.Fullscreen ? "Fullscreen (Legacy)" : "Fullscreen";

var modeChangesDesc = panel.Get("MODE_CHANGES_DESC");
modeChangesDesc.IsVisible = () => ds.Mode != WindowMode.Windowed && ds.Mode != OriginalGraphicsMode;
modeChangesDesc.IsVisible = () => ds.Mode != WindowMode.Windowed && (ds.Mode != OriginalGraphicsMode ||
ds.VideoDisplay != OriginalVideoDisplay);

var displaySelectionDropDown = panel.Get<DropDownButtonWidget>("DISPLAY_SELECTION_DROPDOWN");
displaySelectionDropDown.OnMouseDown = _ => ShowDisplaySelectionDropdown(displaySelectionDropDown, ds);
var displaySelectionLabel = new CachedTransform<int, string>(i => "Display {0}".F(i + 1));
displaySelectionDropDown.GetText = () => displaySelectionLabel.Update(ds.VideoDisplay);
displaySelectionDropDown.IsDisabled = () => Game.Renderer.DisplayCount < 2;

var statusBarsDropDown = panel.Get<DropDownButtonWidget>("STATUS_BAR_DROPDOWN");
statusBarsDropDown.OnMouseDown = _ => ShowStatusBarsDropdown(statusBarsDropDown, gs);
Expand Down Expand Up @@ -289,6 +299,7 @@ Action InitDisplayPanel(Widget panel)

uiScaleDropdown.IsDisabled = () => disableUIScale;

panel.Get("DISPLAY_SELECTION").IsVisible = () => ds.Mode != WindowMode.Windowed;
panel.Get("WINDOW_RESOLUTION").IsVisible = () => ds.Mode == WindowMode.Windowed;
var windowWidth = panel.Get<TextFieldWidget>("WINDOW_WIDTH");
var origWidthText = windowWidth.Text = ds.WindowedSize.X.ToString();
Expand Down Expand Up @@ -369,6 +380,7 @@ Action ResetDisplayPanel(Widget panel)
ds.MaxFramerate = dds.MaxFramerate;
ds.Language = dds.Language;
ds.Mode = dds.Mode;
ds.VideoDisplay = dds.VideoDisplay;
ds.WindowedSize = dds.WindowedSize;
ds.CursorDouble = dds.CursorDouble;
ds.ViewportDistance = dds.ViewportDistance;
Expand Down Expand Up @@ -830,6 +842,22 @@ static void ShowStatusBarsDropdown(DropDownButtonWidget dropdown, GameSettings s
dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, options.Keys, setupItem);
}

static void ShowDisplaySelectionDropdown(DropDownButtonWidget dropdown, GraphicSettings s)
{
Func<int, ScrollItemWidget, ScrollItemWidget> setupItem = (o, itemTemplate) =>
{
var item = ScrollItemWidget.Setup(itemTemplate,
() => s.VideoDisplay == o,
() => s.VideoDisplay = o);

var label = "Display {0}".F(o + 1);
item.Get<LabelWidget>("LABEL").GetText = () => label;
return item;
};

dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 500, Enumerable.Range(0, Game.Renderer.DisplayCount), setupItem);
}

static void ShowTargetLinesDropdown(DropDownButtonWidget dropdown, GameSettings s)
{
var options = new Dictionary<string, TargetLinesType>()
Expand Down
4 changes: 2 additions & 2 deletions OpenRA.Platforms.Default/DefaultPlatform.cs
Expand Up @@ -16,9 +16,9 @@ namespace OpenRA.Platforms.Default
{
public class DefaultPlatform : IPlatform
{
public IPlatformWindow CreateWindow(Size size, WindowMode windowMode, float scaleModifier, int batchSize)
public IPlatformWindow CreateWindow(Size size, WindowMode windowMode, float scaleModifier, int batchSize, int videoDisplay)
{
return new Sdl2PlatformWindow(size, windowMode, scaleModifier, batchSize);
return new Sdl2PlatformWindow(size, windowMode, scaleModifier, batchSize, videoDisplay);
}

public ISoundEngine CreateSound(string device)
Expand Down
32 changes: 23 additions & 9 deletions OpenRA.Platforms.Default/Sdl2PlatformWindow.cs
Expand Up @@ -87,12 +87,28 @@ public Size SurfaceSize
}
}

public int CurrentDisplay
{
get
{
return SDL.SDL_GetWindowDisplayIndex(window);
}
}

public int DisplayCount
{
get
{
return SDL.SDL_GetNumVideoDisplays();
}
}

public event Action<float, float, float, float> OnWindowScaleChanged = (oldNative, oldEffective, newNative, newEffective) => { };

[DllImport("user32.dll")]
static extern bool SetProcessDPIAware();

public Sdl2PlatformWindow(Size requestEffectiveWindowSize, WindowMode windowMode, float scaleModifier, int batchSize)
public Sdl2PlatformWindow(Size requestEffectiveWindowSize, WindowMode windowMode, float scaleModifier, int batchSize, int videoDisplay)
{
// Lock the Window/Surface properties until initialization is complete
lock (syncObject)
Expand Down Expand Up @@ -129,16 +145,19 @@ public Sdl2PlatformWindow(Size requestEffectiveWindowSize, WindowMode windowMode

Console.WriteLine("Using SDL 2 with OpenGL{0} renderer", useGLES ? " ES" : "");

if (videoDisplay < 0 || videoDisplay >= DisplayCount)
videoDisplay = 0;

SDL.SDL_DisplayMode display;
SDL.SDL_GetCurrentDisplayMode(0, out display);
SDL.SDL_GetCurrentDisplayMode(videoDisplay, out display);
everclear72216 marked this conversation as resolved.
Show resolved Hide resolved

// Windows and Linux define window sizes in native pixel units.
// Query the display/dpi scale so we can convert our requested effective size to pixels.
// This is not necessary on macOS, which defines window sizes in effective units ("points").
if (Platform.CurrentPlatform == PlatformType.Windows)
{
float ddpi, hdpi, vdpi;
if (SDL.SDL_GetDisplayDPI(0, out ddpi, out hdpi, out vdpi) == 0)
if (SDL.SDL_GetDisplayDPI(videoDisplay, out ddpi, out hdpi, out vdpi) == 0)
windowScale = ddpi / 96;
}
else if (Platform.CurrentPlatform != PlatformType.OSX)
Expand Down Expand Up @@ -166,7 +185,7 @@ public Sdl2PlatformWindow(Size requestEffectiveWindowSize, WindowMode windowMode
if (Platform.CurrentPlatform == PlatformType.OSX && windowMode == WindowMode.Fullscreen)
SDL.SDL_SetHint(SDL.SDL_HINT_VIDEO_HIGHDPI_DISABLED, "1");

window = SDL.SDL_CreateWindow("OpenRA", SDL.SDL_WINDOWPOS_CENTERED, SDL.SDL_WINDOWPOS_CENTERED,
window = SDL.SDL_CreateWindow("OpenRA", SDL.SDL_WINDOWPOS_CENTERED_DISPLAY(videoDisplay), SDL.SDL_WINDOWPOS_CENTERED_DISPLAY(videoDisplay),
windowSize.Width, windowSize.Height, windowFlags);

// Work around an issue in macOS's GL backend where the window remains permanently black
Expand Down Expand Up @@ -235,11 +254,6 @@ public Sdl2PlatformWindow(Size requestEffectiveWindowSize, WindowMode windowMode
}
else if (windowMode == WindowMode.PseudoFullscreen)
{
// Work around a visual glitch in OSX: the window is offset
// partially offscreen if the dock is at the left of the screen
if (Platform.CurrentPlatform == PlatformType.OSX)
SDL.SDL_SetWindowPosition(Window, 0, 0);

SDL.SDL_SetWindowFullscreen(Window, (uint)SDL.SDL_WindowFlags.SDL_WINDOW_FULLSCREEN_DESKTOP);
SDL.SDL_SetHint(SDL.SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
}
Expand Down
28 changes: 21 additions & 7 deletions mods/cnc/chrome/settings.yaml
Expand Up @@ -200,13 +200,6 @@ Container@SETTINGS_PANEL:
Height: 25
Font: Regular
Text: Windowed
Label@MODE_CHANGES_DESC:
X: 100
Y: 237
Width: 200
Height: 15
Font: Tiny
Text: Video mode changes require restart
Container@WINDOW_RESOLUTION:
Y: 240
Children:
Expand Down Expand Up @@ -242,6 +235,27 @@ Container@SETTINGS_PANEL:
Height: 15
Font: Tiny
Text: Video mode and window size changes require restart
Container@DISPLAY_SELECTION:
Y: 240
Children:
Label@DISPLAY_SELECTION_LABEL:
X: 15
Height: 25
Width: 120
Align: Right
Text: Select Display:
DropDownButton@DISPLAY_SELECTION_DROPDOWN:
X: 140
Width: 160
Height: 25
Font: Regular
Label@MODE_CHANGES_DESC:
X: 60
Y: 27
Width: 200
Height: 15
Font: Tiny
Text: Video mode and display changes require restart
Checkbox@VSYNC_CHECKBOX:
X: 310
Y: 210
Expand Down
29 changes: 22 additions & 7 deletions mods/common/chrome/settings.yaml
Expand Up @@ -214,13 +214,6 @@ Background@SETTINGS_PANEL:
Height: 25
Font: Regular
Text: Windowed
Label@MODE_CHANGES_DESC:
X: 100
Y: 237
Width: 200
Height: 15
Font: Tiny
Text: Video mode changes require restart
Checkbox@VSYNC_CHECKBOX:
X: 310
Y: 213
Expand Down Expand Up @@ -263,6 +256,28 @@ Background@SETTINGS_PANEL:
Height: 15
Font: Tiny
Text: Video mode and window size changes require restart
Container@DISPLAY_SELECTION:
Y: 240
Children:
Label@DISPLAY_SELECTION_LABEL:
X: 15
Height: 25
Width: 120
Align: Right
Text: Select Display:
DropDownButton@DISPLAY_SELECTION_DROPDOWN:
X: 140
Width: 160
Height: 25
Font: Regular
Text: Standard
Label@MODE_CHANGES_DESC:
X: 60
Y: 27
Width: 200
Height: 15
Font: Tiny
Text: Video mode and display changes require restart
Checkbox@FRAME_LIMIT_CHECKBOX:
X: 310
Y: 243
Expand Down