diff --git a/BUILD_LINUX.md b/BUILD_LINUX.md
index ae0a88a98e..ed82d097f8 100644
--- a/BUILD_LINUX.md
+++ b/BUILD_LINUX.md
@@ -1,75 +1,81 @@
# Build Linux
-*Last Updated on December 1, 2020*
+*Last Updated on January 6, 2022*
Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only Linux specific instructions are found in this file.
You can use the [Vircadia Builder](https://github.com/vircadia/vircadia-builder) to build on Linux more easily. Alternatively, you can follow the manual steps below.
-## Ubuntu 16.04/18.04 specific build guide
-### Ubuntu 16.04 only
-Add the following line to *.bash_profile*
-`export QT_QPA_FONTDIR=/usr/share/fonts/truetype/dejavu/`
-### Ubuntu 18.04 server only
+## Ubuntu 18.04
+
+### Ubuntu 18.04 Server only
Add the universe repository:
-_(This is not enabled by default on the server edition)_
+_(This is not enabled by default on the server edition.)_
```bash
sudo add-apt-repository universe
sudo apt-get update
```
-#### Install build tools:
+
+### Install build tools:
- First update the repositories:
```bash
sudo apt-get update -y
sudo apt-get upgrade -y
```
-- git
+
+- Install git
```bash
sudo apt-get install git -y
```
-Verify by git --version
-- g++
+Verify git was installed by running `git --version`.
+
+- Install g++
```bash
sudo apt-get install g++ -y
```
-Verify by g++ --version
-- *Ubuntu 18.04* cmake
+Verify g++ was installed by running `g++ --version`.
+
+- **Ubuntu 18.04** CMake
```bash
sudo apt-get install cmake -y
```
-Verify by cmake --version
-- *Ubuntu 16.04* cmake
-```bash
-wget https://cmake.org/files/v3.14/cmake-3.14.2-Linux-x86_64.sh
-sudo sh cmake-3.14.2-Linux-x86_64.sh --prefix=/usr/local --exclude-subdir
-```
-#### Install build dependencies:
+Verify CMake was installed by running `cmake --version`.
+
+### Install build dependencies:
- OpenSSL:
```bash
sudo apt-get install libssl-dev
```
-Verify with `openssl version`
+Verify OpenSSL was installed by running `openssl version`.
+
- OpenGL:
```bash
sudo apt-get install libgl1-mesa-dev -y
-sudo ln -s /usr/lib/x86_64-linux-gnu/libGL.so.346.35 /usr/lib/x86_64-linux-gnu/libGL.so.1.2.0
```
-- Verify OpenGL:
- - First install mesa-utils with the command `sudo apt install mesa-utils -y`
- - Then run `glxinfo | grep "OpenGL version"`
-#### To compile interface in a server you must install:
+Verify OpenGL:
+ - First install mesa-utils with the command `sudo apt install mesa-utils -y`.
+ - Then run `glxinfo | grep "OpenGL version"`.
+
+
+### Extra dependencies to compile Interface on a server
+
+
+- Install the following:
```bash
sudo apt-get -y install libpulse0 libnss3 libnspr4 libfontconfig1 libxcursor1 libxcomposite1 libxtst6 libxslt1.1
```
+
- Misc dependencies:
```bash
sudo apt-get install libasound2 libxmu-dev libxi-dev freeglut3-dev libasound2-dev libjack0 libjack-dev libxrandr-dev libudev-dev libssl-dev zlib1g-dev
```
+
- Install Python 3 and required packages:
```bash
sudo apt-get install python python3 python3-distro
```
-- Install node, required to build the jsdoc documentation:
+
+- Install Node.js as it is required to build the jsdoc documentation:
```bash
sudo apt-get install nodejs
```
@@ -81,16 +87,17 @@ Clone this repository:
git clone https://github.com/vircadia/vircadia.git
```
-To compile a DEV version checkout the branch you need. To get a list of all tags:
-```bash
-git fetch -a
-```
-
-Then checkout the main branch with:
+Then checkout the master branch with:
```bash
git checkout master
```
+If you need a different branch, you can get a list of all tags with:
+```bash
+git fetch --tags
+git tag
+```
+
### Using a custom Qt build
Qt binaries are only provided for Ubuntu. In order to build on other distributions, a Qt5 install
@@ -104,6 +111,18 @@ The system's Qt can be used, if the development packages are installed, by setti
also the last version available in the Qt 5 branch. It is expected that Linux distributions will have
Qt 5.15.2 available for a long time.
+### Architecture support
+
+If the build is intended to be packaged for distribution, the `VIRCADIA_CPU_ARCHITECTURE`
+CMake variable needs to be set to an architecture specific value.
+
+By default, it is set to `-march=native -mtune=native`, which yields builds optimized for a particular
+machine, but these builds will not work on machines lacking same CPU instructions.
+
+For packaging, it is recommended to set it to a different value, for example `-msse3`. This will help ensure that the build will run on all reasonably modern CPUs.
+
+Setting `VIRCADIA_CPU_ARCHITECTURE` to an empty string will use the default compiler settings and yield maximum compatibility.
+
### Compiling
Create the build directory:
@@ -118,33 +137,34 @@ Prepare makefiles:
cmake ..
```
-- If cmake fails with a vcpkg error - delete /tmp/hifi/vcpkg.
+If cmake fails with a vcpkg error, then delete `~/vircadia-files/vcpkg/`.
-Start compilation of the server and get a cup of coffee:
+#### Server
+
+To compile the Domain server:
```bash
make domain-server assignment-client
```
-To compile interface:
+*Note: For a server, it is not necessary to compile the Interface.*
+
+#### Interface
+
+To compile the Interface client:
```bash
make interface
```
-The commands above will compile with a single thread. If you have enough memory,
-you can decrease your build time using the `-j` flag. Since most x64 CPUs
-support two threads per core, this works out to CPU_COUNT*2. As an example, if
-you have a 2 core machine, you could use:
-```
+The commands above will compile with a single thread. If you have enough memory, you can decrease your build time using the `-j` flag. Since most x64 CPUs support two threads per core, this works out to CPU_COUNT*2. As an example, if you have a 2 core machine, you could use:
+```bash
make -j4 interface
```
-In a server, it does not make sense to compile interface.
-
### Running the software
#### Domain server
-Running domain server:
+Running Domain server:
```bash
./domain-server/domain-server
```
@@ -158,24 +178,16 @@ Running assignment client:
#### Interface
-Running interface:
+Running Interface:
```bash
./interface/interface
```
-Go to localhost in the running interface.
+Go to "localhost" in the running Interface to visit your newly launched Domain server.
-#### Notes
+### Notes
-If your goal is to set up a development environment, it is desirable to set the
-directory that vcpkg builds into with the `HIFI_VCPKG_BASE` environment variable.
+If your goal is to set up a development environment, it is desirable to set the directory that vcpkg builds into with the `HIFI_VCPKG_BASE` environment variable.
For example, you might set `HIFI_VCPKG_BASE` to `/home/$USER/vcpkg`.
-By default, vcpkg will build in the system `/tmp` directory.
-If build is intended for packaging or creation of AppImage, `VIRCADIA_CPU_ARCHITECTURE`
-CMake variable needs to be set to architecture specific value.
-It defaults to `-march=native -mtune=native`, which yields builds optimized for particular
-machine, but builds will not work on machines lacking same CPU instructions.
-For packaging and AppImage it is recommended to set it to different value, for example `-msse3`.
-Setting `VIRCADIA_CPU_ARCHITECTURE` to empty string will use default compiler settings and yield
-maximum compatibility.
+By default, vcpkg will build in the `~/vircadia-files/vcpkg/` directory.
diff --git a/BUILD_OSX.md b/BUILD_OSX.md
index 03106b9354..b041768dce 100644
--- a/BUILD_OSX.md
+++ b/BUILD_OSX.md
@@ -1,6 +1,6 @@
-# Build MacOS
+# Build macOS
-*Last Updated on October 19, 2021*
+*Last Updated on December 1, 2021*
Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. This will include the necessary environment variables to customize your build. Only macOS specific instructions are found in this document.
@@ -21,9 +21,9 @@ brew install cmake openssl npm
Download an install Python 3.6.6 or higher from [here](https://www.python.org/downloads/).
Execute the `Update Shell Profile.command` script that is provided with the installer.
-### MacOS SDK
+### macOS SDK
-You will need version `10.12` of the macOS SDK for building, otherwise you may have crashing or other unintended issues due to the deprecation of OpenGL on macOS. You can get that SDK from [here](https://github.com/phracker/MacOSX-SDKs). You must copy it in to your Xcode SDK directory, e.g.
+You will need version `10.12` of the macOS SDK for building, otherwise you may experience crashing or other unintended issues due to the deprecation of OpenGL on macOS. You can get that SDK from [here](https://github.com/phracker/MacOSX-SDKs). You must copy it in to your Xcode SDK directory, e.g.
```bash
cp -rp ~/Downloads/MacOSX10.12.sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/
@@ -64,14 +64,17 @@ You can append `-j4` to assign more threads to build with. The number indicates
To package the installation, you can simply run `make package` afterwards.
-## Notes
+## Architecture Support
-If build is intended for packaging or creation of AppImage, `VIRCADIA_CPU_ARCHITECTURE`
-CMake variable needs to be set to architecture specific value.
-It defaults to `-march=native -mtune=native`, which yields builds optimized for particular
-machine, but builds will not work on machines lacking same CPU instructions.
-For packaging and AppImage it is recommended to set it to different value, for example `-msse3`.
-Setting `VIRCADIA_CPU_ARCHITECTURE` to empty string will use default compiler settings and yield
+If the build is intended to be packaged for distribution, the `VIRCADIA_CPU_ARCHITECTURE`
+CMake variable needs to be set to an architecture specific value.
+
+By default, it is set to `-march=native -mtune=native`, which yields builds optimized for a particular
+machine, but these builds will not work on machines lacking same CPU instructions.
+
+For packaging, it is recommended to set it to a different value, for example `-msse3`. This will help ensure that the build will run on all reasonably modern CPUs.
+
+Setting `VIRCADIA_CPU_ARCHITECTURE` to an empty string will use the default compiler settings and yield
maximum compatibility.
## FAQ
diff --git a/README.md b/README.md
index e5d3c68b2f..28e82735f0 100644
--- a/README.md
+++ b/README.md
@@ -54,7 +54,6 @@ Vircadia™ is a 3D social software project seeking to incrementally bring about
- [For Windows - Interface & Server](https://github.com/vircadia/vircadia/blob/master/INSTALLER.md)
- [For Mac - Interface](https://github.com/vircadia/vircadia/blob/master/INSTALLER.md#os-x)
- [For Linux - Server .deb - Vircadia Builder](INSTALLER.md#ubuntu-1804--deb)
-- [For Linux - Server .rpm - Vircadia Builder](INSTALLER.md#amazon-linux-2--rpm)
- [For Linux - Interface AppImage - Vircadia Builder](https://github.com/vircadia/vircadia-builder/blob/master/README.md#building-appimages)
### Boot to Metaverse: [The Goal](https://vircadia.com/vision/)
@@ -94,10 +93,8 @@ Keep in mind that Vircadia consists of multiple smaller projects that might have
#### Supporters of the Vircadia Project
-| [ksuprynowicz (74hc595)](https://github.com/ksuprynowicz) |
+One (1) anonymous, three (3) total sponsors through GitHub. ❤️
+
+| [Daichi Shimabukuro](https://github.com/mshlomd) |
| --- |
-|
[
](https://github.com/ksuprynowicz)
-
-#### Sponsors of Open Source
-
-
+| [
](https://github.com/mshlomd)
diff --git a/hifi_qt.py b/hifi_qt.py
index eb3e945ddb..412eb798ce 100644
--- a/hifi_qt.py
+++ b/hifi_qt.py
@@ -144,12 +144,16 @@ endif()
if 'x86_64' == cpu_architecture:
u_major = int( distro.major_version() )
u_minor = int( distro.minor_version() )
- if (distro.id() == 'ubuntu' and u_major == 18) or distro.id() == 'linuxmint' and u_major == 19:
- self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.15.2-ubuntu-18.04-amd64.tar.xz'
- elif (distro.id() == 'ubuntu' and u_major > 18) or (distro.id() == 'linuxmint' and u_major > 19):
- self.__no_qt_package_error()
+ if distro.id() == 'ubuntu' or distro.id() == 'linuxmint':
+ if (distro.id() == 'ubuntu' and u_major == 18) or distro.id() == 'linuxmint' and u_major == 19:
+ self.qtUrl = self.assets_url + '/dependencies/vcpkg/qt5-install-5.15.2-ubuntu-18.04-amd64.tar.xz'
+ elif (distro.id() == 'ubuntu' and u_major > 18) or (distro.id() == 'linuxmint' and u_major > 19):
+ self.__no_qt_package_error()
+ else:
+ self.__unsupported_error()
else:
- self.__unsupported_error()
+ self.__no_qt_package_error()
+
elif 'aarch64' == cpu_architecture:
if distro.id() == 'ubuntu':
diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp
index 0670252406..8808dc34ad 100644
--- a/interface/src/Util.cpp
+++ b/interface/src/Util.cpp
@@ -182,7 +182,7 @@ void runTimingTests() {
const int EXTRA_JUNK_SIZE = 200;
extraJunk.append((unsigned char)255);
for (int i = 0; i < EXTRA_JUNK_SIZE; i++) {
- extraJunk.append(QString("junk"));
+ extraJunk.append(QString("junk").toUtf8());
}
{
@@ -257,17 +257,17 @@ void runUnitTests() {
quint64 LAST_TEST = 10;
quint64 SKIP_BY = 1;
-
+
for (quint64 value = 0; value <= LAST_TEST; value += SKIP_BY) {
qDebug() << "value:" << value;
ByteCountCoded codedValue = value;
-
+
QByteArray codedValueBuffer = codedValue;
-
+
codedValueBuffer.append((unsigned char)255);
- codedValueBuffer.append(QString("junk"));
-
+ codedValueBuffer.append(QString("junk").toUtf8());
+
qDebug() << "codedValueBuffer:";
outputBufferBits((const unsigned char*)codedValueBuffer.constData(), codedValueBuffer.size());
@@ -276,7 +276,7 @@ void runUnitTests() {
quint64 valueDecoded = valueDecoder;
qDebug() << "valueDecoded:" << valueDecoded;
qDebug() << "bytesConsumed:" << bytesConsumed;
-
+
if (value == valueDecoded) {
qDebug() << "SUCCESS!";
diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp
index 95533b0fb9..7dfb908844 100644
--- a/interface/src/commerce/Wallet.cpp
+++ b/interface/src/commerce/Wallet.cpp
@@ -525,7 +525,7 @@ bool Wallet::readSecurityImage(const QString& inputFilePath, unsigned char** out
} else {
foundFooter = (line == IMAGE_FOOTER);
if (!foundFooter) {
- base64EncryptedBuffer.append(line);
+ base64EncryptedBuffer.append(line.toUtf8());
}
}
}
diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp
index 7ac6414fe7..03a463c82a 100644
--- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp
+++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp
@@ -844,7 +844,7 @@ glm::uvec2 OpenGLDisplayPlugin::getSurfacePixels() const {
uvec2 result;
auto window = _container->getPrimaryWidget();
if (window) {
- result = toGlm(window->geometry().size() * window->devicePixelRatio());
+ result = toGlm(window->geometry().size() * window->devicePixelRatioF());
}
return result;
}
diff --git a/libraries/networking/src/AccountManager.cpp b/libraries/networking/src/AccountManager.cpp
index 514efb431f..ce449a66c3 100644
--- a/libraries/networking/src/AccountManager.cpp
+++ b/libraries/networking/src/AccountManager.cpp
@@ -239,7 +239,7 @@ QNetworkRequest AccountManager::createRequest(QString path, AccountManagerAuth::
} else {
requestURL.setPath(getMetaverseServerURLPath(true) + path.left(queryStringLocation));
}
-
+
// qCDebug(networking) << "Creating request path" << requestURL;
// qCDebug(networking) << "requestURL.isValid()" << requestURL.isValid();
// qCDebug(networking) << "requestURL.errorString()" << requestURL.errorString();
@@ -573,7 +573,7 @@ void AccountManager::requestAccessToken(const QString& login, const QString& pas
postData.append("grant_type=password&");
postData.append("username=" + QUrl::toPercentEncoding(login) + "&");
postData.append("password=" + QUrl::toPercentEncoding(password) + "&");
- postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE);
+ postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE.toUtf8());
request.setUrl(grantURL);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
@@ -594,9 +594,9 @@ void AccountManager::requestAccessTokenWithAuthCode(const QString& authCode, con
QByteArray postData;
postData.append("grant_type=authorization_code&");
- postData.append("client_id=" + clientId + "&");
- postData.append("client_secret=" + clientSecret + "&");
- postData.append("code=" + authCode + "&");
+ postData.append("client_id=" + clientId.toUtf8() + "&");
+ postData.append("client_secret=" + clientSecret.toUtf8() + "&");
+ postData.append("code=" + authCode.toUtf8() + "&");
postData.append("redirect_uri=" + QUrl::toPercentEncoding(redirectUri));
request.setUrl(grantURL);
@@ -618,7 +618,7 @@ void AccountManager::requestAccessTokenWithSteam(QByteArray authSessionTicket) {
QByteArray postData;
postData.append("grant_type=password&");
postData.append("steam_auth_ticket=" + QUrl::toPercentEncoding(authSessionTicket) + "&");
- postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE);
+ postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE.toUtf8());
request.setUrl(grantURL);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
@@ -639,9 +639,9 @@ void AccountManager::requestAccessTokenWithOculus(const QString& nonce, const QS
QByteArray postData;
postData.append("grant_type=password&");
- postData.append("oculus_nonce=" + nonce + "&");
- postData.append("oculus_id=" + oculusID + "&");
- postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE);
+ postData.append("oculus_nonce=" + nonce.toUtf8() + "&");
+ postData.append("oculus_id=" + oculusID.toUtf8() + "&");
+ postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE.toUtf8());
request.setUrl(grantURL);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
@@ -671,7 +671,7 @@ void AccountManager::refreshAccessToken() {
QByteArray postData;
postData.append("grant_type=refresh_token&");
postData.append("refresh_token=" + QUrl::toPercentEncoding(_accountInfo.getAccessToken().refreshToken) + "&");
- postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE);
+ postData.append("scope=" + ACCOUNT_MANAGER_REQUESTED_SCOPE.toUtf8());
request.setUrl(grantURL);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
diff --git a/libraries/networking/src/DomainAccountManager.cpp b/libraries/networking/src/DomainAccountManager.cpp
index 23c52143f6..9ec5badc91 100644
--- a/libraries/networking/src/DomainAccountManager.cpp
+++ b/libraries/networking/src/DomainAccountManager.cpp
@@ -57,7 +57,7 @@ void DomainAccountManager::setAuthURL(const QUrl& authURL) {
}
_currentAuth.authURL = authURL;
- qCDebug(networking) << "DomainAccountManager URL for authenticated requests has been changed to"
+ qCDebug(networking) << "DomainAccountManager URL for authenticated requests has been changed to"
<< qPrintable(_currentAuth.authURL.toString());
_currentAuth.accessToken = "";
@@ -70,7 +70,7 @@ bool DomainAccountManager::hasLogIn() {
return !_currentAuth.authURL.isEmpty();
}
-bool DomainAccountManager::isLoggedIn() {
+bool DomainAccountManager::isLoggedIn() {
return !_currentAuth.authURL.isEmpty() && hasValidAccessToken();
}
@@ -92,7 +92,7 @@ void DomainAccountManager::requestAccessToken(const QString& username, const QSt
formData.append("grant_type=password&");
formData.append("username=" + QUrl::toPercentEncoding(username) + "&");
formData.append("password=" + QUrl::toPercentEncoding(password) + "&");
- formData.append("client_id=" + _currentAuth.clientID);
+ formData.append("client_id=" + _currentAuth.clientID.toUtf8());
request.setUrl(_currentAuth.authURL);
@@ -168,7 +168,7 @@ bool DomainAccountManager::hasValidAccessToken() {
}
// ####### TODO
-
+
// if (!_isWaitingForTokenRefresh && needsToRefreshToken()) {
// refreshAccessToken();
// }
@@ -184,18 +184,18 @@ void DomainAccountManager::setTokensFromJSON(const QJsonObject& jsonObject, cons
bool DomainAccountManager::checkAndSignalForAccessToken() {
bool hasToken = hasValidAccessToken();
- // ####### TODO: Handle hasToken == true.
- // It causes the login dialog not to display (OK) but somewhere the domain server needs to be sent it (and if domain server
+ // ####### TODO: Handle hasToken == true.
+ // It causes the login dialog not to display (OK) but somewhere the domain server needs to be sent it (and if domain server
// gets error when trying to use it then user should be prompted to login).
hasToken = false;
-
+
if (!hasToken) {
// Emit a signal so somebody can call back to us and request an access token given a user name and password.
// Dialog can be hidden immediately after showing if we've just teleported to the domain, unless the signal is delayed.
auto domain = _currentAuth.authURL.host();
QTimer::singleShot(500, this, [this, domain] {
- emit this->authRequired(domain);
+ emit this->authRequired(domain);
});
}
diff --git a/libraries/networking/src/UserActivityLogger.cpp b/libraries/networking/src/UserActivityLogger.cpp
index 94d6371ba4..4454648564 100644
--- a/libraries/networking/src/UserActivityLogger.cpp
+++ b/libraries/networking/src/UserActivityLogger.cpp
@@ -52,7 +52,7 @@ void UserActivityLogger::logAction(QString action, QJsonObject details, JSONCall
// Adding the action name
QHttpPart actionPart;
actionPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"action_name\"");
- actionPart.setBody(QByteArray().append(action));
+ actionPart.setBody(QByteArray().append(action.toUtf8()));
multipart->append(actionPart);
// Log the local-time that this event was logged
diff --git a/libraries/octree/src/OctreeDataUtils.cpp b/libraries/octree/src/OctreeDataUtils.cpp
index b861904255..81e49d4cff 100644
--- a/libraries/octree/src/OctreeDataUtils.cpp
+++ b/libraries/octree/src/OctreeDataUtils.cpp
@@ -63,11 +63,11 @@ bool OctreeUtils::RawOctreeData::readOctreeDataInfoFromFile(QString path) {
QByteArray OctreeUtils::RawOctreeData::toByteArray() {
QByteArray jsonString;
- jsonString += QString("{\n \"DataVersion\": %1,\n").arg(dataVersion);
+ jsonString += QString("{\n \"DataVersion\": %1,\n").arg(dataVersion).toUtf8();
writeSubclassData(jsonString);
- jsonString += QString(",\n \"Id\": \"%1\",\n \"Version\": %2\n}").arg(id.toString()).arg(version);
+ jsonString += QString(",\n \"Id\": \"%1\",\n \"Version\": %2\n}").arg(id.toString()).arg(version).toUtf8();
return jsonString;
}
diff --git a/libraries/ui/src/OffscreenUi.cpp b/libraries/ui/src/OffscreenUi.cpp
index d5fa6609d4..07376cf761 100644
--- a/libraries/ui/src/OffscreenUi.cpp
+++ b/libraries/ui/src/OffscreenUi.cpp
@@ -38,14 +38,14 @@
* This API currently has no effect and is not used.
*
* @namespace OffscreenFlags
- *
+ *
* @hifi-interface
* @hifi-client-entity
* @hifi-avatar
*
- * @property {boolean} navigationFocused - true
if UI has joystick navigation focus, false
if it
+ * @property {boolean} navigationFocused - true
if UI has joystick navigation focus, false
if it
* doesn't.
- * @property {boolean} navigationFocusDisabled - true
if UI joystick navigation focus is disabled,
+ * @property {boolean} navigationFocusDisabled - true
if UI joystick navigation focus is disabled,
* false
if it isn't.
*/
@@ -75,7 +75,7 @@ public:
emit navigationFocusDisabledChanged();
}
}
-
+
signals:
/*@jsdoc
@@ -99,9 +99,9 @@ private:
static OffscreenFlags* offscreenFlags { nullptr };
-// This hack allows the QML UI to work with keys that are also bound as
-// shortcuts at the application level. However, it seems as though the
-// bound actions are still getting triggered. At least for backspace.
+// This hack allows the QML UI to work with keys that are also bound as
+// shortcuts at the application level. However, it seems as though the
+// bound actions are still getting triggered. At least for backspace.
// Not sure why.
//
// However, the problem may go away once we switch to the new menu system,
@@ -168,7 +168,7 @@ void OffscreenUi::onRootContextCreated(QQmlContext* qmlContext) {
qmlContext->setContextProperty("fileDialogHelper", new FileDialogHelper());
#ifdef DEBUG
qmlContext->setContextProperty("DebugQML", QVariant(true));
-#else
+#else
qmlContext->setContextProperty("DebugQML", QVariant(false));
#endif
@@ -284,7 +284,7 @@ QQuickItem* OffscreenUi::createMessageBox(Icon icon, const QString& title, const
map.insert("buttons", buttons.operator int());
map.insert("defaultButton", defaultButton);
QVariant result;
- bool invokeResult;
+ bool invokeResult = false;
auto tabletScriptingInterface = DependencyManager::get();
TabletProxy* tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
if (tablet->getToolbarMode() && _desktop) {
@@ -309,7 +309,7 @@ int OffscreenUi::waitForMessageBoxResult(QQuickItem* messageBox) {
if (!messageBox) {
return QMessageBox::NoButton;
}
-
+
return MessageBoxListener(messageBox).waitForButtonResult();
}
@@ -424,8 +424,8 @@ QString OffscreenUi::getText(const Icon icon, const QString& title, const QStrin
QString OffscreenUi::getItem(const Icon icon, const QString& title, const QString& label, const QStringList& items,
int current, bool editable, bool* ok) {
- if (ok) {
- *ok = false;
+ if (ok) {
+ *ok = false;
}
auto offscreenUi = DependencyManager::get();
@@ -580,7 +580,7 @@ QQuickItem* OffscreenUi::createInputDialog(const Icon icon, const QString& title
auto tabletScriptingInterface = DependencyManager::get();
TabletProxy* tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
- bool invokeResult;
+ bool invokeResult = false;
if (tablet->getToolbarMode() && _desktop) {
invokeResult = QMetaObject::invokeMethod(_desktop, "inputDialog",
Q_RETURN_ARG(QVariant, result),
@@ -608,7 +608,7 @@ QQuickItem* OffscreenUi::createCustomInputDialog(const Icon icon, const QString&
auto tabletScriptingInterface = DependencyManager::get();
TabletProxy* tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
- bool invokeResult;
+ bool invokeResult = false;
if (tablet->getToolbarMode() && _desktop) {
invokeResult = QMetaObject::invokeMethod(_desktop, "inputDialog",
Q_RETURN_ARG(QVariant, result),
@@ -619,7 +619,7 @@ QQuickItem* OffscreenUi::createCustomInputDialog(const Icon icon, const QString&
Q_ARG(QVariant, QVariant::fromValue(map)));
emit tabletScriptingInterface->tabletNotification();
}
-
+
if (!invokeResult) {
qWarning() << "Failed to create custom message box";
return nullptr;
@@ -648,13 +648,13 @@ void OffscreenUi::setNavigationFocused(bool focused) {
// FIXME HACK....
// This hack is an attempt to work around the 'offscreen UI can't gain keyboard focus' bug
// https://app.asana.com/0/27650181942747/83176475832393
-// The problem seems related to https://bugreports.qt.io/browse/QTBUG-50309
+// The problem seems related to https://bugreports.qt.io/browse/QTBUG-50309
//
// The workaround seems to be to give some other window (same process or another process doesn't seem to matter)
-// focus and then put focus back on the interface main window.
+// focus and then put focus back on the interface main window.
//
-// If I could reliably reproduce this bug I could eventually track down what state change is occuring
-// during the process of the main window losing and then gaining focus, but failing that, here's a
+// If I could reliably reproduce this bug I could eventually track down what state change is occuring
+// during the process of the main window losing and then gaining focus, but failing that, here's a
// brute force way of triggering that state change at application start in a way that should be nearly
// imperceptible to the user.
class KeyboardFocusHack : public QObject {
@@ -754,7 +754,7 @@ private slots:
QString OffscreenUi::fileDialog(const QVariantMap& properties) {
QVariant buildDialogResult;
- bool invokeResult;
+ bool invokeResult = false;
auto tabletScriptingInterface = DependencyManager::get();
TabletProxy* tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
if (tablet->getToolbarMode() && _desktop) {
@@ -783,7 +783,7 @@ QString OffscreenUi::fileDialog(const QVariantMap& properties) {
ModalDialogListener* OffscreenUi::fileDialogAsync(const QVariantMap& properties) {
QVariant buildDialogResult;
- bool invokeResult;
+ bool invokeResult = false;
auto tabletScriptingInterface = DependencyManager::get();
TabletProxy* tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
if (tablet->getToolbarMode() && _desktop) {
@@ -1003,7 +1003,7 @@ class AssetDialogListener : public ModalDialogListener {
QString OffscreenUi::assetDialog(const QVariantMap& properties) {
// ATP equivalent of fileDialog().
QVariant buildDialogResult;
- bool invokeResult;
+ bool invokeResult = false;
auto tabletScriptingInterface = DependencyManager::get();
TabletProxy* tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
if (tablet->getToolbarMode() && _desktop) {
@@ -1033,7 +1033,7 @@ QString OffscreenUi::assetDialog(const QVariantMap& properties) {
ModalDialogListener *OffscreenUi::assetDialogAsync(const QVariantMap& properties) {
// ATP equivalent of fileDialog().
QVariant buildDialogResult;
- bool invokeResult;
+ bool invokeResult = false;
auto tabletScriptingInterface = DependencyManager::get();
TabletProxy* tablet = dynamic_cast(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
if (tablet->getToolbarMode() && _desktop) {
@@ -1165,7 +1165,7 @@ bool OffscreenUi::eventFilter(QObject* originalDestination, QEvent* event) {
}
// QML input elements absorb key press, but apparently not key release.
- // therefore we want to ensure that key release events for key presses that were
+ // therefore we want to ensure that key release events for key presses that were
// accepted by the QML layer are suppressed
if (type == QEvent::KeyRelease && pressed) {
pressed = false;
@@ -1175,10 +1175,6 @@ bool OffscreenUi::eventFilter(QObject* originalDestination, QEvent* event) {
return result;
}
-unsigned int OffscreenUi::getMenuUserDataId() const {
- return _vrMenu->_userDataId;
-}
-
ModalDialogListener::ModalDialogListener(QQuickItem *dialog) : _dialog(dialog) {
if (!dialog) {
_finished = true;
diff --git a/libraries/ui/src/OffscreenUi.h b/libraries/ui/src/OffscreenUi.h
index 7e20a0b09d..994a579f44 100644
--- a/libraries/ui/src/OffscreenUi.h
+++ b/libraries/ui/src/OffscreenUi.h
@@ -74,7 +74,7 @@ public:
// Setting pinned to true will hide all overlay elements on the desktop that don't have a pinned flag
void setPinned(bool pinned = true);
-
+
void togglePinned();
void setConstrainToolbarToCenterX(bool constrained);
@@ -237,7 +237,6 @@ public:
static ModalDialogListener* getTextAsync(const Icon icon, const QString & title, const QString & label, const QString & text = QString());
static ModalDialogListener* getItemAsync(const Icon icon, const QString & title, const QString & label, const QStringList & items, int current = 0, bool editable = true);
- unsigned int getMenuUserDataId() const;
QList &getModalDialogListeners();
signals:
@@ -270,7 +269,7 @@ private:
QList _modalDialogListeners;
std::unordered_map _pressedKeys;
VrMenu* _vrMenu { nullptr };
- QQueue> _queuedMenuInitializers;
+ QQueue> _queuedMenuInitializers;
};
#endif
diff --git a/libraries/ui/src/VrMenu.cpp b/libraries/ui/src/VrMenu.cpp
index 8003337eac..6ba01165d5 100644
--- a/libraries/ui/src/VrMenu.cpp
+++ b/libraries/ui/src/VrMenu.cpp
@@ -17,139 +17,116 @@
#include "OffscreenUi.h"
#include "ui/Logging.h"
-static unsigned int USER_DATA_ID = 0;
-// Binds together a Qt Action or Menu with the QML Menu or MenuItem
-//
-// TODO On reflection, it may be pointless to use the UUID. Perhaps
-// simply creating the bidirectional link pointing to both the widget
-// and qml object and inject the pointer into both objects
-class MenuUserData : public QObjectUserData {
-public:
- MenuUserData(QAction* action, QObject* qmlObject, QObject* qmlParent) {
- if (!USER_DATA_ID) {
- USER_DATA_ID = DependencyManager::get()->getMenuUserDataId();
- }
- _action = action;
- _qml = qmlObject;
- _qmlParent = qmlParent;
- action->setUserData(USER_DATA_ID, this);
- qmlObject->setUserData(USER_DATA_ID, this);
- qmlObject->setObjectName(uuid.toString());
- // Make sure we can find it again in the future
+MenuUserData::MenuUserData(QAction* action, QObject* qmlObject, QObject* qmlParent) {
+ _action = action;
+ _qml = qmlObject;
+ _qmlParent = qmlParent;
+
+ action->setProperty(USER_DATA, QVariant::fromValue(this));
+ qmlObject->setProperty(USER_DATA, QVariant::fromValue(this));
+ qmlObject->setObjectName(uuid.toString());
+ // Make sure we can find it again in the future
+ updateQmlItemFromAction();
+ _changedConnection = QObject::connect(action, &QAction::changed, [=] {
updateQmlItemFromAction();
- _changedConnection = QObject::connect(action, &QAction::changed, [=] {
- updateQmlItemFromAction();
- });
- _shutdownConnection = QObject::connect(qApp, &QCoreApplication::aboutToQuit, [=] {
- QObject::disconnect(_changedConnection);
- });
-
- class ExclusionGroupSetter : public QObject {
- public:
- ExclusionGroupSetter(QObject* from, QObject* to, QObject* qmlParent) : QObject(from), _from(from), _to(to), _qmlParent(qmlParent) {
- _from->installEventFilter(this);
- }
-
- ~ExclusionGroupSetter() {
- _from->removeEventFilter(this);
- }
- protected:
- virtual bool eventFilter(QObject* o, QEvent* e) override {
- if (e->type() == QEvent::DynamicPropertyChange) {
- QDynamicPropertyChangeEvent* dpc = static_cast(e);
- if (dpc->propertyName() == "exclusionGroup")
- {
- // unfortunately Qt doesn't support passing dynamic properties between C++ / QML, so we have to use this ugly helper function
- QMetaObject::invokeMethod(_qmlParent,
- "addExclusionGroup",
- Qt::DirectConnection,
- Q_ARG(QVariant, QVariant::fromValue(_to)),
- Q_ARG(QVariant, _from->property(dpc->propertyName())));
- }
- }
-
- return QObject::eventFilter(o, e);
- }
-
- private:
- QObject* _from;
- QObject* _to;
- QObject* _qmlParent;
- };
-
- new ExclusionGroupSetter(action, qmlObject, qmlParent);
- }
-
- ~MenuUserData() {
+ });
+ _shutdownConnection = QObject::connect(qApp, &QCoreApplication::aboutToQuit, [=] {
QObject::disconnect(_changedConnection);
- QObject::disconnect(_shutdownConnection);
- _action->setUserData(USER_DATA_ID, nullptr);
- _qml->setUserData(USER_DATA_ID, nullptr);
- }
+ });
- void updateQmlItemFromAction() {
- _qml->setProperty("checkable", _action->isCheckable());
- _qml->setProperty("enabled", _action->isEnabled());
- QString text = _action->text();
- _qml->setProperty("text", text);
- _qml->setProperty("shortcut", _action->shortcut().toString());
- _qml->setProperty("checked", _action->isChecked());
- _qml->setProperty("visible", _action->isVisible());
- }
-
- void clear() {
- _qml->setProperty("checkable", 0);
- _qml->setProperty("enabled", 0);
- _qml->setProperty("text", 0);
- _qml->setProperty("shortcut", 0);
- _qml->setProperty("checked", 0);
- _qml->setProperty("visible", 0);
-
- _action->setUserData(USER_DATA_ID, nullptr);
- _qml->setUserData(USER_DATA_ID, nullptr);
- }
-
-
- const QUuid uuid{ QUuid::createUuid() };
-
- static bool hasData(QAction* object) {
- if (!object) {
- qWarning() << "Attempted to fetch MenuUserData for null object";
- return false;
+ class ExclusionGroupSetter : public QObject {
+ public:
+ ExclusionGroupSetter(QObject* from, QObject* to, QObject* qmlParent) : QObject(from), _from(from), _to(to), _qmlParent(qmlParent) {
+ _from->installEventFilter(this);
}
- return (nullptr != static_cast(object->userData(USER_DATA_ID)));
- }
- static MenuUserData* forObject(QAction* object) {
- if (!object) {
- qWarning() << "Attempted to fetch MenuUserData for null object";
- return nullptr;
+ ~ExclusionGroupSetter() {
+ _from->removeEventFilter(this);
}
- auto result = static_cast(object->userData(USER_DATA_ID));
- if (!result) {
- qWarning() << "Unable to find MenuUserData for object " << object;
- if (auto action = dynamic_cast(object)) {
- qWarning() << action->text();
- } else if (auto menu = dynamic_cast(object)) {
- qWarning() << menu->title();
+ protected:
+ virtual bool eventFilter(QObject* o, QEvent* e) override {
+ if (e->type() == QEvent::DynamicPropertyChange) {
+ QDynamicPropertyChangeEvent* dpc = static_cast(e);
+ if (dpc->propertyName() == "exclusionGroup") {
+ // unfortunately Qt doesn't support passing dynamic properties between C++ / QML, so we have to use this ugly helper function
+ QMetaObject::invokeMethod(_qmlParent,
+ "addExclusionGroup",
+ Qt::DirectConnection,
+ Q_ARG(QVariant, QVariant::fromValue(_to)),
+ Q_ARG(QVariant, _from->property(dpc->propertyName())));
+ }
}
- return nullptr;
+
+ return QObject::eventFilter(o, e);
}
- return result;
+
+ private:
+ QObject* _from;
+ QObject* _to;
+ QObject* _qmlParent;
+ };
+
+ new ExclusionGroupSetter(action, qmlObject, qmlParent);
+}
+
+MenuUserData::~MenuUserData() {
+ QObject::disconnect(_changedConnection);
+ QObject::disconnect(_shutdownConnection);
+ _action->setProperty(USER_DATA, QVariant());
+ _qml->setProperty(USER_DATA, QVariant());
+}
+
+void MenuUserData::updateQmlItemFromAction() {
+ _qml->setProperty("checkable", _action->isCheckable());
+ _qml->setProperty("enabled", _action->isEnabled());
+ QString text = _action->text();
+ _qml->setProperty("text", text);
+ _qml->setProperty("shortcut", _action->shortcut().toString());
+ _qml->setProperty("checked", _action->isChecked());
+ _qml->setProperty("visible", _action->isVisible());
+}
+
+void MenuUserData::clear() {
+ _qml->setProperty("checkable", 0);
+ _qml->setProperty("enabled", 0);
+ _qml->setProperty("text", 0);
+ _qml->setProperty("shortcut", 0);
+ _qml->setProperty("checked", 0);
+ _qml->setProperty("visible", 0);
+
+ _action->setProperty(USER_DATA, QVariant());
+ _qml->setProperty(USER_DATA, QVariant());
+}
+
+
+
+bool MenuUserData::hasData(QAction* object) {
+ if (!object) {
+ qWarning() << "Attempted to fetch MenuUserData for null object";
+ return false;
}
+ return (nullptr != object->property(USER_DATA).value());
+}
-private:
- Q_DISABLE_COPY(MenuUserData);
-
- QMetaObject::Connection _shutdownConnection;
- QMetaObject::Connection _changedConnection;
- QAction* _action { nullptr };
- QObject* _qml { nullptr };
- QObject* _qmlParent{ nullptr };
-};
-
+MenuUserData* MenuUserData::forObject(QAction* object) {
+ if (!object) {
+ qWarning() << "Attempted to fetch MenuUserData for null object";
+ return nullptr;
+ }
+ auto result = object->property(USER_DATA).value();
+ if (!result) {
+ qWarning() << "Unable to find MenuUserData for object " << object;
+ if (auto action = dynamic_cast(object)) {
+ qWarning() << action->text();
+ } else if (auto menu = dynamic_cast(object)) {
+ qWarning() << menu->title();
+ }
+ return nullptr;
+ }
+ return result;
+}
VrMenu::VrMenu(OffscreenUi* parent) : QObject(parent) {
_rootMenu = parent->getRootItem()->findChild("rootMenu");
diff --git a/libraries/ui/src/VrMenu.h b/libraries/ui/src/VrMenu.h
index c2f9fd830b..4e7031f650 100644
--- a/libraries/ui/src/VrMenu.h
+++ b/libraries/ui/src/VrMenu.h
@@ -18,8 +18,44 @@
#include
#include
#include
+#include
#include "OffscreenUi.h"
+
+
+// Binds together a Qt Action or Menu with the QML Menu or MenuItem
+//
+// TODO On reflection, it may be pointless to use the UUID. Perhaps
+// simply creating the bidirectional link pointing to both the widget
+// and qml object and inject the pointer into both objects
+class MenuUserData : public QObject {
+ Q_OBJECT
+public:
+ MenuUserData(QAction* action, QObject* qmlObject, QObject* qmlParent);
+ ~MenuUserData();
+ void updateQmlItemFromAction();
+ void clear();
+
+ const QUuid uuid{ QUuid::createUuid() };
+
+ static bool hasData(QAction* object);
+
+ static MenuUserData* forObject(QAction* object);
+
+private:
+ Q_DISABLE_COPY(MenuUserData);
+
+ static constexpr const char *USER_DATA{"user_data"};
+
+ QMetaObject::Connection _shutdownConnection;
+ QMetaObject::Connection _changedConnection;
+ QAction* _action { nullptr };
+ QObject* _qml { nullptr };
+ QObject* _qmlParent{ nullptr };
+};
+
+
+
// FIXME break up the rendering code (VrMenu) and the code for mirroring a Widget based menu in QML
class VrMenu : public QObject {
Q_OBJECT
@@ -37,7 +73,6 @@ protected:
friend class MenuUserData;
friend class OffscreenUi;
- const unsigned int _userDataId { QObject::registerUserData() };
};
#endif // hifi_VrMenu_h
diff --git a/scripts/system/inventory/package-lock.json b/scripts/system/inventory/package-lock.json
index 807d100bae..79ee53cdd2 100644
--- a/scripts/system/inventory/package-lock.json
+++ b/scripts/system/inventory/package-lock.json
@@ -6488,9 +6488,9 @@
}
},
"follow-redirects": {
- "version": "1.12.1",
- "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.12.1.tgz",
- "integrity": "sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg==",
+ "version": "1.14.7",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.7.tgz",
+ "integrity": "sha512-+hbxoLbFMbRKDwohX8GkTataGqO6Jb7jGwpAlwgy2bIz25XtRm7KEzJM76R1WiNT5SwZkX4Y75SwBolkpmE7iQ==",
"dev": true
},
"for-in": {
@@ -10662,9 +10662,9 @@
"dev": true
},
"shelljs": {
- "version": "0.8.4",
- "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.4.tgz",
- "integrity": "sha512-7gk3UZ9kOfPLIAbslLzyWeGiEqx9e3rxwZM0KE6EL8GlGwjym9Mrlx5/p33bWTu9YG6vcS4MBxYZDHYr5lr8BQ==",
+ "version": "0.8.5",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.5.tgz",
+ "integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==",
"dev": true,
"requires": {
"glob": "^7.0.0",