Skip to content

Commit

Permalink
Show the window when left-clicking tray icon
Browse files Browse the repository at this point in the history
  • Loading branch information
Erimelowo committed Oct 21, 2024
1 parent ed00469 commit ae22143
Show file tree
Hide file tree
Showing 6 changed files with 289 additions and 61 deletions.
13 changes: 1 addition & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,6 @@ CPMAddPackage(
add_library(lodepng STATIC "${lodepng_SOURCE_DIR}/lodepng.cpp")
target_include_directories(lodepng PUBLIC "${lodepng_SOURCE_DIR}")

IF(WIN32)
CPMAddPackage(
NAME tray
URL https://github.com/Soundux/traypp/archive/698db7d58dd450cc9e30dc12d3bd0c5ca4d6a5b1.zip
)
ENDIF()

set(CMAKE_SKIP_BUILD_RPATH FALSE)
set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
set(CMAKE_INSTALL_RPATH $ORIGIN)
Expand All @@ -107,16 +100,12 @@ if(WIN32)
link_directories("${OPENVR_CMAKE_LIBRARY_OUTPUT_DIRECTORY}")
endif()
if(WIN32)
add_executable("${PROJECT_NAME}" ${GUI_TYPE} "src/main.cpp" "src/pathtools_excerpt.cpp" "src/setup.cpp")
add_executable("${PROJECT_NAME}" ${GUI_TYPE} "src/main.cpp" "src/pathtools_excerpt.cpp" "src/setup.cpp" "src/tray_windows.c")
else()
add_executable("${PROJECT_NAME}" ${GUI_TYPE} "src/main.cpp" "src/setup.cpp")
endif()

target_link_libraries("${PROJECT_NAME}" openvr_api fmt::fmt-header-only simpleini imgui lodepng Threads::Threads)
if(TARGET tray)
target_link_libraries("${PROJECT_NAME}" tray)
endif()

target_include_directories("${PROJECT_NAME}" PRIVATE ${CMAKE_CURRENT_BINARY_DIR} PUBLIC "${openvr_SOURCE_DIR}/headers")
target_compile_features("${PROJECT_NAME}" PRIVATE cxx_std_17)

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,4 @@ We also use:
- The [fmt](https://github.com/fmtlib/fmt) library which is available under a Boost-like license.
- [DearImGui](https://github.com/ocornut/imgui) which is available under the MIT license.
- [lodepng](https://github.com/lvandeve/lodepng/blob/master/LICENSE) which is available under the zlib license.
- [Traypp](https://github.com/Soundux/traypp) which is available under the MIT license.
- A [tray fork](https://github.com/dmikushin/tray) which is available under the MIT license.
6 changes: 3 additions & 3 deletions resources/ThirdPartyLicenses.txt
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,10 @@ freely, subject to the following restrictions:
3. This notice may not be removed or altered from any source
distribution.

---------- lodepng License ----------
---------- tray License ----------
MIT License

Copyright (c) 2021 Soundux
Copyright (c) 2017 Serge Zaitsev

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand All @@ -175,4 +175,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.
102 changes: 57 additions & 45 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,7 @@
#include "lodepng.h"

// Tray icon
#if __has_include(<tray.hpp>)
#include <tray.hpp>
#define TRAY_ICON
#endif
#include "tray.h"

#ifndef WIN32
#define HMODULE void *
Expand Down Expand Up @@ -69,6 +66,10 @@ static constexpr const int mainWindowHeight = 304;

static constexpr const float bitsToGB = 1073741824;

GLFWwindow *glfwWindow;

bool trayQuit = false;

#pragma region Config
#pragma region Default settings
// Initialization
Expand All @@ -86,7 +87,7 @@ int maxRes = 250;
int resIncreaseThreshold = 80;
int resDecreaseThreshold = 88;
int resIncreaseMin = 3;
int resDecreaseMin = 6;
int resDecreaseMin = 5;
int resIncreaseScale = 140;
int resDecreaseScale = 140;
float minCpuTimeThreshold = 0.6f;
Expand Down Expand Up @@ -152,7 +153,7 @@ bool loadSettings()
if (dataAverageSamples > 128)
dataAverageSamples = 128; // Max stored by OpenVR
disabledApps = ini.GetValue("General", "disabledApps", disabledApps.c_str());
std::replace(disabledApps.begin(), disabledApps.end(), ' ', '\n'); // todo test
std::replace(disabledApps.begin(), disabledApps.end(), ' ', '\n');
disabledAppsSet = multilineStringToSet(disabledApps);
// Resolution
initialRes = std::stoi(ini.GetValue("Resolution", "initialRes", std::to_string(initialRes).c_str()));
Expand Down Expand Up @@ -316,11 +317,11 @@ bool shouldAdjustResolution(std::string appKey, bool manualRes, float cpuTime)
return !inDashboard && !isCurrentAppDisabled && !manualRes && !(resetOnThreshold && cpuTime < minCpuTimeThreshold);
}

void printLine(GLFWwindow *window, std::string text, long duration)
void printLine(std::string text, long duration)
{
long startTime = getCurrentTimeMillis();

while (getCurrentTimeMillis() < startTime + duration && !glfwWindowShouldClose(window))
while (getCurrentTimeMillis() < startTime + duration && !glfwWindowShouldClose(glfwWindow))
{
glfwPollEvents();

Expand All @@ -346,14 +347,14 @@ void printLine(GLFWwindow *window, std::string text, long duration)
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

glfwSwapBuffers(window);
glfwSwapBuffers(glfwWindow);

// Sleep to display the text for a set duration
std::this_thread::sleep_for(refreshIntervalBackground);
}
}

void cleanup(GLFWwindow *window, nvmlLib nvmlLibrary)
void cleanup(nvmlLib nvmlLibrary)
{
// OpenVR cleanup
vr::VR_Shutdown();
Expand All @@ -379,7 +380,7 @@ void cleanup(GLFWwindow *window, nvmlLib nvmlLibrary)
ImGui_ImplOpenGL3_Shutdown();
ImGui_ImplGlfw_Shutdown();
ImGui::DestroyContext();
glfwDestroyWindow(window);
glfwDestroyWindow(glfwWindow);
glfwTerminate();
}

Expand Down Expand Up @@ -420,10 +421,10 @@ int main(int argc, char *argv[])
glfwWindowHint(GLFW_RESIZABLE, false);

// Create window with graphics context
GLFWwindow *window = glfwCreateWindow(mainWindowWidth, mainWindowHeight, fmt::format("OVR Dynamic Resolution {}", version).c_str(), nullptr, nullptr);
if (window == nullptr)
glfwWindow = glfwCreateWindow(mainWindowWidth, mainWindowHeight, fmt::format("OVR Dynamic Resolution {}", version).c_str(), nullptr, nullptr);
if (glfwWindow == nullptr)
return 1;
glfwMakeContextCurrent(window);
glfwMakeContextCurrent(glfwWindow);

// Setup Dear ImGui context
IMGUI_CHECKVERSION();
Expand All @@ -438,7 +439,7 @@ int main(int argc, char *argv[])
ImGui::PushStyleColor(ImGuiCol_WindowBg, ImVec4(0.03, 0.03, 0.03, 1));

// Setup Platform/Renderer backends
ImGui_ImplGlfw_InitForOpenGL(window, true);
ImGui_ImplGlfw_InitForOpenGL(glfwWindow, true);
#ifdef __EMSCRIPTEN__
ImGui_ImplGlfw_InstallEmscriptenCallbacks(window, "#canvas");
#endif
Expand All @@ -450,7 +451,7 @@ int main(int argc, char *argv[])
unsigned test = lodepng_decode32_file(&(icon.pixels), &(iconWidth), &(iconHeight), iconPath);
icon.width = (int)iconWidth;
icon.height = (int)iconHeight;
glfwSetWindowIcon(window, 1, &icon);
glfwSetWindowIcon(glfwWindow, 1, &icon);
#pragma endregion

#pragma region VR init
Expand All @@ -460,12 +461,12 @@ int main(int argc, char *argv[])
if (init_error)
{
system = nullptr;
printLine(window, VR_GetVRInitErrorAsEnglishDescription(init_error), 6000l);
printLine(VR_GetVRInitErrorAsEnglishDescription(init_error), 6000l);
return EXIT_FAILURE;
}
if (!VRCompositor())
{
printLine(window, "Failed to initialize VR compositor.", 6000l);
printLine("Failed to initialize VR compositor.", 6000l);
return EXIT_FAILURE;
}
#pragma endregion
Expand All @@ -477,13 +478,13 @@ int main(int argc, char *argv[])
// Set auto-start
int autoStartResult = handle_setup(autoStart);
if (autoStartResult != 0)
printLine(window, fmt::format("Error toggling auto-start ({}) ", autoStartResult), 6000l);
printLine(fmt::format("Error toggling auto-start ({}) ", autoStartResult), 6000l);

// Minimize or hide the window according to config
if (minimizeOnStart == 1) // Minimize
glfwIconifyWindow(window);
glfwIconifyWindow(glfwWindow);
else if (minimizeOnStart == 2) // Hide
glfwHideWindow(window);
glfwHideWindow(glfwWindow);

// Make sure we can set resolution ourselves (Custom instead of Auto)
vr::VRSettings()->SetInt32(vr::k_pch_SteamVR_Section,
Expand Down Expand Up @@ -555,21 +556,32 @@ int main(int argc, char *argv[])
nvmlEnabled = false;
}
#pragma endregion
#if defined(TRAY_ICON)
// Add tray icon
Tray::Tray tray("OVRDR", "icon.ico");
// Construct menu
tray.addEntries(Tray::Button("Show", [&]
{ glfwShowWindow(window); }),
Tray::Button("Hide", [&]
{ glfwHideWindow(window); }),
Tray::Separator(),
Tray::Button("Exit", [&]
{ cleanup(window, nvmlLibrary); tray.exit(); return 0; }));

// Run in a thread
std::thread trayThread(&Tray::Tray::run, &tray);
#endif // TRAY_ICON
#if defined(_WIN32)
const char *hideToggleText = "Hide";
if (minimizeOnStart == 2)
{
hideToggleText = "Show";
}

tray trayInstance = {
"icon.ico",
"OVR Dynamic Resolution",
[](tray *trayInstance)
{ trayInstance->menu->text = "Hide"; tray_update(trayInstance); glfwShowWindow(glfwWindow); },
new tray_menu_item[5]{
{hideToggleText, 0, 0, [](tray_menu_item *item)
{ if (item->text == "Hide") { item->text = "Show"; tray_update(tray_get_instance()); glfwHideWindow(glfwWindow); }
else { item->text = "Hide"; tray_update(tray_get_instance()); glfwShowWindow(glfwWindow); } }},
{"-", 0, 0, nullptr},
{"Quit", 0, 0, [](tray_menu_item *item)
{ trayQuit = true; }},
{nullptr, 0, 0, nullptr}}};

tray_init(&trayInstance);

std::thread trayThread([&]
{ while(tray_loop(1) == 0); trayQuit = true; });
#endif // _WIN32

// Initialize loop variables
Compositor_FrameTiming *frameTiming = new vr::Compositor_FrameTiming[dataAverageSamples];
Expand All @@ -595,7 +607,7 @@ int main(int argc, char *argv[])
bool prevAutoStart = autoStart;

// event loop
while (!glfwWindowShouldClose(window) && !openvrQuit)
while (!glfwWindowShouldClose(glfwWindow) && !openvrQuit && !trayQuit)
{
// Get current time
long currentTime = getCurrentTimeMillis();
Expand Down Expand Up @@ -828,7 +840,7 @@ int main(int argc, char *argv[])
ImGui::SameLine(0, 10);
if (manualRes)
{
ImGui::PushItemWidth(172);
ImGui::PushItemWidth(192);
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
if (ImGui::SliderInt("", &newRes, 20, 500, "%d", ImGuiSliderFlags_AlwaysClamp))
{
Expand Down Expand Up @@ -905,7 +917,7 @@ int main(int argc, char *argv[])
if (ImGui::CollapsingHeader("General"))
{
if (ImGui::InputInt("Resolution change delay ms", &resChangeDelayMs, 100))
resChangeDelayMs = std::max(resChangeDelayMs, 10);
resChangeDelayMs = std::max(resChangeDelayMs, 100);
addTooltip("Delay in milliseconds between resolution changes.");

if (ImGui::InputInt("Data average samples.", &dataAverageSamples, 2))
Expand Down Expand Up @@ -1043,7 +1055,7 @@ int main(int argc, char *argv[])
ImGui::Render();
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());

glfwSwapBuffers(window);
glfwSwapBuffers(glfwWindow);
#pragma endregion

// Check if OpenVR is quitting so we can quit alongside it
Expand All @@ -1060,7 +1072,7 @@ int main(int argc, char *argv[])

// Calculate how long to sleep for depending on if the window is focused or not.
std::chrono::milliseconds sleepTime;
if (glfwGetWindowAttrib(window, GLFW_FOCUSED))
if (glfwGetWindowAttrib(glfwWindow, GLFW_FOCUSED))
sleepTime = refreshIntervalFocused;
else
sleepTime = refreshIntervalBackground;
Expand All @@ -1069,11 +1081,11 @@ int main(int argc, char *argv[])
std::this_thread::sleep_for(sleepTime);
}

cleanup(window, nvmlLibrary);
cleanup(nvmlLibrary);

#if defined(TRAY_ICON)
tray.exit();
#endif // TRAY_ICON
#if defined(_WIN32)
tray_exit();
#endif // _WIN32

return 0;
}
Expand Down
38 changes: 38 additions & 0 deletions src/tray.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#ifndef TRAY_H
#define TRAY_H

#ifdef __cplusplus
extern "C"
{
#endif

struct tray {
const char *icon_filepath;
const char *tooltip;
void (*cb)(struct tray *); // called on left click, leave null to just open menu
struct tray_menu_item *menu;
};

struct tray_menu_item {
const char *text;
int disabled;
int checked;
void (*cb)(struct tray_menu_item *);
struct tray_menu_item *submenu;
};

struct tray * tray_get_instance();

int tray_init(struct tray *tray);

int tray_loop(int blocking);

void tray_update(struct tray *tray);

void tray_exit(void);

#ifdef __cplusplus
} // extern "C"
#endif

#endif /* TRAY_H */
Loading

0 comments on commit ae22143

Please sign in to comment.