mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 22:30:43 +02:00
Merge pull request #302 from daleglass-overte/allow-fullscreen-display-selection
Allow fullscreen display selection
This commit is contained in:
commit
90efffa2fb
7 changed files with 289 additions and 20 deletions
|
@ -50,8 +50,8 @@ FocusScope {
|
|||
|
||||
function previousItem() { root.currentHighLightedIndex = (root.currentHighLightedIndex + comboBox.count - 1) % comboBox.count; }
|
||||
function nextItem() { root.currentHighLightedIndex = (root.currentHighLightedIndex + comboBox.count + 1) % comboBox.count; }
|
||||
function selectCurrentItem() { root.currentIndex = root.currentHighLightedIndex; close(); /*hideList();*/ }
|
||||
function selectSpecificItem(index) { root.currentIndex = index; close();/*hideList();*/ }
|
||||
function selectCurrentItem() { root.currentIndex = root.currentHighLightedIndex; /*hideList();*/ }
|
||||
function selectSpecificItem(index) { root.currentIndex = index; /*hideList();*/ }
|
||||
|
||||
Keys.onUpPressed: previousItem();
|
||||
Keys.onDownPressed: nextItem();
|
||||
|
|
|
@ -481,6 +481,106 @@ Item {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
Layout.topMargin: 20
|
||||
Layout.preferredWidth: parent.width
|
||||
spacing: 0
|
||||
|
||||
Item {
|
||||
Layout.preferredWidth: parent.width
|
||||
Layout.preferredHeight: 35
|
||||
|
||||
HifiStylesUit.RalewayRegular {
|
||||
id: fullScreenDisplayHeader
|
||||
text: "Full screen display"
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
width: 130
|
||||
height: parent.height
|
||||
size: 16
|
||||
color: "#FFFFFF"
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: fullScreenDisplayModel
|
||||
|
||||
ListElement {
|
||||
text: "Screen 1"
|
||||
}
|
||||
|
||||
function refreshScreens() {
|
||||
fullScreenDisplayModel.clear();
|
||||
Render.getScreens().forEach(function(screen) {
|
||||
fullScreenDisplayModel.append({"text" : screen});
|
||||
});
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
fullScreenDisplayModel.refreshScreens();
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.ComboBox {
|
||||
id: fullScreenDisplayDropdown
|
||||
anchors.left: fullScreenDisplayHeader.right
|
||||
anchors.leftMargin: 20
|
||||
anchors.top: parent.top
|
||||
width: 280
|
||||
height: parent.height
|
||||
colorScheme: hifi.colorSchemes.dark
|
||||
model: fullScreenDisplayModel
|
||||
currentIndex: 0
|
||||
|
||||
function refreshFullScreenDisplayDropdown() {
|
||||
var screens = Render.getScreens();
|
||||
var selected = Render.getFullScreenScreen();
|
||||
|
||||
for(let idx = 0; idx < screens.length; idx++) {
|
||||
if (screens[idx] == selected) {
|
||||
fullScreenDisplayDropdown.currentIndex = idx;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
console.log("Selected full screen screen", selected, "not found, falling back to primary screen");
|
||||
console.log("List of screens is:", screens);
|
||||
fullScreenDisplayDropdown.currentIndex = 0;
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
model.refreshScreens();
|
||||
fullScreenDisplayDropdown.refreshFullScreenDisplayDropdown();
|
||||
fullScreenDisplayDropdown.displayText = model.get(currentIndex).text;
|
||||
}
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
if (currentIndex >= 0) {
|
||||
// Somehow, we end up going through here twice on every change of the combo box.
|
||||
// The first one is with the new selected index, and the second one is with the
|
||||
// index at -1.
|
||||
//
|
||||
// The first one comes from a sensible stack of:
|
||||
// onCurrentIndexChanged (qrc:/qml/hifi/dialogs/graphics/GraphicsSettings.qml:559)
|
||||
// refreshScreens (qrc:/qml/hifi/dialogs/graphics/GraphicsSettings.qml:514)
|
||||
// onCompleted (qrc:/qml/hifi/dialogs/graphics/GraphicsSettings.qml:553)
|
||||
// load (qrc:/qml/hifi/tablet/WindowRoot.qml:170)
|
||||
// loadSource (qrc:/qml/hifi/tablet/WindowRoot.qml:63)
|
||||
//
|
||||
// The second seems to be called out of nowhere. This likely indicates some sort of bug.
|
||||
// Might be related to Wayland?
|
||||
|
||||
Render.setFullScreenScreen(model.get(currentIndex).text);
|
||||
fullScreenDisplayDropdown.displayText = model.get(currentIndex).text;
|
||||
} else {
|
||||
console.log("Called with currentIndex =", currentIndex);
|
||||
console.trace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#include "RenderScriptingInterface.h"
|
||||
|
||||
#include "LightingModel.h"
|
||||
#include <QScreen>
|
||||
#include "ScreenName.h"
|
||||
|
||||
|
||||
RenderScriptingInterface* RenderScriptingInterface::getInstance() {
|
||||
|
@ -23,6 +25,7 @@ RenderScriptingInterface::RenderScriptingInterface() {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
void RenderScriptingInterface::loadSettings() {
|
||||
_renderSettingLock.withReadLock([&] {
|
||||
_renderMethod = (_renderMethodSetting.get());
|
||||
|
@ -31,7 +34,17 @@ void RenderScriptingInterface::loadSettings() {
|
|||
//_antialiasingMode = (_antialiasingModeSetting.get());
|
||||
_antialiasingMode = static_cast<AntialiasingConfig::Mode>(_antialiasingModeSetting.get());
|
||||
_viewportResolutionScale = (_viewportResolutionScaleSetting.get());
|
||||
_fullScreenScreen = (_fullScreenScreenSetting.get());
|
||||
});
|
||||
|
||||
// If full screen screen is not initialized, or set to an invalid value,
|
||||
// set to the first screen.
|
||||
auto screens = getScreens();
|
||||
if (std::find(screens.begin(), screens.end(), _fullScreenScreen) == screens.end()) {
|
||||
setFullScreenScreen(screens.first());
|
||||
}
|
||||
|
||||
|
||||
forceRenderMethod((RenderMethod)_renderMethod);
|
||||
forceShadowsEnabled(_shadowsEnabled);
|
||||
forceAmbientOcclusionEnabled(_ambientOcclusionEnabled);
|
||||
|
@ -193,6 +206,41 @@ void RenderScriptingInterface::setViewportResolutionScale(float scale) {
|
|||
}
|
||||
}
|
||||
|
||||
QStringList RenderScriptingInterface::getScreens() const {
|
||||
QStringList screens;
|
||||
|
||||
for(QScreen *screen : qApp->screens()) {
|
||||
screens << ScreenName::getNameForScreen(screen);
|
||||
}
|
||||
|
||||
return screens;
|
||||
}
|
||||
|
||||
bool RenderScriptingInterface::setFullScreenScreen(QString name) {
|
||||
auto screens = getScreens();
|
||||
|
||||
if (std::find(screens.begin(), screens.end(), name) == screens.end()) {
|
||||
// Screens can come and go and don't have a stable opaque ID, so we
|
||||
// go by model here. For multiple screens with the same model we get names
|
||||
// that include a serial number, so it works.
|
||||
return false;
|
||||
}
|
||||
|
||||
_renderSettingLock.withWriteLock([&] {
|
||||
_fullScreenScreen = name;
|
||||
_fullScreenScreenSetting.set(name);
|
||||
});
|
||||
|
||||
emit settingsChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
QString RenderScriptingInterface::getFullScreenScreen() const {
|
||||
return _fullScreenScreen;
|
||||
}
|
||||
|
||||
|
||||
void RenderScriptingInterface::forceViewportResolutionScale(float scale) {
|
||||
// just not negative values or zero
|
||||
if (scale <= 0.f) {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include "RenderForward.h"
|
||||
#include "AntialiasingEffect.h"
|
||||
|
||||
#include <QScreen>
|
||||
|
||||
/*@jsdoc
|
||||
* The <code>Render</code> API enables you to configure the graphics engine.
|
||||
|
@ -74,6 +74,7 @@ public:
|
|||
// Need to be called on start up to re-initialize the runtime to the saved setting states
|
||||
void loadSettings();
|
||||
|
||||
|
||||
public slots:
|
||||
/*@jsdoc
|
||||
* Gets the configuration for a rendering job by name.
|
||||
|
@ -172,6 +173,30 @@ public slots:
|
|||
*/
|
||||
void setViewportResolutionScale(float resolutionScale);
|
||||
|
||||
/*@jsdoc
|
||||
* Returns the list of screens
|
||||
* @function Render.getScreens
|
||||
* @returns {string[]} The names of the available screens
|
||||
*/
|
||||
QStringList getScreens() const;
|
||||
|
||||
/*@jsdoc
|
||||
* Gets the screen used when switching to full screen mode
|
||||
* @function Render.getFullScreenScreen
|
||||
* @returns {string} The name of the screen used for full screen mode
|
||||
*/
|
||||
QString getFullScreenScreen() const;
|
||||
|
||||
/*@jsdoc
|
||||
* Sets the screen used when switching to full screen mode
|
||||
* This function will only succeed if the name passed is one of the entries from Render.getScreens.
|
||||
* Otherwise, it will return False and have no effect.
|
||||
*
|
||||
* @function Render.setFullScreenScreen
|
||||
* @returns {bool} True if the setting was successful
|
||||
*/
|
||||
bool setFullScreenScreen(QString name);
|
||||
|
||||
signals:
|
||||
|
||||
/*@jsdoc
|
||||
|
@ -196,6 +221,8 @@ private:
|
|||
bool _ambientOcclusionEnabled{ false };
|
||||
AntialiasingConfig::Mode _antialiasingMode{ AntialiasingConfig::Mode::NONE };
|
||||
float _viewportResolutionScale{ 1.0f };
|
||||
QString _fullScreenScreen;
|
||||
|
||||
|
||||
// Actual settings saved on disk
|
||||
Setting::Handle<int> _renderMethodSetting { "renderMethod", RENDER_FORWARD ? render::Args::RenderMethod::FORWARD : render::Args::RenderMethod::DEFERRED };
|
||||
|
@ -204,6 +231,7 @@ private:
|
|||
//Setting::Handle<AntialiasingConfig::Mode> _antialiasingModeSetting { "antialiasingMode", AntialiasingConfig::Mode::TAA };
|
||||
Setting::Handle<int> _antialiasingModeSetting { "antialiasingMode", AntialiasingConfig::Mode::NONE };
|
||||
Setting::Handle<float> _viewportResolutionScaleSetting { "viewportResolutionScale", 1.0f };
|
||||
Setting::Handle<QString> _fullScreenScreenSetting { "fullScreenScreen", "" };
|
||||
|
||||
// Force assign both setting AND runtime value to the parameter value
|
||||
void forceRenderMethod(RenderMethod renderMethod);
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
|
||||
#include <ui-plugins/PluginContainer.h>
|
||||
#include <PathUtils.h>
|
||||
#include "SettingHandle.h"
|
||||
#include "ScreenName.h"
|
||||
|
||||
|
||||
const QString Basic2DWindowOpenGLDisplayPlugin::NAME("Desktop");
|
||||
|
||||
|
@ -165,8 +168,17 @@ bool Basic2DWindowOpenGLDisplayPlugin::isThrottled() const {
|
|||
return _isThrottled;
|
||||
}
|
||||
|
||||
// FIXME target the screen the window is currently on
|
||||
QScreen* Basic2DWindowOpenGLDisplayPlugin::getFullscreenTarget() {
|
||||
Setting::Handle<QString> _fullScreenScreenSetting { "fullScreenScreen", "" };
|
||||
QString selectedModel = _fullScreenScreenSetting.get();
|
||||
|
||||
for(QScreen *screen : qApp->screens()) {
|
||||
if (ScreenName::getNameForScreen(screen) == selectedModel) {
|
||||
return screen;
|
||||
}
|
||||
}
|
||||
|
||||
qWarning() << "Failed to find selected screen" << selectedModel << "for full screen mode, using primary screen";
|
||||
return qApp->primaryScreen();
|
||||
}
|
||||
|
||||
|
|
49
libraries/ui/src/ScreenName.cpp
Normal file
49
libraries/ui/src/ScreenName.cpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// Created by Dale Glass on 7/01/2023
|
||||
// Copyright 2023 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "ScreenName.h"
|
||||
|
||||
QString ScreenName::getNameForScreen(QScreen *screen) {
|
||||
// The data provided by QScreen isn't as convenient as it could be.
|
||||
// So far testing shows:
|
||||
//
|
||||
// Windows:
|
||||
// model() returns an empty string
|
||||
// name() returns something like \\.\DISPLAY1
|
||||
//
|
||||
// Linux:
|
||||
// model() returns a name, like "LG Ultra HD/525000"
|
||||
// name() returns the output's name, like "HDMI1"
|
||||
|
||||
// So we try to assemble something unique and readable from all the possibilities.
|
||||
|
||||
QString ret;
|
||||
bool addParens = false;
|
||||
|
||||
ret.append(screen->manufacturer());
|
||||
|
||||
if (!ret.isEmpty()) {
|
||||
ret.append(" - ");
|
||||
}
|
||||
ret.append(screen->model());
|
||||
|
||||
addParens = !ret.isEmpty();
|
||||
|
||||
if(addParens) {
|
||||
ret.append(" (");
|
||||
}
|
||||
|
||||
ret.append(screen->name().replace(QString("\\\\.\\"), QString("")));
|
||||
|
||||
|
||||
if(addParens) {
|
||||
ret.append(")");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
32
libraries/ui/src/ScreenName.h
Normal file
32
libraries/ui/src/ScreenName.h
Normal file
|
@ -0,0 +1,32 @@
|
|||
//
|
||||
// Created by Dale Glass on 7/01/2023
|
||||
// Copyright 2023 Overte e.V.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <QScreen>
|
||||
#include <QString>
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @brief Screen naming
|
||||
*
|
||||
* This class exists because display-plugins and interface need to share the same,
|
||||
* fairly involved rule for converting QScreen data to user-facing text.
|
||||
*/
|
||||
class ScreenName {
|
||||
public:
|
||||
/**
|
||||
* @brief Get a descriptive name for a screen
|
||||
*
|
||||
* This is used in the graphics settings, to name monitors. This function tries to generate
|
||||
* human friendly and unique, even if two identical monitors are present.
|
||||
*
|
||||
* @param screen Screen to provide a name for
|
||||
* @return QString Descriptive name for the screen
|
||||
*/
|
||||
static QString getNameForScreen(QScreen *screen);
|
||||
|
||||
};
|
Loading…
Reference in a new issue