├── .github ├── FUNDING.yml └── workflows │ └── nightly.yml ├── CONTRIBUTING ├── LICENSE ├── README.md ├── assets ├── action_manifest.json ├── actions_default.ini ├── config_default.ini ├── images │ ├── browser_load.png │ ├── desktop_plus_capsule.png │ ├── icon_dashboard.png │ ├── icon_dashboard_gamepadui.png │ ├── icons │ │ ├── add.png │ │ ├── browser.png │ │ ├── desktop.png │ │ ├── desktop_1.png │ │ ├── desktop_2.png │ │ ├── desktop_3.png │ │ ├── desktop_4.png │ │ ├── desktop_5.png │ │ ├── desktop_6.png │ │ ├── desktop_all.png │ │ ├── desktop_next.png │ │ ├── desktop_none.png │ │ ├── desktop_previous.png │ │ ├── keyboard.png │ │ ├── performance_monitor.png │ │ ├── settings.png │ │ ├── task_switch.png │ │ └── window_overlay.png │ ├── icons_small │ │ ├── small_actionbar.png │ │ ├── small_add_window.png │ │ ├── small_app_icon.png │ │ ├── small_browser_back.png │ │ ├── small_browser_forward.png │ │ ├── small_browser_refresh.png │ │ ├── small_browser_stop.png │ │ ├── small_close.png │ │ ├── small_move.png │ │ ├── small_move_locked.png │ │ ├── small_performance_monitor_reset.png │ │ ├── xsmall_browser.png │ │ ├── xsmall_desktop.png │ │ ├── xsmall_desktop_1.png │ │ ├── xsmall_desktop_2.png │ │ ├── xsmall_desktop_3.png │ │ ├── xsmall_desktop_4.png │ │ ├── xsmall_desktop_5.png │ │ ├── xsmall_desktop_6.png │ │ ├── xsmall_desktop_all.png │ │ ├── xsmall_desktop_none.png │ │ ├── xsmall_keyboard.png │ │ ├── xsmall_origin_aux.png │ │ ├── xsmall_origin_controller_left.png │ │ ├── xsmall_origin_controller_right.png │ │ ├── xsmall_origin_dashboard.png │ │ ├── xsmall_origin_hmd.png │ │ ├── xsmall_origin_hmd_pos.png │ │ ├── xsmall_origin_playspace.png │ │ ├── xsmall_origin_seated.png │ │ ├── xsmall_origin_theater_screen.png │ │ ├── xsmall_performance_monitor.png │ │ ├── xsmall_settings.png │ │ ├── xxsmall_browser_back.png │ │ ├── xxsmall_close.png │ │ ├── xxsmall_pin.png │ │ └── xxsmall_unpin.png │ └── output_error.png ├── input │ ├── action_bindings_gamepad.json │ ├── action_bindings_generic.json │ ├── action_bindings_holographic.json │ ├── action_bindings_hpmotioncontroller.json │ ├── action_bindings_knuckles.json │ ├── action_bindings_knuckles_ev1.json │ ├── action_bindings_playstation_vr2_sense_controller.json │ ├── action_bindings_touch.json │ ├── action_bindings_vive_controller.json │ ├── action_bindings_vive_cosmos.json │ ├── action_manifest_de.json │ ├── action_manifest_en.json │ ├── action_manifest_ja.json │ └── action_manifest_zh_CN.json ├── keyboards │ ├── azerty_be.ini │ ├── azerty_fr.ini │ ├── qwerty_dk.ini │ ├── qwerty_es.ini │ ├── qwerty_latam.ini │ ├── qwerty_uk.ini │ ├── qwerty_usa.ini │ └── qwertz_ger.ini ├── lang │ ├── de.ini │ ├── en.ini │ ├── ja.ini │ └── zh_CN.ini ├── license.txt ├── manifest.vrmanifest ├── misc │ ├── !About this folder.txt │ ├── CreateElevatedTask.bat │ ├── CreateElevatedTask.ps1 │ ├── EnableUIAccess.bat │ ├── EnableUIAccess.ps1 │ ├── EnableUIAccessDesktopPlus.manifest │ ├── UndoSystemChanges.bat │ └── UndoSystemChanges.ps1 ├── openvr_api.dll ├── profiles │ └── Sample Profile.ini ├── readme.txt └── third-party_licenses.txt ├── docs ├── images │ ├── desktop_mode.png │ ├── floating_ui.png │ ├── keyboard_layout_editor.png │ ├── overlay_bar.png │ ├── overlay_properties_advanced.png │ ├── overlay_properties_appearance.png │ ├── overlay_properties_browser.png │ ├── overlay_properties_capture.png │ ├── overlay_properties_interface.png │ ├── overlay_properties_page_change_position.png │ ├── overlay_properties_page_cropping_area.png │ ├── overlay_properties_performance.png │ ├── overlay_properties_performance_monitor.png │ ├── overlay_properties_position.png │ ├── settings_actions.png │ ├── settings_browser.png │ ├── settings_environment.png │ ├── settings_interface.png │ ├── settings_keyboard.png │ ├── settings_laser_pointer.png │ ├── settings_mouse.png │ ├── settings_page_application_profiles.png │ ├── settings_page_change_action_order.png │ ├── settings_page_edit_action.png │ ├── settings_page_keyboard_layout.png │ ├── settings_page_manage_actions.png │ ├── settings_page_overlay_profiles.png │ ├── settings_page_persistent_ui.png │ ├── settings_page_restore_defaults.png │ ├── settings_performance.png │ ├── settings_profiles.png │ ├── settings_startup.png │ ├── settings_troubleshooting.png │ ├── settings_version_info.png │ ├── settings_warnings.png │ ├── settings_window_overlays.png │ └── vr_keyboard.png ├── screenshot.jpg └── user_guide.md └── src ├── DesktopPlus.sln ├── DesktopPlus ├── BackgroundOverlay.cpp ├── BackgroundOverlay.h ├── CommonTypes.h ├── DesktopPlus.cpp ├── DesktopPlus.manifest ├── DesktopPlus.rc ├── DesktopPlus.ruleset ├── DesktopPlus.vcxproj ├── DesktopPlus.vcxproj.filters ├── DesktopPlus.vcxproj.user ├── DisplayManager.cpp ├── DisplayManager.h ├── DuplicationManager.cpp ├── DuplicationManager.h ├── ElevatedMode.cpp ├── ElevatedMode.h ├── InputSimulator.cpp ├── InputSimulator.h ├── LaserPointer.cpp ├── LaserPointer.h ├── OutputManager.cpp ├── OutputManager.h ├── Overlays.cpp ├── Overlays.h ├── PixelShader.hlsl ├── PixelShaderCursor.hlsl ├── RadialFollowSmoothing.cpp ├── RadialFollowSmoothing.h ├── ThreadManager.cpp ├── ThreadManager.h ├── VRInput.cpp ├── VRInput.h ├── VertexShader.hlsl └── resource.h ├── DesktopPlusUI ├── AuxUI.cpp ├── AuxUI.h ├── DesktopPlusUI.cpp ├── DesktopPlusUI.rc ├── DesktopPlusUI.vcxproj ├── DesktopPlusUI.vcxproj.filters ├── DesktopPlusUI.vcxproj.user ├── FloatingUI.cpp ├── FloatingUI.h ├── FloatingWindow.cpp ├── FloatingWindow.h ├── ImGuiExt.cpp ├── ImGuiExt.h ├── NotificationIcon.cpp ├── NotificationIcon.h ├── TextureManager.cpp ├── TextureManager.h ├── TranslationManager.cpp ├── TranslationManager.h ├── UIManager.cpp ├── UIManager.h ├── VRKeyboard.cpp ├── VRKeyboard.h ├── VRKeyboardCommon.h ├── Win32PerformanceData.cpp ├── Win32PerformanceData.h ├── WindowDesktopMode.cpp ├── WindowDesktopMode.h ├── WindowFloatingUIBar.cpp ├── WindowFloatingUIBar.h ├── WindowKeyboard.cpp ├── WindowKeyboard.h ├── WindowKeyboardEditor.cpp ├── WindowKeyboardEditor.h ├── WindowOverlayBar.cpp ├── WindowOverlayBar.h ├── WindowOverlayProperties.cpp ├── WindowOverlayProperties.h ├── WindowPerformance.cpp ├── WindowPerformance.h ├── WindowSettings.cpp ├── WindowSettings.h ├── icon_src │ ├── add.svg │ ├── add_window.svg │ ├── browser.svg │ ├── browser32.svg │ ├── controller_left.svg │ ├── controller_right.svg │ ├── dashboard.svg │ ├── desktop.svg │ ├── desktop_1.svg │ ├── desktop_2.svg │ ├── desktop_3.svg │ ├── desktop_4.svg │ ├── desktop_5.svg │ ├── desktop_6.svg │ ├── desktop_all.svg │ ├── desktop_error.svg │ ├── desktop_next.svg │ ├── hmd.svg │ ├── hmdpos.svg │ ├── icon_desktop.svg │ ├── icon_desktop32.svg │ ├── icon_openvr.svg │ ├── keyboard.svg │ ├── keyboard32.svg │ ├── performance_monitor.svg │ ├── performance_monitor_reset.svg │ ├── pin.svg │ ├── playspace.svg │ ├── seated_space.svg │ ├── settings.svg │ ├── small_actionbar.svg │ ├── small_browser_back.svg │ ├── small_browser_refresh.svg │ ├── small_browser_stop.svg │ ├── small_close.svg │ ├── small_move.svg │ ├── small_move_locked.svg │ ├── task_switch.svg │ ├── theater_screen.svg │ └── tracker.svg ├── imgui │ ├── imconfig.h │ ├── imgui.cpp │ ├── imgui.h │ ├── imgui_demo.cpp │ ├── imgui_draw.cpp │ ├── imgui_internal.h │ ├── imgui_tables.cpp │ ├── imgui_widgets.cpp │ ├── imstb_rectpack.h │ ├── imstb_textedit.h │ └── imstb_truetype.h ├── imgui_win32_dx11_openvr │ ├── PixelShaderImGui.hlsl │ ├── VertexShaderImGui.hlsl │ ├── imgui_impl_dx11_openvr.cpp │ ├── imgui_impl_dx11_openvr.h │ ├── imgui_impl_win32_openvr.cpp │ └── imgui_impl_win32_openvr.h ├── implot │ ├── implot.cpp │ ├── implot.h │ ├── implot_internal.h │ └── implot_items.cpp └── resource.h ├── DesktopPlusWinRT ├── CaptureManager.cpp ├── CaptureManager.h ├── CommonHeaders.h ├── DesktopPlusWinRT.cpp ├── DesktopPlusWinRT.h ├── DesktopPlusWinRT.rc ├── DesktopPlusWinRT.vcxproj ├── DesktopPlusWinRT.vcxproj.filters ├── DesktopPlusWinRT.vcxproj.user ├── OverlayCapture.cpp ├── OverlayCapture.h ├── ThreadData.h ├── packages.config ├── resource.h └── util │ ├── DesktopWindow.h │ ├── capture.desktop.interop.h │ ├── direct3d11.interop.h │ ├── dispatcherqueue.desktop.interop.h │ └── hwnd.interop.h └── Shared ├── Actions.cpp ├── Actions.h ├── AppProfiles.cpp ├── AppProfiles.h ├── ConfigManager.cpp ├── ConfigManager.h ├── DPBrowserAPI.h ├── DPBrowserAPIClient.cpp ├── DPBrowserAPIClient.h ├── DPRect.h ├── Ini.cpp ├── Ini.h ├── InterprocessMessaging.cpp ├── InterprocessMessaging.h ├── Logging.cpp ├── Logging.h ├── Matrices.cpp ├── Matrices.h ├── OUtoSBSConverter.cpp ├── OUtoSBSConverter.h ├── OpenVRExt.cpp ├── OpenVRExt.h ├── OverlayDragger.cpp ├── OverlayDragger.h ├── OverlayManager.cpp ├── OverlayManager.h ├── Util.cpp ├── Util.h ├── Vectors.h ├── WindowManager.cpp ├── WindowManager.h ├── icon_desktop.ico ├── loguru.cpp ├── loguru.hpp ├── openvr.h └── openvr_api.lib /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | ko_fi: elvissteinjr 2 | -------------------------------------------------------------------------------- /.github/workflows/nightly.yml: -------------------------------------------------------------------------------- 1 | name: Nightly Build 2 | 3 | on: 4 | push: 5 | paths-ignore: 6 | - 'README.md' 7 | - 'CONTRIBUTING' 8 | - 'LICENSE' 9 | - 'docs/**' 10 | 11 | env: 12 | SOLUTION_FILE_PATH: ./src/DesktopPlus.sln 13 | OUTPUT_PATH: ./src/x64/Release 14 | BUILD_CONFIGURATION: Release 15 | 16 | permissions: 17 | contents: read 18 | 19 | jobs: 20 | build: 21 | runs-on: windows-latest 22 | 23 | steps: 24 | - name: Checkout 25 | uses: actions/checkout@v4 26 | 27 | - name: Setup MSBuild 28 | uses: microsoft/setup-msbuild@v2 29 | 30 | - name: Restore NuGet Packages 31 | working-directory: ${{env.GITHUB_WORKSPACE}} 32 | run: nuget restore ${{env.SOLUTION_FILE_PATH}} 33 | 34 | - name: Build 35 | working-directory: ${{env.GITHUB_WORKSPACE}} 36 | run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} /p:DPLUS_SHA='"${{github.sha}}"' ${{env.SOLUTION_FILE_PATH}} 37 | 38 | - name: Rename Output Folder for Archive 39 | working-directory: ${{env.GITHUB_WORKSPACE}} 40 | run: ren ${{env.OUTPUT_PATH}} DesktopPlus 41 | 42 | - name: Upload Artifact 43 | uses: actions/upload-artifact@v4 44 | with: 45 | name: DesktopPlus-NewUI-${{github.sha}} 46 | path: | 47 | ./src/x64 48 | !./**/*.h 49 | !./**/*.lib 50 | !./**/*.exp 51 | -------------------------------------------------------------------------------- /CONTRIBUTING: -------------------------------------------------------------------------------- 1 | Short version: 2 | Any contribution is welcomed with open arms. In the rare case something would be off, it'll be taken care of. 3 | If you contribute code, you allow me to use it in a Steam build that may contain additional code not present in this repo. 4 | 5 | Long version: 6 | I want to preface this with stating that the Desktop+ code is no way trying to be professional. Just read the comments. 7 | It's provided as-is, in hope somebody finds a use in it. 8 | The code grew with time, overall structure may not be up to best practice. If you want to re-organize it to be "better", feel free. 9 | 10 | In terms of actually adding code, there are no strict style guidelines. Just don't make the code look foreign in the middle of the existing mess. 11 | If you plan to add something big, consider opening an issue for it first. 12 | I take some needless pride in the low memory footprint, both runtime and size on disk. Try to not add bloat without reason. 13 | It's fine for code to be a tiny bit awkward in order to use system libraries instead of pulling megabytes of additional dependencies. 14 | Perhaps also avoid stacks of abstraction. The code may run on typically beefy machines, but it's running in the background most of time. Make sane decisions. 15 | 16 | Just felt like I should mention this stuff somewhere. Not like anyone reads this anyways. 17 | 18 | If you contribute code to this repository, you are also granting me (GitHub user elvissteinjr) permission to distribute it on other platforms such as Steam in binary form, possibly linking to non-free third-party libraries such as the Steamworks API library. Such a build may also contain additional code not present in this repo to support these libraries. 19 | Please do not contribute if you do not agree to this. -------------------------------------------------------------------------------- /assets/actions_default.ini: -------------------------------------------------------------------------------- 1 | [1] 2 | Name=tstr_DefActionShowKeyboard 3 | CommandCount=1 4 | Command0Type=ShowKeyboard 5 | Command0UIntArg=0 6 | IconFilename=keyboard.png 7 | 8 | [2] 9 | Name=tstr_DefActionActiveWindowCrop 10 | Label=tstr_DefActionActiveWindowCropLabel 11 | CommandCount=1 12 | Command0Type=CropActiveWindow 13 | 14 | [3] 15 | Name=tstr_DefActionSwitchTask 16 | CommandCount=1 17 | Command0Type=SwitchTask 18 | IconFilename=task_switch.png 19 | 20 | [4] 21 | Name=tstr_DefActionToggleOverlays 22 | Label=tstr_DefActionToggleOverlaysLabel 23 | CommandCount=1 24 | Command0Type=ShowOverlay 25 | TargetUseTags=true 26 | TargetTags=Ovrl_All 27 | 28 | [5] 29 | Name=tstr_DefActionMiddleMouse 30 | Label=tstr_DefActionMiddleMouseLabel 31 | CommandCount=1 32 | Command0Type=Key 33 | Command0UIntID=4 34 | Command0UIntArg=0 35 | 36 | [6] 37 | Name=tstr_DefActionBackMouse 38 | Label=tstr_DefActionBackMouseLabel 39 | CommandCount=1 40 | Command0Type=Key 41 | Command0UIntID=5 42 | Command0UIntArg=0 43 | 44 | [7] 45 | Name=tstr_DefActionReadMe 46 | Label=tstr_DefActionReadMeLabel 47 | CommandCount=1 48 | Command0Type=LaunchApp 49 | Command0StrMain=readme.txt 50 | 51 | [8] 52 | Name=tstr_DefActionDashboardToggle 53 | Label=tstr_DefActionDashboardToggleLabel 54 | CommandCount=1 55 | Command0Type=LaunchApp 56 | Command0StrMain=vrmonitor://debugcommands/system_dashboard_toggle -------------------------------------------------------------------------------- /assets/images/browser_load.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/browser_load.png -------------------------------------------------------------------------------- /assets/images/desktop_plus_capsule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/desktop_plus_capsule.png -------------------------------------------------------------------------------- /assets/images/icon_dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icon_dashboard.png -------------------------------------------------------------------------------- /assets/images/icon_dashboard_gamepadui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icon_dashboard_gamepadui.png -------------------------------------------------------------------------------- /assets/images/icons/add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons/add.png -------------------------------------------------------------------------------- /assets/images/icons/browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons/browser.png -------------------------------------------------------------------------------- /assets/images/icons/desktop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons/desktop.png -------------------------------------------------------------------------------- /assets/images/icons/desktop_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons/desktop_1.png -------------------------------------------------------------------------------- /assets/images/icons/desktop_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons/desktop_2.png -------------------------------------------------------------------------------- /assets/images/icons/desktop_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons/desktop_3.png -------------------------------------------------------------------------------- /assets/images/icons/desktop_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons/desktop_4.png -------------------------------------------------------------------------------- /assets/images/icons/desktop_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons/desktop_5.png -------------------------------------------------------------------------------- /assets/images/icons/desktop_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons/desktop_6.png -------------------------------------------------------------------------------- /assets/images/icons/desktop_all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons/desktop_all.png -------------------------------------------------------------------------------- /assets/images/icons/desktop_next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons/desktop_next.png -------------------------------------------------------------------------------- /assets/images/icons/desktop_none.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons/desktop_none.png -------------------------------------------------------------------------------- /assets/images/icons/desktop_previous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons/desktop_previous.png -------------------------------------------------------------------------------- /assets/images/icons/keyboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons/keyboard.png -------------------------------------------------------------------------------- /assets/images/icons/performance_monitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons/performance_monitor.png -------------------------------------------------------------------------------- /assets/images/icons/settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons/settings.png -------------------------------------------------------------------------------- /assets/images/icons/task_switch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons/task_switch.png -------------------------------------------------------------------------------- /assets/images/icons/window_overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons/window_overlay.png -------------------------------------------------------------------------------- /assets/images/icons_small/small_actionbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/small_actionbar.png -------------------------------------------------------------------------------- /assets/images/icons_small/small_add_window.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/small_add_window.png -------------------------------------------------------------------------------- /assets/images/icons_small/small_app_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/small_app_icon.png -------------------------------------------------------------------------------- /assets/images/icons_small/small_browser_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/small_browser_back.png -------------------------------------------------------------------------------- /assets/images/icons_small/small_browser_forward.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/small_browser_forward.png -------------------------------------------------------------------------------- /assets/images/icons_small/small_browser_refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/small_browser_refresh.png -------------------------------------------------------------------------------- /assets/images/icons_small/small_browser_stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/small_browser_stop.png -------------------------------------------------------------------------------- /assets/images/icons_small/small_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/small_close.png -------------------------------------------------------------------------------- /assets/images/icons_small/small_move.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/small_move.png -------------------------------------------------------------------------------- /assets/images/icons_small/small_move_locked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/small_move_locked.png -------------------------------------------------------------------------------- /assets/images/icons_small/small_performance_monitor_reset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/small_performance_monitor_reset.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_browser.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_desktop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_desktop.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_desktop_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_desktop_1.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_desktop_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_desktop_2.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_desktop_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_desktop_3.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_desktop_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_desktop_4.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_desktop_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_desktop_5.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_desktop_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_desktop_6.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_desktop_all.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_desktop_all.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_desktop_none.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_desktop_none.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_keyboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_keyboard.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_origin_aux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_origin_aux.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_origin_controller_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_origin_controller_left.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_origin_controller_right.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_origin_controller_right.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_origin_dashboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_origin_dashboard.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_origin_hmd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_origin_hmd.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_origin_hmd_pos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_origin_hmd_pos.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_origin_playspace.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_origin_playspace.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_origin_seated.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_origin_seated.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_origin_theater_screen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_origin_theater_screen.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_performance_monitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_performance_monitor.png -------------------------------------------------------------------------------- /assets/images/icons_small/xsmall_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xsmall_settings.png -------------------------------------------------------------------------------- /assets/images/icons_small/xxsmall_browser_back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xxsmall_browser_back.png -------------------------------------------------------------------------------- /assets/images/icons_small/xxsmall_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xxsmall_close.png -------------------------------------------------------------------------------- /assets/images/icons_small/xxsmall_pin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xxsmall_pin.png -------------------------------------------------------------------------------- /assets/images/icons_small/xxsmall_unpin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/icons_small/xxsmall_unpin.png -------------------------------------------------------------------------------- /assets/images/output_error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/images/output_error.png -------------------------------------------------------------------------------- /assets/input/action_bindings_gamepad.json: -------------------------------------------------------------------------------- 1 | { 2 | "action_manifest_version" : 5, 3 | "alias_info" : {}, 4 | "app_key" : "steam.overlay.1494460", 5 | "bindings" : { 6 | "/actions/laserpointer" : { 7 | "sources" : [ 8 | { 9 | "inputs" : { 10 | "click" : { 11 | "output" : "/actions/laserpointer/in/LeftClick" 12 | } 13 | }, 14 | "mode" : "button", 15 | "path" : "/user/gamepad/input/trigger_right" 16 | }, 17 | { 18 | "inputs" : { 19 | "east" : { 20 | "output" : "/actions/laserpointer/in/RightClick" 21 | } 22 | }, 23 | "mode" : "button", 24 | "path" : "/user/gamepad/input/trigger_left" 25 | }, 26 | { 27 | "inputs" : { 28 | "click" : { 29 | "output" : "/actions/laserpointer/in/Aux01Click" 30 | } 31 | }, 32 | "mode" : "button", 33 | "path" : "/user/gamepad/input/b" 34 | }, 35 | { 36 | "inputs" : { 37 | "click" : { 38 | "output" : "/actions/laserpointer/in/Aux02Click" 39 | } 40 | }, 41 | "mode" : "button", 42 | "path" : "/user/gamepad/input/x" 43 | } 44 | ] 45 | }, 46 | "/actions/scroll_discrete" : { 47 | "sources" : [ 48 | { 49 | "inputs" : { 50 | "scroll" : { 51 | "output" : "/actions/scroll_discrete/in/ScrollDiscrete" 52 | } 53 | }, 54 | "mode" : "scroll", 55 | "path" : "/user/gamepad/input/joystick_right" 56 | } 57 | ] 58 | }, 59 | "/actions/scroll_smooth" : { 60 | "sources" : [ 61 | { 62 | "inputs" : { 63 | "scroll" : { 64 | "output" : "/actions/scroll_smooth/in/ScrollSmooth" 65 | } 66 | }, 67 | "mode" : "scroll", 68 | "parameters" : { 69 | "scroll_mode" : "smooth" 70 | }, 71 | "path" : "/user/gamepad/input/joystick_right" 72 | } 73 | ] 74 | } 75 | }, 76 | "category" : "steamvr_input", 77 | "controller_type" : "gamepad", 78 | "description" : "", 79 | "name" : "Default Desktop+ bindings for Gamepads", 80 | "options" : {}, 81 | "simulated_actions" : [] 82 | } 83 | -------------------------------------------------------------------------------- /assets/input/action_manifest_de.json: -------------------------------------------------------------------------------- 1 | { 2 | "language_tag": "de_DE", 3 | 4 | "/actions/shortcuts" : "Globale Kürzel", 5 | 6 | "/actions/shortcuts/in/EnableGlobalLaserPointer" : "Aktiviere globalen Laser-Pointer", 7 | "/actions/shortcuts/in/GlobalShortcut01" : "Globales Kürzel #1 ausführen", 8 | "/actions/shortcuts/in/GlobalShortcut02" : "Globales Kürzel #2 ausführen", 9 | "/actions/shortcuts/in/GlobalShortcut03" : "Globales Kürzel #3 ausführen", 10 | "/actions/shortcuts/in/GlobalShortcut04" : "Globales Kürzel #4 ausführen", 11 | "/actions/shortcuts/in/GlobalShortcut05" : "Globales Kürzel #5 ausführen", 12 | "/actions/shortcuts/in/GlobalShortcut06" : "Globales Kürzel #6 ausführen", 13 | "/actions/shortcuts/in/GlobalShortcut07" : "Globales Kürzel #7 ausführen", 14 | "/actions/shortcuts/in/GlobalShortcut08" : "Globales Kürzel #8 ausführen", 15 | "/actions/shortcuts/in/GlobalShortcut09" : "Globales Kürzel #9 ausführen", 16 | "/actions/shortcuts/in/GlobalShortcut10" : "Globales Kürzel #10 ausführen", 17 | "/actions/shortcuts/in/GlobalShortcut11" : "Globales Kürzel #11 ausführen", 18 | "/actions/shortcuts/in/GlobalShortcut12" : "Globales Kürzel #12 ausführen", 19 | "/actions/shortcuts/in/GlobalShortcut13" : "Globales Kürzel #13 ausführen", 20 | "/actions/shortcuts/in/GlobalShortcut14" : "Globales Kürzel #14 ausführen", 21 | "/actions/shortcuts/in/GlobalShortcut15" : "Globales Kürzel #15 ausführen", 22 | "/actions/shortcuts/in/GlobalShortcut16" : "Globales Kürzel #16 ausführen", 23 | "/actions/shortcuts/in/GlobalShortcut17" : "Globales Kürzel #17 ausführen", 24 | "/actions/shortcuts/in/GlobalShortcut18" : "Globales Kürzel #18 ausführen", 25 | "/actions/shortcuts/in/GlobalShortcut19" : "Globales Kürzel #19 ausführen", 26 | "/actions/shortcuts/in/GlobalShortcut20" : "Globales Kürzel #20 ausführen", 27 | 28 | "/actions/laserpointer" : "Laserpointer", 29 | 30 | "/actions/laserpointer/in/LeftClick" : "Linksklick", 31 | "/actions/laserpointer/in/RightClick" : "Rechtsklick", 32 | "/actions/laserpointer/in/MiddleClick" : "Mittelklick", 33 | "/actions/laserpointer/in/Aux01Click" : "Extra 1-Klick", 34 | "/actions/laserpointer/in/Aux02Click" : "Extra 2-Klick", 35 | "/actions/laserpointer/in/Drag" : "Overlay ziehen", 36 | 37 | "/actions/scroll_discrete" : "Mausrad-Bildlauf", 38 | 39 | "/actions/scroll_discrete/in/ScrollDiscrete" : "Overlay scrollen", 40 | 41 | "/actions/scroll_smooth" : "Weicher Bildlauf", 42 | 43 | "/actions/scroll_smooth/in/ScrollSmooth" : "Overlay scrollen" 44 | } 45 | -------------------------------------------------------------------------------- /assets/input/action_manifest_en.json: -------------------------------------------------------------------------------- 1 | { 2 | "language_tag": "en_US", 3 | 4 | "/actions/shortcuts" : "Global Shortcuts", 5 | 6 | "/actions/shortcuts/in/EnableGlobalLaserPointer" : "Enable Global Laser Pointer", 7 | "/actions/shortcuts/in/GlobalShortcut01" : "Do Global Shortcut #1", 8 | "/actions/shortcuts/in/GlobalShortcut02" : "Do Global Shortcut #2", 9 | "/actions/shortcuts/in/GlobalShortcut03" : "Do Global Shortcut #3", 10 | "/actions/shortcuts/in/GlobalShortcut04" : "Do Global Shortcut #4", 11 | "/actions/shortcuts/in/GlobalShortcut05" : "Do Global Shortcut #5", 12 | "/actions/shortcuts/in/GlobalShortcut06" : "Do Global Shortcut #6", 13 | "/actions/shortcuts/in/GlobalShortcut07" : "Do Global Shortcut #7", 14 | "/actions/shortcuts/in/GlobalShortcut08" : "Do Global Shortcut #8", 15 | "/actions/shortcuts/in/GlobalShortcut09" : "Do Global Shortcut #9", 16 | "/actions/shortcuts/in/GlobalShortcut10" : "Do Global Shortcut #10", 17 | "/actions/shortcuts/in/GlobalShortcut11" : "Do Global Shortcut #11", 18 | "/actions/shortcuts/in/GlobalShortcut12" : "Do Global Shortcut #12", 19 | "/actions/shortcuts/in/GlobalShortcut13" : "Do Global Shortcut #13", 20 | "/actions/shortcuts/in/GlobalShortcut14" : "Do Global Shortcut #14", 21 | "/actions/shortcuts/in/GlobalShortcut15" : "Do Global Shortcut #15", 22 | "/actions/shortcuts/in/GlobalShortcut16" : "Do Global Shortcut #16", 23 | "/actions/shortcuts/in/GlobalShortcut17" : "Do Global Shortcut #17", 24 | "/actions/shortcuts/in/GlobalShortcut18" : "Do Global Shortcut #18", 25 | "/actions/shortcuts/in/GlobalShortcut19" : "Do Global Shortcut #19", 26 | "/actions/shortcuts/in/GlobalShortcut20" : "Do Global Shortcut #20", 27 | 28 | "/actions/laserpointer" : "Laser Pointer", 29 | 30 | "/actions/laserpointer/in/LeftClick" : "Left Click", 31 | "/actions/laserpointer/in/RightClick" : "Right Click", 32 | "/actions/laserpointer/in/MiddleClick" : "Middle Click", 33 | "/actions/laserpointer/in/Aux01Click" : "Auxiliary 1 Click", 34 | "/actions/laserpointer/in/Aux02Click" : "Auxiliary 2 Click", 35 | "/actions/laserpointer/in/Drag" : "Drag Overlay", 36 | 37 | "/actions/scroll_discrete" : "Mousewheel Scrolling", 38 | 39 | "/actions/scroll_discrete/in/ScrollDiscrete" : "Scroll Overlay", 40 | 41 | "/actions/scroll_smooth" : "Smooth Scrolling", 42 | 43 | "/actions/scroll_smooth/in/ScrollSmooth" : "Scroll Overlay" 44 | } 45 | -------------------------------------------------------------------------------- /assets/input/action_manifest_ja.json: -------------------------------------------------------------------------------- 1 | { 2 | "language_tag": "ja_JP", 3 | 4 | "/actions/shortcuts" : "グローバルショートカット", 5 | 6 | "/actions/shortcuts/in/EnableGlobalLaserPointer" : "グローバルレーザーポインターを有効化", 7 | "/actions/shortcuts/in/GlobalShortcut01" : "グローバルショートカットを実行 #1", 8 | "/actions/shortcuts/in/GlobalShortcut02" : "グローバルショートカットを実行 #2", 9 | "/actions/shortcuts/in/GlobalShortcut03" : "グローバルショートカットを実行 #3", 10 | "/actions/shortcuts/in/GlobalShortcut04" : "グローバルショートカットを実行 #4", 11 | "/actions/shortcuts/in/GlobalShortcut05" : "グローバルショートカットを実行 #5", 12 | "/actions/shortcuts/in/GlobalShortcut06" : "グローバルショートカットを実行 #6", 13 | "/actions/shortcuts/in/GlobalShortcut07" : "グローバルショートカットを実行 #7", 14 | "/actions/shortcuts/in/GlobalShortcut08" : "グローバルショートカットを実行 #8", 15 | "/actions/shortcuts/in/GlobalShortcut09" : "グローバルショートカットを実行 #9", 16 | "/actions/shortcuts/in/GlobalShortcut10" : "グローバルショートカットを実行 #10", 17 | "/actions/shortcuts/in/GlobalShortcut11" : "グローバルショートカットを実行 #11", 18 | "/actions/shortcuts/in/GlobalShortcut12" : "グローバルショートカットを実行 #12", 19 | "/actions/shortcuts/in/GlobalShortcut13" : "グローバルショートカットを実行 #13", 20 | "/actions/shortcuts/in/GlobalShortcut14" : "グローバルショートカットを実行 #14", 21 | "/actions/shortcuts/in/GlobalShortcut15" : "グローバルショートカットを実行 #15", 22 | "/actions/shortcuts/in/GlobalShortcut16" : "グローバルショートカットを実行 #16", 23 | "/actions/shortcuts/in/GlobalShortcut17" : "グローバルショートカットを実行 #17", 24 | "/actions/shortcuts/in/GlobalShortcut18" : "グローバルショートカットを実行 #18", 25 | "/actions/shortcuts/in/GlobalShortcut19" : "グローバルショートカットを実行 #19", 26 | "/actions/shortcuts/in/GlobalShortcut20" : "グローバルショートカットを実行 #20", 27 | 28 | "/actions/laserpointer" : "レーザーポインター", 29 | 30 | "/actions/laserpointer/in/LeftClick" : "左クリック", 31 | "/actions/laserpointer/in/RightClick" : "右クリック", 32 | "/actions/laserpointer/in/MiddleClick" : "ホイールクリック", 33 | "/actions/laserpointer/in/Aux01Click" : "補助 1 クリック", 34 | "/actions/laserpointer/in/Aux02Click" : "補助 2 クリック", 35 | 36 | "/actions/scroll_discrete" : "マウスホイール スクロール", 37 | 38 | "/actions/scroll_discrete/in/ScrollDiscrete" : "スクロールオーバーレイ", 39 | 40 | "/actions/scroll_smooth" : "スムーズ スクロール", 41 | 42 | "/actions/scroll_smooth/in/ScrollSmooth" : "スクロールオーバーレイ" 43 | } 44 | -------------------------------------------------------------------------------- /assets/input/action_manifest_zh_CN.json: -------------------------------------------------------------------------------- 1 | { 2 | "language_tag": "zh_CN", 3 | 4 | "/actions/shortcuts" : "全局快捷键", 5 | 6 | "/actions/shortcuts/in/EnableGlobalLaserPointer" : "启用全局激光指针", 7 | "/actions/shortcuts/in/GlobalShortcut01" : "执行全局快捷键 #1", 8 | "/actions/shortcuts/in/GlobalShortcut02" : "执行全局快捷键 #2", 9 | "/actions/shortcuts/in/GlobalShortcut03" : "执行全局快捷键 #3", 10 | "/actions/shortcuts/in/GlobalShortcut04" : "执行全局快捷键 #4", 11 | "/actions/shortcuts/in/GlobalShortcut05" : "执行全局快捷键 #5", 12 | "/actions/shortcuts/in/GlobalShortcut06" : "执行全局快捷键 #6", 13 | "/actions/shortcuts/in/GlobalShortcut07" : "执行全局快捷键 #7", 14 | "/actions/shortcuts/in/GlobalShortcut08" : "执行全局快捷键 #8", 15 | "/actions/shortcuts/in/GlobalShortcut09" : "执行全局快捷键 #9", 16 | "/actions/shortcuts/in/GlobalShortcut10" : "执行全局快捷键 #10", 17 | "/actions/shortcuts/in/GlobalShortcut11" : "执行全局快捷键 #11", 18 | "/actions/shortcuts/in/GlobalShortcut12" : "执行全局快捷键 #12", 19 | "/actions/shortcuts/in/GlobalShortcut13" : "执行全局快捷键 #13", 20 | "/actions/shortcuts/in/GlobalShortcut14" : "执行全局快捷键 #14", 21 | "/actions/shortcuts/in/GlobalShortcut15" : "执行全局快捷键 #15", 22 | "/actions/shortcuts/in/GlobalShortcut16" : "执行全局快捷键 #16", 23 | "/actions/shortcuts/in/GlobalShortcut17" : "执行全局快捷键 #17", 24 | "/actions/shortcuts/in/GlobalShortcut18" : "执行全局快捷键 #18", 25 | "/actions/shortcuts/in/GlobalShortcut19" : "执行全局快捷键 #19", 26 | "/actions/shortcuts/in/GlobalShortcut20" : "执行全局快捷键 #20", 27 | 28 | "/actions/laserpointer" : "激光指针", 29 | 30 | "/actions/laserpointer/in/LeftClick" : "左键点击", 31 | "/actions/laserpointer/in/RightClick" : "右键点击", 32 | "/actions/laserpointer/in/MiddleClick" : "中键点击", 33 | "/actions/laserpointer/in/Aux01Click" : "辅助1点击", 34 | "/actions/laserpointer/in/Aux02Click" : "辅助2点击", 35 | "/actions/laserpointer/in/Drag" : "拖动叠加", 36 | 37 | "/actions/scroll_discrete" : "鼠标滚轮滚动", 38 | 39 | "/actions/scroll_discrete/in/ScrollDiscrete" : "滚动叠加", 40 | 41 | "/actions/scroll_smooth" : "平滑滚动", 42 | 43 | "/actions/scroll_smooth/in/ScrollSmooth" : "滚动叠加" 44 | } 45 | -------------------------------------------------------------------------------- /assets/manifest.vrmanifest: -------------------------------------------------------------------------------- 1 | { 2 | "source": "builtin", 3 | "applications": [ 4 | { 5 | "app_key": "steam.overlay.1494460", 6 | 7 | "launch_type": "binary", 8 | "binary_path_windows": "DesktopPlus.exe", 9 | "is_dashboard_overlay": true, 10 | "action_manifest_path" : "action_manifest.json", 11 | "image_path" : "images/desktop_plus_capsule.png", 12 | 13 | "strings": { 14 | "en_us": { 15 | "name": "Desktop+", 16 | "description": "Desktop+ Overlay" 17 | } 18 | } 19 | }, 20 | { 21 | "app_key": "elvissteinjr.DesktopPlusTheaterScreen", 22 | 23 | "launch_type": "binary", 24 | "binary_path_windows": "DesktopPlus.exe", 25 | "starts_theater_mode": true, 26 | "is_hidden": true, 27 | "is_internal": true, 28 | 29 | "strings": { 30 | "en_us": { 31 | "name": "Desktop+ Theater Screen", 32 | "description": "Desktop+ Theater Screen" 33 | } 34 | } 35 | }] 36 | } 37 | -------------------------------------------------------------------------------- /assets/misc/!About this folder.txt: -------------------------------------------------------------------------------- 1 | This folder contains scripts enabling Desktop+ to gain higher access rights. 2 | The scripts are provided for convenience. Changes made by these scripts are inherently unsafe due to SteamVR running from an 3 | user-writable location among other things. 4 | 5 | ! Use your own judgment before running any of them. Don't use them if you don't know what you're doing. 6 | ! The author of Desktop+ shall not be liable for any damage caused by the use of these scripts. 7 | 8 | The .ps1 PowerShell scripts require to be run as administrator. The .bat files will try do that for you, so it's recommended to 9 | use those instead. 10 | Make sure Desktop+ is not running before executing them. 11 | 12 | 13 | CreateElevatedTask.ps1: 14 | - 15 | Creates a scheduled task to enable use of Desktop+'s elevated mode. 16 | Elevated mode allows inputs and actions to be executed with administrator privileges, getting around most restrictions of User 17 | Interface Privilege Isolation (UIPI), which it is subject to otherwise. 18 | After running this script, elevated mode can be accessed via [Misc|Troubleshooting|Desktop+: Enter Elevated Mode]. 19 | If you move Desktop+'s files, the scheduled task will break but the button remains. Re-run the script to fix this. 20 | 21 | Note that actions launching applications will run them with the same privileges as Desktop+, so be careful if you don't intend 22 | them to have administrator rights. 23 | Leave elevated mode again as soon as possible. 24 | 25 | 26 | EnableUIAccess.ps1: 27 | - 28 | Enables UIAccess rights for Desktop+ to lift interaction restrictions with higher privileged applications and UAC prompts. 29 | This is done by signing the DesktopPlus.exe executable with a self-signed certificate, using a different side-by-side manifest 30 | and changing group policies if needed. 31 | 32 | Compared to elevated mode, this enables Desktop+ to simulate input on any applications, including UAC prompts, at any time while 33 | not running with administrator privileges. 34 | This script needs to be run again after Desktop+ has been updated or otherwise modified. 35 | 36 | The following group policy is changed by the script: 37 | - "User Account Control: Only elevate UIAccess applications that are installed in secure locations" (set to 0) (only if needed) 38 | 39 | In order for Desktop+ to be able to mirror and interact with UAC prompts, the UAC level has to be lowered to not display the 40 | prompts on the secure desktop ("do not dim my desktop"). 41 | The elevated scheduled task has to be recreated after enabling UIAccess for the first time or entering elevated mode will fail. 42 | 43 | 44 | UndoSystemChanges.ps1: 45 | - 46 | Reverts system-wide changes made by above scripts. 47 | The script does not revert changes made to group policies as it may impact other applications. -------------------------------------------------------------------------------- /assets/misc/CreateElevatedTask.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | pushd %~dp0 4 | echo Launching script with administrator privileges... 5 | powershell -command " Start-Process PowerShell -Verb RunAs \""-ExecutionPolicy Bypass -Command `\""cd '%cd%'; & '.\CreateElevatedTask.ps1';`\""\"" " 6 | -------------------------------------------------------------------------------- /assets/misc/CreateElevatedTask.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | $msg = "Desktop+ Elevated Scheduled Task Creation Script 4 | ------------------------------------------------ 5 | This creates an elevated scheduled task for Desktop+ to allow entering elevated mode without UAC prompt to simulate inputs with administrator rights. 6 | Desktop+ will only use this task when the button in the UI is used to enter elevated mode. 7 | Please keep the security implications of doing this in mind. 8 | At the very least consider restricting write access to the Desktop+ executable file. 9 | " 10 | 11 | Write-Host $msg 12 | 13 | #Ask before continuing 14 | $opt_yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Create scheduled task and enable elevated mode for Desktop+" 15 | $opt_no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", 'Cancel' 16 | $options = [System.Management.Automation.Host.ChoiceDescription[]]($opt_yes, $opt_no) 17 | 18 | $result = $host.ui.PromptForChoice("", "Continue and create the scheduled task?", $options, 1) 19 | 20 | if ($result -eq 1) 21 | { 22 | exit 23 | } 24 | 25 | #Apply the changes 26 | 27 | #Command and arguments for the scheduled task 28 | $command = $PSScriptRoot + "\..\DesktopPlus.exe" 29 | $arg = "-ElevatedMode" 30 | 31 | #Check if UIAccess is currently enabled 32 | $sel = Select-String -Path "..\DesktopPlus.exe.manifest" -Pattern "uiAccess=`"true`"" 33 | 34 | #String found means UIAccess is enabled 35 | if ($sel -ne $null) 36 | { 37 | #Change the command and arguments to use cmd as a workaround since the elevated scheduled task can't be run directly when UIAccess is enabled 38 | $command = "cmd" 39 | $arg = "/c `"start DesktopPlus.exe -ElevatedMode`"" 40 | } 41 | 42 | 43 | #We use an XML file with schtasks instead of the Powershell cmdlets as we can create the task from an elevated session without additional password input this way. 44 | $xml = ' 45 | 46 | 47 | Desktop+ 48 | This scheduled task is run manually by Desktop+ in order to allow it to be run with adminstrator rights without UAC prompt. 49 | Desktop+ will only use it when the button in the settings is used to switch into elevated mode. 50 | 51 | 52 | 53 | 54 | InteractiveToken 55 | HighestAvailable 56 | 57 | 58 | 59 | Parallel 60 | false 61 | false 62 | false 63 | false 64 | false 65 | 66 | false 67 | false 68 | 69 | true 70 | true 71 | false 72 | false 73 | false 74 | PT0S 75 | 7 76 | 77 | 78 | 79 | ' + $command + ' 80 | ' + $arg + ' 81 | '+ $PSScriptRoot + '\.. 82 | 83 | 84 | ' 85 | 86 | #Write XML to file 87 | $xml | Set-Content .\DesktopPlusElevatedTask.xml 88 | 89 | #Create task 90 | schtasks /Create /TN "DesktopPlus Elevated" /XML "DesktopPlusElevatedTask.xml" /F 91 | 92 | #Delete the XML file after we're done 93 | Remove-Item DesktopPlusElevatedTask.xml 94 | 95 | Write-Output "`n" 96 | 97 | cmd /c pause 98 | -------------------------------------------------------------------------------- /assets/misc/EnableUIAccess.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | pushd %~dp0 4 | echo Launching script with administrator privileges... 5 | powershell -command " Start-Process PowerShell -Verb RunAs \""-ExecutionPolicy Bypass -Command `\""cd '%cd%'; & '.\EnableUIAccess.ps1';`\""\"" " 6 | -------------------------------------------------------------------------------- /assets/misc/EnableUIAccess.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | $msg = "Desktop+ UIAccess Setup Script 4 | ------------------------------ 5 | This enables UIAccess rights for Desktop+ to lift interaction restrictions with higher privileged applications and UAC prompts. 6 | This is done by signing the DesktopPlus.exe executable with a self-signed certificate, using a different side-by-side manifest and changing group policies if needed. 7 | The private key of the certificate created in this script is deleted afterwards and does not remain on the system. 8 | Nevertheless it's recommended to inspect what this script does and use your own judgement before just running this. 9 | The script needs to be run again each time Desktop+ has been updated or otherwise modified. 10 | " 11 | 12 | Write-Host $msg 13 | 14 | #Ask before continuing 15 | $opt_yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Apply changes and enable UIAccess for Desktop+" 16 | $opt_no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", 'Cancel' 17 | $options = [System.Management.Automation.Host.ChoiceDescription[]]($opt_yes, $opt_no) 18 | 19 | $result = $host.ui.PromptForChoice("", "Continue and apply these changes?", $options, 1) 20 | 21 | if ($result -eq 1) 22 | { 23 | exit 24 | } 25 | 26 | #Apply the changes 27 | $CertificateSubject = "DesktopPlus UIAccess Script" 28 | 29 | #Remove old certificates if they exist 30 | Get-ChildItem Cert:\LocalMachine\Root | 31 | Where-Object { $_.Subject -match $CertificateSubject } | 32 | Remove-Item 33 | 34 | Get-ChildItem Cert:\LocalMachine\CA | 35 | Where-Object { $_.Subject -match $CertificateSubject } | 36 | Remove-Item 37 | 38 | 39 | #Create the new self-signed certificate 40 | $cert = New-SelfSignedCertificate -CertStoreLocation Cert:\LocalMachine\My -Type CodeSigningCert -Subject $CertificateSubject -NotAfter (Get-Date).AddYears(5) 41 | 42 | #Export the certificate to import it again as a root certificate, but without the private key 43 | Export-Certificate -Cert $cert -FilePath ".\DesktopPlusCert.cer" | Out-Null 44 | Import-Certificate -FilePath ".\DesktopPlusCert.cer" -CertStoreLocation "Cert:\LocalMachine\Root" | Out-Null 45 | 46 | 47 | #Sign DesktopPlus.exe 48 | Set-AuthenticodeSignature -FilePath "..\DesktopPlus.exe" -Certificate $cert | Out-Null 49 | 50 | 51 | #Backup normal side-by-side manifest (doesn't overwrite if already exists) 52 | Move-Item "..\DesktopPlus.exe.manifest" -Destination "EnableUIAccessDesktopPlusBackup.manifest" -ErrorAction SilentlyContinue 53 | #Replace side-by-side manifest with the UIAccess enabled one 54 | Copy-Item "EnableUIAccessDesktopPlus.manifest" -Destination "..\DesktopPlus.exe.manifest" 55 | 56 | 57 | #Disable "User Account Control: Only elevate UIAccess applications that are installed in secure locations" group policy if we are outside of the Program Files directory 58 | if (!$pwd.path.StartsWith($env:ProgramFiles)) 59 | { 60 | Set-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "EnableSecureUIAPaths" -Value 0 61 | } 62 | 63 | 64 | #Cleanup 65 | Remove-Item ".\DesktopPlusCert.cer" 66 | 67 | #We do not leave the certificate with the private key on the system. Signing with it was a one-time thing. 68 | Set-Location "Cert:" 69 | $cert | Remove-Item -DeleteKey 70 | 71 | Write-Host "Done." 72 | Write-Output "`n" 73 | 74 | cmd /c pause -------------------------------------------------------------------------------- /assets/misc/EnableUIAccessDesktopPlus.manifest: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | True/PM 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /assets/misc/UndoSystemChanges.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | pushd %~dp0 4 | echo Launching script with administrator privileges... 5 | powershell -command " Start-Process PowerShell -Verb RunAs \""-ExecutionPolicy Bypass -Command `\""cd '%cd%'; & '.\UndoSystemChanges.ps1';`\""\"" " 6 | -------------------------------------------------------------------------------- /assets/misc/UndoSystemChanges.ps1: -------------------------------------------------------------------------------- 1 | #Requires -RunAsAdministrator 2 | 3 | $msg = "Desktop+ Cleanup Script 4 | ----------------------- 5 | This reverts system-wide changes made by the scripts in the `"misc`" folder of Desktop+. 6 | 7 | It removes the following: 8 | - `"DesktopPlus Elevated`" scheduled task 9 | - `"DesktopPlus UIAccess Script`" self-signed certificates 10 | - Desktop+ UIAccess side-by-side manifest 11 | 12 | Not reverted are changes which may impact other applications or may not have been different from the start, such as: 13 | - `"User Account Control: Only elevate UIAccess applications that are installed in secure locations`" group policy 14 | " 15 | 16 | Write-Host $msg 17 | 18 | #Ask before continuing 19 | $opt_yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Undo changes made by Desktop+ scripts" 20 | $opt_no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", 'Cancel' 21 | $options = [System.Management.Automation.Host.ChoiceDescription[]]($opt_yes, $opt_no) 22 | 23 | $result = $host.ui.PromptForChoice("", "Continue and undo these changes?", $options, 1) 24 | 25 | if ($result -eq 1) 26 | { 27 | exit 28 | } 29 | 30 | #Delete scheduled task if it exists 31 | 32 | schtasks /Query /TN "DesktopPlus Elevated" *>$null 33 | if ($LastExitCode -eq 0) 34 | { 35 | schtasks /Delete /TN "DesktopPlus Elevated" /F 36 | } 37 | 38 | #Remove certificates 39 | Get-ChildItem Cert:\LocalMachine\Root | 40 | Where-Object { $_.Subject -match $CertificateSubject } | 41 | Remove-Item 42 | 43 | Get-ChildItem Cert:\LocalMachine\CA | 44 | Where-Object { $_.Subject -match $CertificateSubject } | 45 | Remove-Item 46 | 47 | #Restore previously backed-up side-by-side manifest if it exists 48 | if (Test-Path -Path "EnableUIAccessDesktopPlusBackup.manifest") 49 | { 50 | Move-Item "EnableUIAccessDesktopPlusBackup.manifest" -Destination "..\DesktopPlus.exe.manifest" -Force 51 | } 52 | 53 | Write-Host "Done." 54 | Write-Output "`n" 55 | 56 | cmd /c pause -------------------------------------------------------------------------------- /assets/openvr_api.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/assets/openvr_api.dll -------------------------------------------------------------------------------- /docs/images/desktop_mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/desktop_mode.png -------------------------------------------------------------------------------- /docs/images/floating_ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/floating_ui.png -------------------------------------------------------------------------------- /docs/images/keyboard_layout_editor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/keyboard_layout_editor.png -------------------------------------------------------------------------------- /docs/images/overlay_bar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/overlay_bar.png -------------------------------------------------------------------------------- /docs/images/overlay_properties_advanced.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/overlay_properties_advanced.png -------------------------------------------------------------------------------- /docs/images/overlay_properties_appearance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/overlay_properties_appearance.png -------------------------------------------------------------------------------- /docs/images/overlay_properties_browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/overlay_properties_browser.png -------------------------------------------------------------------------------- /docs/images/overlay_properties_capture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/overlay_properties_capture.png -------------------------------------------------------------------------------- /docs/images/overlay_properties_interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/overlay_properties_interface.png -------------------------------------------------------------------------------- /docs/images/overlay_properties_page_change_position.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/overlay_properties_page_change_position.png -------------------------------------------------------------------------------- /docs/images/overlay_properties_page_cropping_area.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/overlay_properties_page_cropping_area.png -------------------------------------------------------------------------------- /docs/images/overlay_properties_performance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/overlay_properties_performance.png -------------------------------------------------------------------------------- /docs/images/overlay_properties_performance_monitor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/overlay_properties_performance_monitor.png -------------------------------------------------------------------------------- /docs/images/overlay_properties_position.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/overlay_properties_position.png -------------------------------------------------------------------------------- /docs/images/settings_actions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_actions.png -------------------------------------------------------------------------------- /docs/images/settings_browser.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_browser.png -------------------------------------------------------------------------------- /docs/images/settings_environment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_environment.png -------------------------------------------------------------------------------- /docs/images/settings_interface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_interface.png -------------------------------------------------------------------------------- /docs/images/settings_keyboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_keyboard.png -------------------------------------------------------------------------------- /docs/images/settings_laser_pointer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_laser_pointer.png -------------------------------------------------------------------------------- /docs/images/settings_mouse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_mouse.png -------------------------------------------------------------------------------- /docs/images/settings_page_application_profiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_page_application_profiles.png -------------------------------------------------------------------------------- /docs/images/settings_page_change_action_order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_page_change_action_order.png -------------------------------------------------------------------------------- /docs/images/settings_page_edit_action.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_page_edit_action.png -------------------------------------------------------------------------------- /docs/images/settings_page_keyboard_layout.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_page_keyboard_layout.png -------------------------------------------------------------------------------- /docs/images/settings_page_manage_actions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_page_manage_actions.png -------------------------------------------------------------------------------- /docs/images/settings_page_overlay_profiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_page_overlay_profiles.png -------------------------------------------------------------------------------- /docs/images/settings_page_persistent_ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_page_persistent_ui.png -------------------------------------------------------------------------------- /docs/images/settings_page_restore_defaults.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_page_restore_defaults.png -------------------------------------------------------------------------------- /docs/images/settings_performance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_performance.png -------------------------------------------------------------------------------- /docs/images/settings_profiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_profiles.png -------------------------------------------------------------------------------- /docs/images/settings_startup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_startup.png -------------------------------------------------------------------------------- /docs/images/settings_troubleshooting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_troubleshooting.png -------------------------------------------------------------------------------- /docs/images/settings_version_info.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_version_info.png -------------------------------------------------------------------------------- /docs/images/settings_warnings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_warnings.png -------------------------------------------------------------------------------- /docs/images/settings_window_overlays.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/settings_window_overlays.png -------------------------------------------------------------------------------- /docs/images/vr_keyboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/images/vr_keyboard.png -------------------------------------------------------------------------------- /docs/screenshot.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/docs/screenshot.jpg -------------------------------------------------------------------------------- /src/DesktopPlus.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.29519.87 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DesktopPlus", "DesktopPlus\DesktopPlus.vcxproj", "{05050918-71E9-AF87-0B3C-6F34D471A55A}" 7 | ProjectSection(ProjectDependencies) = postProject 8 | {045FFB0E-D0D4-404D-8C33-13C7074B3236} = {045FFB0E-D0D4-404D-8C33-13C7074B3236} 9 | EndProjectSection 10 | EndProject 11 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DesktopPlusUI", "DesktopPlusUI\DesktopPlusUI.vcxproj", "{14405CEC-DF3D-435E-8F11-B79BAC56D7D8}" 12 | ProjectSection(ProjectDependencies) = postProject 13 | {045FFB0E-D0D4-404D-8C33-13C7074B3236} = {045FFB0E-D0D4-404D-8C33-13C7074B3236} 14 | EndProjectSection 15 | EndProject 16 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DesktopPlusWinRT", "DesktopPlusWinRT\DesktopPlusWinRT.vcxproj", "{045FFB0E-D0D4-404D-8C33-13C7074B3236}" 17 | EndProject 18 | Global 19 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 20 | Debug|x64 = Debug|x64 21 | Release|x64 = Release|x64 22 | EndGlobalSection 23 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 24 | {05050918-71E9-AF87-0B3C-6F34D471A55A}.Debug|x64.ActiveCfg = Debug|x64 25 | {05050918-71E9-AF87-0B3C-6F34D471A55A}.Debug|x64.Build.0 = Debug|x64 26 | {05050918-71E9-AF87-0B3C-6F34D471A55A}.Release|x64.ActiveCfg = Release|x64 27 | {05050918-71E9-AF87-0B3C-6F34D471A55A}.Release|x64.Build.0 = Release|x64 28 | {14405CEC-DF3D-435E-8F11-B79BAC56D7D8}.Debug|x64.ActiveCfg = Debug|x64 29 | {14405CEC-DF3D-435E-8F11-B79BAC56D7D8}.Debug|x64.Build.0 = Debug|x64 30 | {14405CEC-DF3D-435E-8F11-B79BAC56D7D8}.Release|x64.ActiveCfg = Release|x64 31 | {14405CEC-DF3D-435E-8F11-B79BAC56D7D8}.Release|x64.Build.0 = Release|x64 32 | {045FFB0E-D0D4-404D-8C33-13C7074B3236}.Debug|x64.ActiveCfg = Debug|x64 33 | {045FFB0E-D0D4-404D-8C33-13C7074B3236}.Debug|x64.Build.0 = Debug|x64 34 | {045FFB0E-D0D4-404D-8C33-13C7074B3236}.Release|x64.ActiveCfg = Release|x64 35 | {045FFB0E-D0D4-404D-8C33-13C7074B3236}.Release|x64.Build.0 = Release|x64 36 | EndGlobalSection 37 | GlobalSection(SolutionProperties) = preSolution 38 | HideSolutionNode = FALSE 39 | EndGlobalSection 40 | GlobalSection(ExtensibilityGlobals) = postSolution 41 | SolutionGuid = {6AC6EA93-8452-42F0-A7BF-B88BDB800DB6} 42 | EndGlobalSection 43 | EndGlobal 44 | -------------------------------------------------------------------------------- /src/DesktopPlus/BackgroundOverlay.cpp: -------------------------------------------------------------------------------- 1 | #include "BackgroundOverlay.h" 2 | 3 | #include "ConfigManager.h" 4 | #include "OutputManager.h" 5 | 6 | BackgroundOverlay::BackgroundOverlay() : m_OvrlHandle(vr::k_ulOverlayHandleInvalid) 7 | { 8 | //Not calling Update() here since the OutputManager typically needs to load the config and OpenVR first 9 | } 10 | 11 | BackgroundOverlay::~BackgroundOverlay() 12 | { 13 | if ((m_OvrlHandle != vr::k_ulOverlayHandleInvalid) && (vr::VROverlay() != nullptr)) 14 | { 15 | vr::VROverlay()->DestroyOverlay(m_OvrlHandle); 16 | } 17 | } 18 | 19 | void BackgroundOverlay::Update() 20 | { 21 | InterfaceBGColorDisplayMode display_mode = (InterfaceBGColorDisplayMode)ConfigManager::GetValue(configid_int_interface_background_color_display_mode); 22 | if (display_mode == ui_bgcolor_dispmode_never) 23 | { 24 | //Don't keep the overlay around if it's absolutely not needed (which is the case most of the time) 25 | if (m_OvrlHandle != vr::k_ulOverlayHandleInvalid) 26 | { 27 | vr::VROverlay()->DestroyOverlay(m_OvrlHandle); 28 | m_OvrlHandle = vr::k_ulOverlayHandleInvalid; 29 | } 30 | } 31 | else 32 | { 33 | //Create overlay if it doesn't exist yet 34 | if (m_OvrlHandle == vr::k_ulOverlayHandleInvalid) 35 | { 36 | vr::EVROverlayError ovrl_error = vr::VROverlay()->CreateOverlay("elvissteinjr.DesktopPlusBackground", "Desktop+ Background", &m_OvrlHandle); 37 | 38 | if (ovrl_error != vr::VROverlayError_None) 39 | return; 40 | 41 | //Fill overlay with some pixels 42 | unsigned char bytes[2 * 2 * 4]; 43 | std::fill(std::begin(bytes), std::end(bytes), 255); //Full white RGBA 44 | 45 | vr::VROverlay()->SetOverlayRaw(m_OvrlHandle, bytes, 2, 2, 4); 46 | 47 | //The trick to this overlay is to set it as a panorama attached to the HMD 48 | //Panorama overlays are weird in that they essentially poke a hole into the rendering in the area they'd cover normally 49 | //By doing this we ensure to always cover the field of view. The actual panorama is rendered in front of scene content, but positioned behind all overlays 50 | //IVRCompositor::FadeToColor() can achieve a similar effect, but the colors are washed out. Impossible to achieve full black with it. 51 | vr::VROverlay()->SetOverlayFlag(m_OvrlHandle, vr::VROverlayFlags_Panorama, true); 52 | vr::VROverlay()->SetOverlayWidthInMeters(m_OvrlHandle, 100.0f); 53 | 54 | Matrix4 transform; 55 | transform.setTranslation({0.0f, 0.0f, -10.0f}); 56 | vr::HmdMatrix34_t transform_openvr = transform.toOpenVR34(); 57 | vr::VROverlay()->SetOverlayTransformTrackedDeviceRelative(m_OvrlHandle, vr::k_unTrackedDeviceIndex_Hmd, &transform_openvr); 58 | } 59 | 60 | bool display_overlay = true; //ui_bgcolor_dispmode_always 61 | 62 | if (display_mode == ui_bgcolor_dispmode_dplustab) 63 | { 64 | display_overlay = ((OutputManager::Get()) && (OutputManager::Get()->IsDashboardTabActive())); 65 | } 66 | 67 | if (display_overlay) 68 | { 69 | //Unpack color value 70 | unsigned int rgba = pun_cast(ConfigManager::GetValue(configid_int_interface_background_color)); 71 | float r = (rgba & 0x000000FF) / 255.0f; 72 | float g = ((rgba & 0x0000FF00) >> 8) / 255.0f; 73 | float b = ((rgba & 0x00FF0000) >> 16) / 255.0f; 74 | float a = ((rgba & 0xFF000000) >> 24) / 255.0f; 75 | 76 | vr::VROverlay()->SetOverlayColor(m_OvrlHandle, r, g, b); 77 | vr::VROverlay()->SetOverlayAlpha(m_OvrlHandle, a); 78 | 79 | if (!vr::VROverlay()->IsOverlayVisible(m_OvrlHandle)) 80 | { 81 | vr::VROverlay()->ShowOverlay(m_OvrlHandle); 82 | } 83 | } 84 | else if (vr::VROverlay()->IsOverlayVisible(m_OvrlHandle)) 85 | { 86 | vr::VROverlay()->HideOverlay(m_OvrlHandle); 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/DesktopPlus/BackgroundOverlay.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "openvr.h" 4 | 5 | class BackgroundOverlay 6 | { 7 | private: 8 | vr::VROverlayHandle_t m_OvrlHandle; 9 | 10 | public: 11 | BackgroundOverlay(); 12 | ~BackgroundOverlay(); 13 | void Update(); 14 | }; -------------------------------------------------------------------------------- /src/DesktopPlus/DesktopPlus.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/DesktopPlus/DesktopPlus.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/src/DesktopPlus/DesktopPlus.rc -------------------------------------------------------------------------------- /src/DesktopPlus/DesktopPlus.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(OutputPath) 5 | WindowsLocalDebugger 6 | 7 | 8 | $(OutputPath) 9 | WindowsLocalDebugger 10 | 11 | -------------------------------------------------------------------------------- /src/DesktopPlus/DisplayManager.h: -------------------------------------------------------------------------------- 1 | #ifndef _DISPLAYMANAGER_H_ 2 | #define _DISPLAYMANAGER_H_ 3 | 4 | #include "CommonTypes.h" 5 | 6 | // 7 | // Handles the task of processing frames 8 | // 9 | class DISPLAYMANAGER 10 | { 11 | public: 12 | DISPLAYMANAGER(); 13 | ~DISPLAYMANAGER(); 14 | void InitD3D(DX_RESOURCES* Data); 15 | ID3D11Device* GetDevice(); 16 | DUPL_RETURN ProcessFrame(_In_ FRAME_DATA* Data, _Inout_ ID3D11Texture2D* SharedSurf, INT OffsetX, INT OffsetY, _In_ DXGI_OUTPUT_DESC* DeskDesc, _Inout_ DPRect& DirtyRectTotal); 17 | void CleanRefs(); 18 | 19 | private: 20 | // methods 21 | DUPL_RETURN CopyDirty(_In_ ID3D11Texture2D* SrcSurface, _Inout_ ID3D11Texture2D* SharedSurf, _In_reads_(DirtyCount) RECT* DirtyBuffer, UINT DirtyCount, INT OffsetX, INT OffsetY, 22 | _In_ DXGI_OUTPUT_DESC* DeskDesc, _Inout_ DPRect& DirtyRectTotal); 23 | DUPL_RETURN CopyMove(_Inout_ ID3D11Texture2D* SharedSurf, _In_reads_(MoveCount) DXGI_OUTDUPL_MOVE_RECT* MoveBuffer, UINT MoveCount, INT OffsetX, INT OffsetY, _In_ DXGI_OUTPUT_DESC* DeskDesc, 24 | INT TexWidth, INT TexHeight, _Inout_ DPRect& DirtyRectTotal); 25 | void SetDirtyVert(_Out_writes_(NUMVERTICES) VERTEX* Vertices, _In_ RECT* Dirty, INT OffsetX, INT OffsetY, _In_ DXGI_OUTPUT_DESC* DeskDesc, _In_ D3D11_TEXTURE2D_DESC* FullDesc, 26 | _In_ D3D11_TEXTURE2D_DESC* ThisDesc, _Inout_ DPRect& DirtyRectTotal); 27 | void SetMoveRect(_Out_ RECT* SrcRect, _Out_ RECT* DestRect, _In_ DXGI_OUTPUT_DESC* DeskDesc, _In_ DXGI_OUTDUPL_MOVE_RECT* MoveRect, INT TexWidth, INT TexHeight); 28 | 29 | // variables 30 | ID3D11Device* m_Device; 31 | ID3D11DeviceContext* m_DeviceContext; 32 | ID3D11Texture2D* m_MoveSurf; 33 | ID3D11VertexShader* m_VertexShader; 34 | ID3D11PixelShader* m_PixelShader; 35 | ID3D11InputLayout* m_InputLayout; 36 | ID3D11RenderTargetView* m_RTV; 37 | ID3D11SamplerState* m_SamplerLinear; 38 | BYTE* m_DirtyVertexBufferAlloc; 39 | UINT m_DirtyVertexBufferAllocSize; 40 | }; 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/DesktopPlus/DuplicationManager.h: -------------------------------------------------------------------------------- 1 | #ifndef _DUPLICATIONMANAGER_H_ 2 | #define _DUPLICATIONMANAGER_H_ 3 | 4 | #include "CommonTypes.h" 5 | 6 | // 7 | // Handles the task of duplicating an output. 8 | // 9 | class DUPLICATIONMANAGER 10 | { 11 | public: 12 | DUPLICATIONMANAGER(); 13 | ~DUPLICATIONMANAGER(); 14 | _Success_(*Timeout == false && return == DUPL_RETURN_SUCCESS) DUPL_RETURN GetFrame(_Out_ FRAME_DATA* Data, _Out_ bool* Timeout); 15 | DUPL_RETURN DoneWithFrame(); 16 | DUPL_RETURN InitDupl(_In_ ID3D11Device* Device, UINT Output, bool WMRIgnoreVScreens, bool UseHDR); 17 | DUPL_RETURN GetMouse(_Inout_ PTR_INFO* PtrInfo, _In_ DXGI_OUTDUPL_FRAME_INFO* FrameInfo, INT OffsetX, INT OffsetY); 18 | void GetOutputDesc(_Out_ DXGI_OUTPUT_DESC* DescPtr); 19 | 20 | private: 21 | 22 | // vars 23 | IDXGIOutputDuplication* m_DeskDupl; 24 | ID3D11Texture2D* m_AcquiredDesktopImage; 25 | _Field_size_bytes_(m_MetaDataSize) BYTE* m_MetaDataBuffer; 26 | UINT m_MetaDataSize; 27 | UINT m_OutputNumber; 28 | DXGI_OUTPUT_DESC m_OutputDesc; 29 | ID3D11Device* m_Device; 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/DesktopPlus/ElevatedMode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define NOMINMAX 4 | #include 5 | 6 | //This runs the process in elevated input command mode, in which it only takes select window messages and passes them to InputSimulator. 7 | // 8 | //This isn't secure at all, I'm well aware. 9 | //There are certainly other more complex ways of implementation to make this seem more secure than the current one, but as far as I'm concerned we're fighting a battle that cannot be won. 10 | //As long as we're open source, not enforcing signed binaries and access rights to the application directory, there will always be an attack vector. 11 | //There's no way to actually trust the unelevated process requesting the inputs. Even if we isolated DesktopPlus.exe, we still couldn't trust SteamVR to not be compromised. 12 | //Both of these live in an environment where they are expected to be updated automatically by an unelevated process as well. 13 | // 14 | //The attack vector is at least smaller than when running Steam and everything related elevated as well. 15 | //Targeted attacks would be fairly easy if such code found the way of an user's machine, though. 16 | 17 | int ElevatedModeEnter(HINSTANCE hinstance); -------------------------------------------------------------------------------- /src/DesktopPlus/InputSimulator.h: -------------------------------------------------------------------------------- 1 | #ifndef _INPUTSIMULATOR_H_ 2 | #define _INPUTSIMULATOR_H_ 3 | 4 | #define NOMINMAX 5 | #include 6 | 7 | #include 8 | 9 | //Dashboard_Back exists, but not doesn't map to "Go Back" ...okay! 10 | #define Button_Dashboard_GoHome vr::k_EButton_IndexController_A 11 | #define Button_Dashboard_GoBack vr::k_EButton_IndexController_B 12 | 13 | enum IPCKeyboardKeystateFlags : unsigned char; 14 | 15 | //SyntheticPointer functions are loaded manually to not require OS support to run the application (Windows 10 1809+ should have them though) 16 | typedef HANDLE HSYNTHETICPOINTERDEVICE_DPLUS; 17 | #ifndef NTDDI_WIN10_RS5 18 | typedef enum { POINTER_FEEDBACK_DEFAULT = 1, POINTER_FEEDBACK_INDIRECT = 2, POINTER_FEEDBACK_NONE = 3 } POINTER_FEEDBACK_MODE; 19 | #endif 20 | 21 | typedef HSYNTHETICPOINTERDEVICE_DPLUS (WINAPI* fn_CreateSyntheticPointerDevice) (_In_ POINTER_INPUT_TYPE pointerType, _In_ ULONG maxCount, _In_ POINTER_FEEDBACK_MODE mode); 22 | typedef BOOL (WINAPI* fn_InjectSyntheticPointerInput) (_In_ HSYNTHETICPOINTERDEVICE_DPLUS device, _In_reads_(count) CONST POINTER_TYPE_INFO* pointerInfo, _In_ UINT32 count); 23 | typedef void (WINAPI* fn_DestroySyntheticPointerDevice)(_In_ HSYNTHETICPOINTERDEVICE_DPLUS device); 24 | 25 | class InputSimulator 26 | { 27 | private: 28 | int m_SpaceMaxX = 0; 29 | int m_SpaceMaxY = 0; 30 | float m_SpaceMultiplierX = 1.0f; 31 | float m_SpaceMultiplierY = 1.0f; 32 | int m_SpaceOffsetX = 0; 33 | int m_SpaceOffsetY = 0; 34 | 35 | static fn_CreateSyntheticPointerDevice s_p_CreateSyntheticPointerDevice; 36 | static fn_InjectSyntheticPointerInput s_p_InjectSyntheticPointerInput; 37 | static fn_DestroySyntheticPointerDevice s_p_DestroySyntheticPointerDevice; 38 | 39 | HSYNTHETICPOINTERDEVICE_DPLUS m_PenDevice = nullptr; 40 | POINTER_TYPE_INFO m_PenState = {0}; 41 | 42 | std::vector m_KeyboardTextQueue; 43 | bool m_ForwardToElevatedModeProcess = false; 44 | bool m_ElevatedModeHasTextQueued = false; 45 | 46 | void CreatePenDeviceIfNeeded(); 47 | 48 | static void LoadPenFunctions(); 49 | static void SetEventForMouseKeyCode(INPUT& input_event, unsigned char keycode, bool down); 50 | //Set the event if it would change key state. Returns if anything was written to input_event 51 | static bool SetEventForKeyCode(INPUT& input_event, unsigned char keycode, bool down, bool skip_check = false); 52 | 53 | public: 54 | InputSimulator(); 55 | ~InputSimulator(); 56 | void RefreshScreenOffsets(); 57 | 58 | void MouseMove(int x, int y); 59 | void MouseSetLeftDown(bool down); 60 | void MouseSetRightDown(bool down); 61 | void MouseSetMiddleDown(bool down); 62 | void MouseWheelHorizontal(float delta); 63 | void MouseWheelVertical(float delta); 64 | 65 | void PenMove(int x, int y); 66 | void PenSetPrimaryDown(bool down); 67 | void PenSetSecondaryDown(bool down); 68 | void PenLeave(); 69 | 70 | void KeyboardSetDown(unsigned char keycode); 71 | void KeyboardSetDown(unsigned char keycode, bool down); 72 | void KeyboardSetUp(unsigned char keycode); 73 | void KeyboardSetDown(unsigned char keycodes[3]); 74 | void KeyboardSetUp(unsigned char keycodes[3]); 75 | void KeyboardToggleState(unsigned char keycode); 76 | void KeyboardToggleState(unsigned char keycodes[3]); 77 | void KeyboardPressAndRelease(unsigned char keycode); 78 | void KeyboardSetToggleKey(unsigned char keycode, bool toggled); 79 | void KeyboardSetFromWin32KeyState(unsigned short keystate, bool down); //Keystate as returned by VkKeyScan() 80 | void KeyboardSetKeyState(IPCKeyboardKeystateFlags flags, unsigned char keycode); 81 | void KeyboardText(const char* str_utf8, bool always_use_unicode_event = false); 82 | void KeyboardTextFinish(); 83 | 84 | void SetElevatedModeForwardingActive(bool do_forward); 85 | 86 | static bool IsPenSimulationSupported(); 87 | static bool IsKeyDown(unsigned char keycode); 88 | }; 89 | 90 | #endif -------------------------------------------------------------------------------- /src/DesktopPlus/LaserPointer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "DPRect.h" 4 | #include "Overlays.h" 5 | #include "openvr.h" 6 | 7 | #include 8 | 9 | struct LaserPointerDevice 10 | { 11 | vr::VROverlayHandle_t OvrlHandle = vr::k_ulOverlayHandleInvalid; 12 | vr::VRInputValueHandle_t InputValueHandle = vr::k_ulInvalidInputValueHandle; 13 | bool UseHMDAsOrigin = false; 14 | bool IsVisible = false; 15 | float LaserLength = 0.0f; 16 | 17 | vr::VROverlayHandle_t OvrlHandleTargetLast = vr::k_ulOverlayHandleInvalid; 18 | OverlayTextureSource OvrlHandleTargetLastTextureSource = ovrl_texsource_none; 19 | bool IsActiveForMultiLaserInput = false; 20 | int InputDownCount = 0; 21 | bool IsDragDown = false; 22 | }; 23 | 24 | //Optional origin that can be passed to SetActiveDevice() in order to keep track what activated the laser pointer (and thus should be responsible for deactivating) 25 | enum LaserPointerActivationOrigin 26 | { 27 | dplp_activation_origin_none, 28 | dplp_activation_origin_auto_toggle, 29 | dplp_activation_origin_input_binding 30 | }; 31 | 32 | //Custom laser pointer implementation for use outside of the dashboard 33 | //Operates on Desktop+ and Desktop+ UI overlays, sending overlay events matching SteamVR laser input behavior as closely as possible 34 | //Actually sends middle mouse events when bound 35 | //Supports use of any tracked device that has the corrects inputs bound, though IsAnyOverlayHovered() only checks handed controllers for auto interaction toggle 36 | //Paralell/Multi-Laser input is supported for certain overlays that can handle it (currently only the VR keyboard) 37 | class LaserPointer 38 | { 39 | private: 40 | LaserPointerDevice m_Devices[vr::k_unMaxTrackedDeviceCount]; 41 | std::vector m_OverlayHandlesUI; 42 | std::vector m_OverlayHandlesMultiLaser; 43 | 44 | LaserPointerActivationOrigin m_ActivationOrigin; 45 | bool m_HadPrimaryPointerDevice; 46 | vr::TrackedDeviceIndex_t m_DeviceMaxActiveID; 47 | ULONGLONG m_LastPrimaryDeviceSwitchTick; 48 | ULONGLONG m_LastScrollTick; 49 | vr::TrackedDeviceIndex_t m_DeviceHapticPending; 50 | 51 | //State set by ForceTargetOverlay() 52 | bool m_IsForceTargetOverlayActive; 53 | vr::VROverlayHandle_t m_ForceTargetOverlayHandle; 54 | 55 | Vector2Int m_UIMouseScale; 56 | std::vector m_UIIntersectionMaskRects; 57 | std::vector m_UIIntersectionMaskRectsPending; 58 | 59 | void CreateDeviceOverlay(vr::TrackedDeviceIndex_t device_index); 60 | void UpdateDeviceOverlay(vr::TrackedDeviceIndex_t device_index); 61 | void UpdateIntersection(vr::TrackedDeviceIndex_t device_index); 62 | 63 | void SendDirectDragCommand(vr::VROverlayHandle_t overlay_handle_target, bool do_start_drag); 64 | 65 | public: 66 | LaserPointer(); 67 | ~LaserPointer(); 68 | 69 | void Update(); 70 | 71 | void SetActiveDevice(vr::TrackedDeviceIndex_t device_index, LaserPointerActivationOrigin activation_origin = dplp_activation_origin_none); 72 | void ClearActiveDevice(); 73 | void RemoveDevice(vr::TrackedDeviceIndex_t device_index); //Clears device entry, called on device disconnect 74 | 75 | void RefreshCachedOverlayHandles(); 76 | void TriggerLaserPointerHaptics(vr::TrackedDeviceIndex_t device_index) const; 77 | void ForceTargetOverlay(vr::VROverlayHandle_t overlay_handle); //Forces a different overlay to be current pointer target (only if there's currently one) 78 | 79 | //ComputeOverlayIntersection() does not take intersection masks into account. It's a bit cumbersome, but we track the DDP/UI ones ourselves to get around that. 80 | bool IntersectionMaskHitTest(OverlayTextureSource texsource, vr::HmdVector2_t& uv) const; 81 | void UIIntersectionMaskAddRect(DPRect& rect); 82 | void UIIntersectionMaskFinish(); 83 | 84 | LaserPointerActivationOrigin GetActivationOrigin() const; 85 | bool IsActive() const; 86 | vr::TrackedDeviceIndex_t IsAnyOverlayHovered(float max_distance) const; //Returns hovering device_index (or invalid if none). Only checks for LaserPointer supported overlays 87 | bool IsScrolling() const; 88 | }; -------------------------------------------------------------------------------- /src/DesktopPlus/Overlays.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "openvr.h" 4 | #include "DPRect.h" 5 | #include "OUtoSBSConverter.h" 6 | 7 | //About the Overlay class: 8 | //OutputManager's m_OvrlHandleDesktopTexture holds the actual texture handle for every other desktop duplication overlay created by SteamVR 9 | //This is *not* documented functionality in SteamVR, but it is the one with the best results. 10 | //Additional overlays are also almost free except for the compositor rendering them. 11 | //The alternative approach for this would be the documented way of using one texture handle for every overlay created by the overlay application, but this 12 | //prevents SteamVR from using the advanced overlay texture filter, so we'd get blurry overlays. Not good. 13 | //Given that variant exists, doing it this way is probably somewhat safe. It wouldn't be super hard to fix this up if it broke eventually, though. 14 | //Using a separate texture for every overlay would be slower and take up more memory, so there's honestly no upside of that. 15 | 16 | enum OverlayTextureSource 17 | { 18 | ovrl_texsource_invalid = -1, //Initial state, shouldn't be set to unless immediately calling SetTextureSource() to explicitly re-apply certain sources 19 | ovrl_texsource_none, //Used with capture sources other than desktop duplication while capture is not active 20 | ovrl_texsource_desktop_duplication, 21 | ovrl_texsource_desktop_duplication_3dou_converted, 22 | ovrl_texsource_winrt_capture, 23 | ovrl_texsource_ui, 24 | ovrl_texsource_browser 25 | }; 26 | 27 | class Overlay 28 | { 29 | private: 30 | unsigned int m_ID; 31 | vr::VROverlayHandle_t m_OvrlHandle; 32 | bool m_Visible; //IVROverlay::IsOverlayVisible() is unreliable if the state changed during the same frame so we keep track ourselves 33 | float m_Opacity; //This is the opacity the overlay is currently set at, which may differ from what the config value is 34 | DPRect m_ValidatedCropRect; //Validated cropping rectangle used in OutputManager::Update() to check against dirty update regions 35 | OverlayTextureSource m_TextureSource; 36 | OUtoSBSConverter m_OUtoSBSConverter; 37 | 38 | public: 39 | Overlay(unsigned int id); 40 | Overlay(Overlay&& b); 41 | Overlay& operator=(Overlay&& b); 42 | ~Overlay(); 43 | 44 | void InitOverlay(); 45 | void AssignDesktopDuplicationTexture(); 46 | unsigned int GetID() const; 47 | void SetID(unsigned int id); 48 | vr::VROverlayHandle_t GetHandle() const; 49 | void SetHandle(vr::VROverlayHandle_t handle); //Sets the handle of the overlay without calling DestroyOverlay() on the previous one, used by OverlayManager 50 | 51 | void SetOpacity(float opacity); 52 | float GetOpacity() const; 53 | 54 | void SetVisible(bool visible); //Call OutputManager::Show/HideOverlay() instead of this to properly manage duplication state based on active overlays 55 | bool IsVisible() const; 56 | bool ShouldBeVisible() const; 57 | 58 | void UpdateValidatedCropRect(); 59 | const DPRect& GetValidatedCropRect() const; 60 | 61 | void SetTextureSource(OverlayTextureSource tex_source); 62 | OverlayTextureSource GetTextureSource() const; 63 | void OnDesktopDuplicationUpdate(); //Called by OutputManager::RefreshOpenVROverlayTexture() for every overlay, but only if the texture has actually changed 64 | }; -------------------------------------------------------------------------------- /src/DesktopPlus/PixelShader.hlsl: -------------------------------------------------------------------------------- 1 | Texture2D tx : register( t0 ); 2 | SamplerState samLinear : register( s0 ); 3 | 4 | struct PS_INPUT 5 | { 6 | float4 Pos : SV_POSITION; 7 | float2 Tex : TEXCOORD; 8 | }; 9 | 10 | //-------------------------------------------------------------------------------------- 11 | // Pixel Shader 12 | //-------------------------------------------------------------------------------------- 13 | float4 PS(PS_INPUT input) : SV_Target 14 | { 15 | float4 color; 16 | color = tx.Sample(samLinear, input.Tex); 17 | color.a = (color.a > 0.0) ? 1.0 : 0.0; //Enforce 1-bit alpha as on some systems the duplication output isn't opaque for some reason 18 | return color; 19 | } -------------------------------------------------------------------------------- /src/DesktopPlus/PixelShaderCursor.hlsl: -------------------------------------------------------------------------------- 1 | Texture2D tx : register( t0 ); 2 | SamplerState samLinear : register( s0 ); 3 | 4 | struct PS_INPUT 5 | { 6 | float4 Pos : SV_POSITION; 7 | float2 Tex : TEXCOORD; 8 | }; 9 | 10 | //-------------------------------------------------------------------------------------- 11 | // Pixel Shader 12 | //-------------------------------------------------------------------------------------- 13 | float4 PSCURSOR(PS_INPUT input) : SV_Target 14 | { 15 | return tx.Sample(samLinear, input.Tex); 16 | } -------------------------------------------------------------------------------- /src/DesktopPlus/RadialFollowSmoothing.h: -------------------------------------------------------------------------------- 1 | /* This Source Code Form is subject to the terms of the Mozilla Public 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this 3 | * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 | 5 | //This header and accompanying source file is based on 6 | //AbstractQbit's Radial Follow Smoothing OpenTabletDriver Plugin (https://github.com/AbstractQbit/AbstractOTDPlugins) (RadialFollowCore.cs only) 7 | 8 | #pragma once 9 | 10 | #include "Util.h" 11 | 12 | class RadialFollowCore 13 | { 14 | public: 15 | double GetOuterRadius(); 16 | void SetOuterRadius(double value); 17 | 18 | double GetInnerRadius(); 19 | void SetInnerRadius(double value); 20 | 21 | double GetSmoothingCoefficient(); 22 | void SetSmoothingCoefficient(double value); 23 | 24 | double GetSoftKneeScale(); 25 | void SetSoftKneeScale(double value); 26 | 27 | double GetSmoothingLeakCoefficient(); 28 | void SetSmoothingLeakCoefficient(double value); 29 | 30 | void ApplyPresetSettings(int preset_id); 31 | 32 | float SampleRadialCurve(float dist); 33 | 34 | Vector2 Filter(Vector2 target); 35 | 36 | private: 37 | double m_RadiusOuter = 5.0; 38 | double m_RadiusInner = 0.0; 39 | double m_SmoothingCoef = 0.95; 40 | double m_SoftKneeScale = 1.0; 41 | double m_SmoothingLeakCoef = 0.0; 42 | double m_GridScale = 1.0; 43 | 44 | Vector2 m_LastPos; 45 | ULONGLONG m_LastTick = 0; 46 | 47 | double m_XOffset = -1.0; 48 | double m_ScaleComp = 1.0; 49 | 50 | void UpdateDerivedParams(); 51 | 52 | //Math functions 53 | double KneeFunc(double x); 54 | double KneeScaled(double x); 55 | double InverseTanh(double x); 56 | double InverseKneeScaled(double x); 57 | double DeriveKneeScaled(double x); 58 | double GetXOffset(); 59 | double GetScaleComp(); 60 | double GetRadiusOuterAdjusted(); 61 | double GetRadiusInnerAdjusted(); 62 | double LeakedFn(double x, double offset, double scaleComp); 63 | double SmoothedFn(double x, double offset, double scaleComp); 64 | double ScaleToOuter(double x, double offset, double scaleComp); 65 | double DeltaFn(double x, double offset, double scaleComp); 66 | }; -------------------------------------------------------------------------------- /src/DesktopPlus/ThreadManager.h: -------------------------------------------------------------------------------- 1 | #ifndef _THREADMANAGER_H_ 2 | #define _THREADMANAGER_H_ 3 | 4 | #include "CommonTypes.h" 5 | 6 | class THREADMANAGER 7 | { 8 | public: 9 | THREADMANAGER(); 10 | ~THREADMANAGER(); 11 | void Clean(); 12 | DUPL_RETURN Initialize(INT SingleOutput, UINT OutputCount, HANDLE UnexpectedErrorEvent, HANDLE ExpectedErrorEvent, HANDLE NewFrameProcessedEvent, 13 | HANDLE PauseDuplicationEvent, HANDLE ResumeDuplicationEvent, HANDLE TerminateThreadsEvent, 14 | HANDLE SharedHandle, _In_ RECT* DesktopDim, IDXGIAdapter* DXGIAdapter, bool WMRIgnoreVScreens); 15 | PTR_INFO* GetPointerInfo(); //Should only be called when shared surface mutex has be aquired 16 | DPRect& GetDirtyRegionTotal(); //Should only be called when shared surface mutex has be aquired 17 | void WaitForThreadTermination(); 18 | 19 | private: 20 | DUPL_RETURN InitializeDx(_Out_ DX_RESOURCES* Data, IDXGIAdapter* DXGIAdapter); //Doesn't Release() the DXGIAdapter 21 | void CleanDx(_Inout_ DX_RESOURCES* Data); 22 | 23 | PTR_INFO m_PtrInfo; 24 | DPRect m_DirtyRegionTotal; 25 | UINT m_ThreadCount; 26 | _Field_size_(m_ThreadCount) HANDLE* m_ThreadHandles; 27 | _Field_size_(m_ThreadCount) THREAD_DATA* m_ThreadData; 28 | }; 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /src/DesktopPlus/VertexShader.hlsl: -------------------------------------------------------------------------------- 1 | struct VS_INPUT 2 | { 3 | float4 Pos : POSITION; 4 | float2 Tex : TEXCOORD; 5 | }; 6 | 7 | struct VS_OUTPUT 8 | { 9 | float4 Pos : SV_POSITION; 10 | float2 Tex : TEXCOORD; 11 | }; 12 | 13 | 14 | //-------------------------------------------------------------------------------------- 15 | // Vertex Shader 16 | //-------------------------------------------------------------------------------------- 17 | VS_OUTPUT VS(VS_INPUT input) 18 | { 19 | return input; 20 | } -------------------------------------------------------------------------------- /src/DesktopPlus/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by DesktopPlus.rc 4 | // 5 | #define IDI_ICON1 101 6 | #define IDI_DPLUS 101 7 | 8 | // Next default values for new objects 9 | // 10 | #ifdef APSTUDIO_INVOKED 11 | #ifndef APSTUDIO_READONLY_SYMBOLS 12 | #define _APS_NEXT_RESOURCE_VALUE 102 13 | #define _APS_NEXT_COMMAND_VALUE 40001 14 | #define _APS_NEXT_CONTROL_VALUE 1001 15 | #define _APS_NEXT_SYMED_VALUE 101 16 | #endif 17 | #endif 18 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/DesktopPlusUI.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/src/DesktopPlusUI/DesktopPlusUI.rc -------------------------------------------------------------------------------- /src/DesktopPlusUI/DesktopPlusUI.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | false 5 | 6 | 7 | $(OutputPath) 8 | WindowsLocalDebugger 9 | -DesktopMode 10 | 11 | 12 | $(OutputPath) 13 | WindowsLocalDebugger 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/FloatingUI.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "WindowFloatingUIBar.h" 4 | 5 | #include "openvr.h" 6 | #include "Matrices.h" 7 | 8 | class FloatingUI 9 | { 10 | private: 11 | WindowFloatingUIMainBar m_WindowMainBar; 12 | WindowFloatingUIActionBar m_WindowActionBar; 13 | WindowFloatingUIOverlayStats m_WindowOverlayStats; 14 | 15 | vr::VROverlayHandle_t m_OvrlHandleCurrentUITarget; 16 | unsigned int m_OvrlIDCurrentUITarget; 17 | 18 | float m_Width; 19 | float m_Alpha; 20 | bool m_Visible; 21 | bool m_IsSwitchingTarget; 22 | float m_FadeOutDelayCount; 23 | int m_AutoFitFrames; 24 | Matrix4 m_TransformLast; 25 | 26 | float m_TheaterOffsetAnimationProgress; 27 | 28 | public: 29 | FloatingUI(); 30 | void Update(); 31 | void UpdateUITargetState(); 32 | bool IsVisible() const; 33 | float GetAlpha() const; 34 | 35 | WindowFloatingUIMainBar& GetMainBarWindow(); 36 | WindowFloatingUIActionBar& GetActionBarWindow(); 37 | }; -------------------------------------------------------------------------------- /src/DesktopPlusUI/NotificationIcon.h: -------------------------------------------------------------------------------- 1 | //Provides a notification area/tray icon 2 | //Technically a singleton, but is designed to have its one instance live in UIManager for proper lifetime management 3 | //Once intialized, it's fully self-contained 4 | 5 | #pragma once 6 | 7 | #define NOMINMAX 8 | #include 9 | 10 | class NotificationIcon 11 | { 12 | private: 13 | HINSTANCE m_Instance; 14 | NOTIFYICONDATA m_IconData; 15 | HMENU m_PopupMenu; 16 | 17 | static LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); 18 | 19 | public: 20 | NotificationIcon(); 21 | ~NotificationIcon(); 22 | bool Init(HINSTANCE hinstance); 23 | void RefreshPopupMenu(); //Destroys the popup menu if it exists and recreates it. Called after Init() to update translation strings 24 | void OnCallbackMessage(WPARAM wparam, LPARAM lparam); 25 | }; -------------------------------------------------------------------------------- /src/DesktopPlusUI/VRKeyboard.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "VRKeyboardCommon.h" 4 | #include "WindowKeyboard.h" 5 | #include "WindowKeyboardEditor.h" 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | class VRKeyboard 12 | { 13 | private: 14 | WindowKeyboard m_WindowKeyboard; 15 | WindowKeyboardShortcuts m_WindowKeyboardShortcuts; 16 | KeyboardEditor m_KeyboardEditor; 17 | 18 | KeyboardLayoutMetadata m_LayoutMetadata; 19 | std::vector m_KeyboardKeys[kbdlayout_sub_MAX]; 20 | std::string m_KeyLabels; //String containing all labels, so their characters are always loaded from the font 21 | 22 | KeyboardInputTarget m_InputTarget; 23 | unsigned int m_InputTargetOverlayID; 24 | bool m_KeyDown[256]; 25 | bool m_CapsLockToggled; 26 | std::queue m_StringQueue; 27 | 28 | ImGuiID m_ActiveInputText; 29 | ImGuiID m_InputBeginWidgetID; 30 | ImGuiDir m_ShortcutWindowDirHint; 31 | float m_ShortcutWindowYOffset; 32 | bool m_ActiveInputTextIsMultiline; 33 | bool m_MouseLeftDownPrevCached; 34 | bool m_MouseLeftClickedPrevCached; 35 | bool m_KeyboardHiddenLastFrame; 36 | 37 | unsigned char GetModifierFlags() const; 38 | vr::VROverlayHandle_t GetTargetOverlayHandle() const; 39 | 40 | public: 41 | VRKeyboard(); 42 | WindowKeyboard& GetWindow(); 43 | KeyboardEditor& GetEditor(); 44 | 45 | void LoadLayoutFromFile(const std::string& filename); 46 | bool SaveCurrentLayoutToFile(const std::string& filename); 47 | void LoadCurrentLayout(); 48 | static std::vector GetKeyboardLayoutList(); 49 | 50 | const KeyboardLayoutMetadata& GetLayoutMetadata() const; 51 | void SetLayoutMetadata(const KeyboardLayoutMetadata& metadata); 52 | std::vector& GetLayout(KeyboardLayoutSubLayout sublayout); 53 | void SetLayout(KeyboardLayoutSubLayout sublayout, std::vector& keys); 54 | const std::string& GetKeyLabelsString() const; 55 | 56 | KeyboardInputTarget GetInputTarget() const; 57 | unsigned int GetInputTargetOverlayID() const; 58 | 59 | bool GetKeyDown(unsigned char keycode) const; 60 | void SetKeyDown(unsigned char keycode, bool down, bool block_modifiers = false); 61 | void SetStringDown(const std::string text, bool down); 62 | void SetActionDown(ActionUID action_uid, bool down); 63 | bool IsCapsLockToggled() const; 64 | void ResetState(); 65 | 66 | void VRKeyboardInputBegin(const char* str_id, bool is_multiline = false); 67 | void VRKeyboardInputBegin(ImGuiID widget_id, bool is_multiline = false); 68 | void VRKeyboardInputEnd(); 69 | 70 | void OnImGuiNewFrame(); 71 | void OnWindowHidden(); 72 | 73 | void AddTextToStringQueue(const std::string text); 74 | 75 | void UpdateImGuiModifierState() const; 76 | void RestoreDesktopModifierState() const; 77 | 78 | //Positioning hint used by the shortcut window. Set when the default down direction would cover related widgets. Offset only used with hint dir. Resets automatically 79 | void SetShortcutWindowDirectionHint(ImGuiDir dir_hint, float y_offset = 0.0f); 80 | 81 | static KeyboardLayoutMetadata LoadLayoutMetadataFromFile(const std::string& filename); 82 | }; -------------------------------------------------------------------------------- /src/DesktopPlusUI/VRKeyboardCommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Actions.h" 4 | #include 5 | 6 | enum KeyboardLayoutSubLayout : unsigned char 7 | { 8 | kbdlayout_sub_base, 9 | kbdlayout_sub_shift, 10 | kbdlayout_sub_altgr, 11 | kbdlayout_sub_aux, 12 | kbdlayout_sub_MAX 13 | }; 14 | 15 | enum KeyboardLayoutKeyType 16 | { 17 | kbdlayout_key_blank_space, 18 | kbdlayout_key_virtual_key, 19 | kbdlayout_key_virtual_key_toggle, 20 | kbdlayout_key_virtual_key_iso_enter, 21 | kbdlayout_key_string, 22 | kbdlayout_key_sublayout_toggle, 23 | kbdlayout_key_action, 24 | kbdlayout_key_MAX 25 | }; 26 | 27 | enum KeyboardLayoutCluster 28 | { 29 | kbdlayout_cluster_base, 30 | kbdlayout_cluster_function, 31 | kbdlayout_cluster_navigation, 32 | kbdlayout_cluster_numpad, 33 | kbdlayout_cluster_extra, 34 | kbdlayout_cluster_MAX 35 | }; 36 | 37 | struct KeyboardLayoutMetadata 38 | { 39 | std::string Name = "Unknown"; 40 | std::string Author = ""; 41 | std::string FileName; 42 | bool HasAltGr = false; //Right Alt switches to AltGr sublayout when down 43 | bool HasCluster[kbdlayout_cluster_MAX] = {false}; 44 | }; 45 | 46 | struct KeyboardLayoutKey 47 | { 48 | KeyboardLayoutCluster KeyCluster = kbdlayout_cluster_base; 49 | KeyboardLayoutKeyType KeyType = kbdlayout_key_blank_space; 50 | bool IsRowEnd = false; 51 | float Width = 1.0f; 52 | float Height = 1.0f; 53 | std::string Label; 54 | bool BlockModifiers = false; 55 | bool NoRepeat = false; 56 | unsigned char KeyCode = 0; 57 | std::string KeyString; 58 | KeyboardLayoutSubLayout KeySubLayoutToggle = kbdlayout_sub_base; 59 | ActionUID KeyActionUID = k_ActionUID_Invalid; 60 | }; 61 | 62 | enum KeyboardInputTarget 63 | { 64 | kbdtarget_desktop, 65 | kbdtarget_ui, 66 | kbdtarget_overlay 67 | }; 68 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/Win32PerformanceData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #define NOMINMAX 6 | #include 7 | 8 | class Win32PerformanceData 9 | { 10 | private: 11 | PDH_HQUERY m_QueryCPU; 12 | PDH_HQUERY m_QueryGPU; 13 | PDH_HQUERY m_QueryVRAM; 14 | PDH_HCOUNTER m_CounterCPU; 15 | PDH_HCOUNTER m_CounterGPU; 16 | PDH_HCOUNTER m_CounterVRAM; 17 | 18 | LUID m_GPUTargetLUID; 19 | 20 | float m_CPULoad; 21 | float m_GPULoad; 22 | float m_RAMTotalGB; 23 | float m_RAMUsedGB; 24 | float m_VRAMTotalGB; 25 | float m_VRAMUsedGB; 26 | 27 | ULONGLONG m_LastUpdateTick; 28 | 29 | static LUID GetLUIDFromFormattedCounterNameString(const std::wstring& str); 30 | 31 | public: 32 | Win32PerformanceData(); 33 | ~Win32PerformanceData(); 34 | 35 | void EnableCounters(bool enable_gpu); 36 | void DisableGPUCounters(); 37 | void DisableCounters(); 38 | 39 | bool Update(); 40 | void SetTargetGPU(LUID gpu_luid, DWORDLONG vram_total_bytes); 41 | 42 | float GetCPULoadPrecentage() const; 43 | float GetGPULoadPrecentage() const; 44 | float GetRAMTotalGB() const; 45 | float GetRAMUsedGB() const; 46 | float GetVRAMTotalGB() const; 47 | float GetVRAMUsedGB() const; 48 | }; 49 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/WindowDesktopMode.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include "imgui.h" 5 | 6 | #include "OverlayManager.h" 7 | 8 | enum WindowDesktopModePage 9 | { 10 | wnddesktopmode_page_none, 11 | wnddesktopmode_page_main, 12 | wnddesktopmode_page_settings, 13 | wnddesktopmode_page_profiles, 14 | wnddesktopmode_page_app_profiles, 15 | wnddesktopmode_page_actions, 16 | wnddesktopmode_page_properties, 17 | wnddesktopmode_page_add_window_overlay 18 | }; 19 | 20 | //Interop functions for windows that have their content hosted as a sub-page in desktop mode 21 | class FloatingWindowDesktopModeInterop 22 | { 23 | public: 24 | virtual const char* DesktopModeGetTitle() const = 0; 25 | virtual bool DesktopModeGetIconTextureInfo(ImVec2& size, ImVec2& uv_min, ImVec2& uv_max) const = 0; //Returns false on no icon 26 | virtual float DesktopModeGetTitleIconAlpha() const { return 1.0f; } 27 | virtual void DesktopModeOnTitleIconClick() {}; 28 | virtual void DesktopModeOnTitleBarHover(bool is_hovered) {}; 29 | virtual bool DesktopModeGoBack() = 0; //Returns false if already on main page 30 | }; 31 | 32 | class WindowDesktopMode 33 | { 34 | private: 35 | std::vector m_PageStack; 36 | int m_PageStackPos = 0; 37 | int m_PageStackPosAnimation = 0; 38 | WindowDesktopModePage m_PageAppearing = wnddesktopmode_page_none; //Similar to ImGui::IsWindowAppearing(), equals the current page ID for a single frame if it or the window is newly appearing 39 | WindowDesktopModePage m_PageReturned = wnddesktopmode_page_none; //Equals the previous page ID after PageGoBack() was called, ideally cleared after making use of its value 40 | 41 | ImVec4 m_TitleBarRect; 42 | 43 | int m_PageAnimationDir = 0; 44 | float m_PageAnimationProgress = 0.0f; 45 | float m_PageAnimationStartPos = 0.0f; 46 | float m_PageAnimationOffset = 0.0f; 47 | 48 | unsigned int m_OverlayListActiveMenuID = k_ulOverlayID_None; 49 | float m_MenuAlpha = 0.0f; 50 | bool m_IsOverlayAddMenuVisible = false; 51 | bool m_IsMenuRemoveConfirmationVisible = false; 52 | bool m_IsDraggingOverlaySelectables = false; 53 | 54 | void UpdateTitleBar(); 55 | void UpdatePageMain(); 56 | void UpdatePageMainOverlayList(); 57 | void UpdatePageAddWindowOverlay(); 58 | 59 | void MenuOverlayList(unsigned int overlay_id); 60 | void MenuAddOverlay(); 61 | void HideMenus(); 62 | 63 | void PageGoForward(WindowDesktopModePage new_page); 64 | void PageGoBack(); 65 | 66 | public: 67 | WindowDesktopMode(); 68 | void Update(); 69 | 70 | ImVec4 GetTitleBarRect() const; 71 | }; -------------------------------------------------------------------------------- /src/DesktopPlusUI/WindowFloatingUIBar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "imgui.h" 4 | 5 | struct Action; 6 | 7 | //The main bar visible in the floating UI, containing buttons to hide the overlay, toggle drag-mode and show the Action-Bar 8 | class WindowFloatingUIMainBar 9 | { 10 | private: 11 | ImVec2 m_Pos; 12 | ImVec2 m_Size; 13 | 14 | int m_IsCurrentWindowCapturable; //-1 = needs update, otherwise bool 15 | float m_AnimationProgress; 16 | 17 | void DisplayTooltipIfHovered(const char* text); 18 | 19 | public: 20 | WindowFloatingUIMainBar(); 21 | 22 | void Update(float mainbar_height, unsigned int overlay_id); 23 | void UpdatePerformanceMonitorButtons(); 24 | void UpdateBrowserButtons(unsigned int overlay_id); 25 | 26 | const ImVec2& GetPos() const; 27 | const ImVec2& GetSize() const; 28 | float GetAnimationProgress() const; 29 | 30 | void MarkCurrentWindowCapturableStateOutdated(); 31 | }; 32 | 33 | //Action-Bar visible in the floating UI, containing desktop buttons and user-defined action buttons 34 | class WindowFloatingUIActionBar 35 | { 36 | private: 37 | ImVec2 m_Pos; 38 | ImVec2 m_Size; 39 | bool m_Visible; 40 | float m_Alpha; 41 | 42 | double m_LastDesktopSwitchTime; 43 | bool m_TooltipPositionForOverlayBar; //This is used instead of an extra argument to no have every custom button code need to be aware of this corner case 44 | 45 | void DisplayTooltipIfHovered(const char* text); 46 | void UpdateDesktopButtons(unsigned int overlay_id); 47 | 48 | void ButtonActionKeyboard(const Action& action, const ImVec2& size, unsigned int overlay_id); 49 | 50 | public: 51 | WindowFloatingUIActionBar(); 52 | 53 | void Show(bool skip_fade = false); 54 | void Hide(bool skip_fade = false); 55 | void Update(unsigned int overlay_id); 56 | const ImVec2& GetPos() const; 57 | const ImVec2& GetSize() const; 58 | bool IsVisible() const; 59 | float GetAlpha() const; 60 | 61 | double GetLastDesktopSwitchTime() const; 62 | 63 | void UpdateActionButtons(unsigned int overlay_id); //WindowOverlayBar can piggyback this function with k_ulOverlayID_None to get action buttons in its window 64 | 65 | static bool ButtonAction(const Action& action, const ImVec2& size, bool use_temp_icon = false); //use_temp_icon still needs icon filename set in action 66 | }; 67 | 68 | //Extra window currently only showing capture fps of the overlay if enabled 69 | class WindowFloatingUIOverlayStats 70 | { 71 | private: 72 | ImVec2 CalcPos(const WindowFloatingUIMainBar& mainbar, const WindowFloatingUIActionBar& actionbar, float& window_width) const; 73 | 74 | public: 75 | void Update(const WindowFloatingUIMainBar& mainbar, const WindowFloatingUIActionBar& actionbar, unsigned int overlay_id); 76 | }; -------------------------------------------------------------------------------- /src/DesktopPlusUI/WindowKeyboardEditor.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "VRKeyboardCommon.h" 4 | #include 5 | 6 | class KeyboardEditor 7 | { 8 | //Not exactly space efficient, but simple and works 9 | struct HistoryItem 10 | { 11 | KeyboardLayoutMetadata Metadata; 12 | std::vector KeyboardKeys[kbdlayout_sub_MAX]; 13 | }; 14 | 15 | private: 16 | float m_TopWindowHeight = 0.0f; 17 | float m_WindowRounding = 0.0f; 18 | 19 | KeyboardLayoutSubLayout m_SelectedSublayout = kbdlayout_sub_base; 20 | int m_SelectedRowID = -1; 21 | int m_SelectedKeyID = -1; 22 | bool m_HasChangedSelectedKey = false; 23 | bool m_RefreshLayout = true; 24 | 25 | std::vector m_HistoryUndo; 26 | std::vector m_HistoryRedo; 27 | bool m_HistoryHasPendingEdit = false; //Set by widgets that make continuous changes but should only push history once until deactivated 28 | 29 | bool m_PreviewCluster[kbdlayout_cluster_MAX] = {true, true, true, true, true}; 30 | 31 | void UpdateWindowKeyList(); 32 | void UpdateWindowKeyProperties(); 33 | void UpdateWindowMetadata(); 34 | void UpdateWindowPreview(); 35 | 36 | std::pair GetKeyRowRange(KeyboardLayoutSubLayout sublayout, int row_id); //Returns beginning & end key IDs 37 | int FindKeyWithClosestPosInNewSubLayout(int key_index, KeyboardLayoutSubLayout sublayout_id_current, KeyboardLayoutSubLayout sublayout_id_new); 38 | 39 | void HistoryPush(); 40 | void HistoryPushInternal(std::vector& target_history); 41 | void HistoryUndo(); 42 | void HistoryRedo(); 43 | void HistoryClear(); 44 | 45 | void CloseCurrentModalPopupFromInput(); //Imitates non-modal popup closing behavior 46 | 47 | public: 48 | void Update(); 49 | }; 50 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/WindowOverlayBar.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "imgui.h" 4 | #include "OverlayManager.h" 5 | 6 | class WindowSettings; 7 | 8 | //The bar visible below the dashboard, containing overlay buttons and access to the settings window 9 | class WindowOverlayBar 10 | { 11 | private: 12 | ImVec2 m_Pos; 13 | ImVec2 m_Size; 14 | bool m_Visible; //This and m_Alpha default to visible state, meaning the dashboard UI, where it's always visible doesn't need to call Show() 15 | float m_Alpha; 16 | bool m_IsScrollBarVisible; 17 | 18 | unsigned int m_OverlayButtonActiveMenuID; 19 | bool m_IsAddOverlayButtonActive; 20 | float m_MenuAlpha; 21 | bool m_IsMenuRemoveConfirmationVisible; 22 | bool m_IsDraggingOverlayButtons; 23 | 24 | void DisplayTooltipIfHovered(const char* text, unsigned int overlay_id = k_ulOverlayID_None); 25 | void UpdateOverlayButtons(); 26 | void MenuOverlayButton(unsigned int overlay_id, ImVec2 pos, bool is_item_active); 27 | void MenuAddOverlayButton(ImVec2 pos, bool is_item_active); 28 | 29 | public: 30 | WindowOverlayBar(); 31 | 32 | void Show(bool skip_fade = false); 33 | void Hide(bool skip_fade = false); 34 | void HideMenus(); 35 | void Update(); 36 | 37 | const ImVec2& GetPos() const; 38 | const ImVec2& GetSize() const; 39 | 40 | bool IsVisible() const; 41 | bool IsVisibleOrFading() const; 42 | bool IsAnyMenuVisible() const; 43 | bool IsScrollBarVisible() const; 44 | bool IsDraggingOverlayButtons() const; 45 | 46 | float GetAlpha() const; 47 | }; -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/add.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 17 | 21 | 25 | 26 | 27 | 29 | 30 | 31 | image/svg+xml 32 | 34 | 36 | 37 | 38 | 40 | 42 | 44 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/browser.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 21 | 26 | 31 | 36 | 41 | 46 | 51 | 53 | 54 | 55 | image/svg+xml 56 | 58 | 60 | 61 | 62 | 64 | 66 | 68 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/browser32.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 21 | 26 | 31 | 36 | 41 | 46 | 51 | 53 | 54 | 55 | image/svg+xml 56 | 58 | 60 | 61 | 62 | 64 | 66 | 68 | 70 | 71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/dashboard.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 18 | 19 | image/svg+xml 20 | 22 | 24 | 25 | 27 | 29 | 31 | 33 | 34 | 35 | 36 | 40 | 44 | 48 | 52 | 53 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/desktop.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 19 | 23 | 24 | 26 | 27 | 28 | image/svg+xml 29 | 31 | 33 | 34 | 35 | 37 | 39 | 41 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/desktop_1.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 19 | 23 | 24 | 26 | 27 | 28 | image/svg+xml 29 | 31 | 33 | 34 | 35 | 37 | 39 | 41 | 43 | 44 | 45 | 46 | 51 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/desktop_2.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 19 | 23 | 24 | 26 | 27 | 28 | image/svg+xml 29 | 31 | 33 | 34 | 35 | 37 | 39 | 41 | 43 | 44 | 45 | 46 | 50 | 51 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/desktop_4.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 19 | 23 | 24 | 26 | 27 | 28 | image/svg+xml 29 | 31 | 33 | 34 | 35 | 37 | 39 | 41 | 43 | 44 | 45 | 46 | 50 | 51 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/desktop_5.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 19 | 23 | 24 | 26 | 27 | 28 | image/svg+xml 29 | 31 | 33 | 34 | 35 | 37 | 39 | 41 | 43 | 44 | 45 | 46 | 50 | 51 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/desktop_next.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 21 | 26 | 27 | 28 | 32 | 36 | 37 | 39 | 40 | 41 | image/svg+xml 42 | 44 | 46 | 47 | 48 | 50 | 52 | 54 | 56 | 57 | 58 | 59 | 63 | 64 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/hmd.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 18 | 19 | image/svg+xml 20 | 22 | 24 | 25 | 27 | 29 | 31 | 33 | 34 | 35 | 36 | 40 | 41 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/pin.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 16 | 17 | image/svg+xml 18 | 20 | 22 | 23 | 24 | 26 | 28 | 30 | 32 | 33 | 34 | 35 | 39 | 40 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/playspace.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 18 | 19 | image/svg+xml 20 | 22 | 24 | 25 | 26 | 28 | 30 | 32 | 34 | 35 | 36 | 37 | 41 | 45 | 51 | 52 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/seated_space.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 21 | 25 | 29 | 33 | 37 | 39 | 40 | 41 | image/svg+xml 42 | 44 | 46 | 47 | 48 | 50 | 52 | 54 | 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/settings.svg: -------------------------------------------------------------------------------- 1 | 2 | 11 | 13 | 15 | 19 | 20 | 22 | 23 | 24 | image/svg+xml 25 | 27 | 29 | 30 | 31 | 33 | 35 | 37 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/small_browser_back.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 19 | 21 | 22 | 23 | image/svg+xml 24 | 26 | 28 | 29 | 30 | 32 | 34 | 36 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/small_browser_refresh.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 19 | 23 | 25 | 26 | 27 | image/svg+xml 28 | 30 | 32 | 33 | 34 | 36 | 38 | 40 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/small_browser_stop.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 19 | 21 | 22 | 23 | image/svg+xml 24 | 26 | 28 | 29 | 30 | 32 | 34 | 36 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/small_close.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 18 | 22 | 26 | 27 | 28 | 30 | 31 | 32 | image/svg+xml 33 | 35 | 37 | 38 | 39 | 41 | 43 | 45 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/small_move.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 18 | 22 | 23 | 25 | 26 | 27 | image/svg+xml 28 | 30 | 32 | 33 | 34 | 36 | 38 | 40 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/small_move_locked.svg: -------------------------------------------------------------------------------- 1 | 2 | 13 | 15 | 18 | 22 | 23 | 25 | 26 | 27 | image/svg+xml 28 | 30 | 32 | 33 | 35 | 37 | 39 | 41 | 42 | 43 | 44 | 48 | 49 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/task_switch.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 20 | 24 | 28 | 29 | 31 | 32 | 33 | image/svg+xml 34 | 36 | 38 | 39 | 40 | 42 | 44 | 46 | 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/theater_screen.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 18 | 19 | image/svg+xml 20 | 22 | 24 | 25 | 27 | 29 | 31 | 33 | 34 | 35 | 36 | 40 | 44 | 48 | 49 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/icon_src/tracker.svg: -------------------------------------------------------------------------------- 1 | 2 | 15 | 17 | 18 | 19 | image/svg+xml 20 | 22 | 24 | 25 | 26 | 28 | 30 | 32 | 34 | 35 | 36 | 37 | 42 | 43 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/imgui_win32_dx11_openvr/PixelShaderImGui.hlsl: -------------------------------------------------------------------------------- 1 | struct PS_INPUT 2 | { 3 | float4 pos : SV_POSITION; 4 | float4 col : COLOR0; 5 | float2 uv : TEXCOORD0; 6 | }; 7 | 8 | sampler sampler0; 9 | Texture2D texture0; 10 | 11 | float4 PS(PS_INPUT input) : SV_Target 12 | { 13 | return input.col * texture0.Sample(sampler0, input.uv); 14 | } -------------------------------------------------------------------------------- /src/DesktopPlusUI/imgui_win32_dx11_openvr/VertexShaderImGui.hlsl: -------------------------------------------------------------------------------- 1 | cbuffer vertexBuffer : register(b0) 2 | { 3 | float4x4 ProjectionMatrix; 4 | }; 5 | 6 | struct VS_INPUT 7 | { 8 | float2 pos : POSITION; 9 | float4 col : COLOR0; 10 | float2 uv : TEXCOORD0; 11 | }; 12 | 13 | struct PS_INPUT 14 | { 15 | float4 pos : SV_POSITION; 16 | float4 col : COLOR0; 17 | float2 uv : TEXCOORD0; 18 | }; 19 | 20 | PS_INPUT VS(VS_INPUT input) 21 | { 22 | PS_INPUT output; 23 | output.pos = mul(ProjectionMatrix, float4(input.pos.xy, 0.f, 1.f)); 24 | output.col = input.col; 25 | output.uv = input.uv; 26 | return output; 27 | } -------------------------------------------------------------------------------- /src/DesktopPlusUI/imgui_win32_dx11_openvr/imgui_impl_dx11_openvr.h: -------------------------------------------------------------------------------- 1 | // Desktop+UI: Modified for OpenVR compatibility 2 | 3 | // dear imgui: Renderer Backend for DirectX11 4 | // This needs to be used along with a Platform Backend (e.g. Win32) 5 | 6 | // Implemented features: 7 | // [X] Renderer: User texture binding. Use 'ID3D11ShaderResourceView*' as ImTextureID. Read the FAQ about ImTextureID! 8 | // [X] Renderer: Large meshes support (64k+ vertices) even with 16-bit indices (ImGuiBackendFlags_RendererHasVtxOffset). 9 | // [X] Renderer: Expose selected render state for draw callbacks to use. Access in '(ImGui_ImplXXXX_RenderState*)GetPlatformIO().Renderer_RenderState'. 10 | 11 | // You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. 12 | // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. 13 | // Learn about Dear ImGui: 14 | // - FAQ https://dearimgui.com/faq 15 | // - Getting Started https://dearimgui.com/getting-started 16 | // - Documentation https://dearimgui.com/docs (same as your local docs/ folder). 17 | // - Introduction, links and more at the top of imgui.cpp 18 | 19 | #pragma once 20 | #include "imgui.h" // IMGUI_IMPL_API 21 | #ifndef IMGUI_DISABLE 22 | 23 | struct ID3D11Device; 24 | struct ID3D11DeviceContext; 25 | struct ID3D11SamplerState; 26 | struct ID3D11Buffer; 27 | 28 | // Follow "Getting Started" link and check examples/ folder to learn about using backends! 29 | IMGUI_IMPL_API bool ImGui_ImplDX11_Init(ID3D11Device* device, ID3D11DeviceContext* device_context); 30 | IMGUI_IMPL_API void ImGui_ImplDX11_Shutdown(); 31 | IMGUI_IMPL_API void ImGui_ImplDX11_NewFrame(); 32 | IMGUI_IMPL_API void ImGui_ImplDX11_RenderDrawData(ImDrawData* draw_data); 33 | 34 | // Use if you want to reset your rendering device without losing Dear ImGui state. 35 | IMGUI_IMPL_API void ImGui_ImplDX11_InvalidateDeviceObjects(); 36 | IMGUI_IMPL_API bool ImGui_ImplDX11_CreateDeviceObjects(); 37 | 38 | // [BETA] Selected render state data shared with callbacks. 39 | // This is temporarily stored in GetPlatformIO().Renderer_RenderState during the ImGui_ImplDX11_RenderDrawData() call. 40 | // (Please open an issue if you feel you need access to more data) 41 | struct ImGui_ImplDX11_RenderState 42 | { 43 | ID3D11Device* Device; 44 | ID3D11DeviceContext* DeviceContext; 45 | ID3D11SamplerState* SamplerDefault; 46 | ID3D11Buffer* VertexConstantBuffer; 47 | }; 48 | 49 | #endif // #ifndef IMGUI_DISABLE 50 | -------------------------------------------------------------------------------- /src/DesktopPlusUI/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by DesktopPlusUI.rc 4 | // 5 | #define IDI_ICON1 102 6 | #define IDI_DPLUS 102 7 | 8 | // Next default values for new objects 9 | // 10 | #ifdef APSTUDIO_INVOKED 11 | #ifndef APSTUDIO_READONLY_SYMBOLS 12 | #define _APS_NEXT_RESOURCE_VALUE 103 13 | #define _APS_NEXT_COMMAND_VALUE 40001 14 | #define _APS_NEXT_CONTROL_VALUE 1001 15 | #define _APS_NEXT_SYMED_VALUE 101 16 | #endif 17 | #endif 18 | -------------------------------------------------------------------------------- /src/DesktopPlusWinRT/CaptureManager.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "OverlayCapture.h" 3 | 4 | class CaptureManager 5 | { 6 | public: 7 | CaptureManager(DPWinRTThreadData& thread_data, DWORD global_main_thread_id); 8 | ~CaptureManager() {} 9 | 10 | winrt::Windows::Graphics::Capture::GraphicsCaptureItem StartCaptureFromWindowHandle(HWND hwnd); 11 | winrt::Windows::Graphics::Capture::GraphicsCaptureItem StartCaptureFromMonitorHandle(HMONITOR hmon); 12 | winrt::Windows::Graphics::DirectX::DirectXPixelFormat PixelFormat() { return m_PixelFormat; } 13 | void PixelFormat(winrt::Windows::Graphics::DirectX::DirectXPixelFormat pixel_format); 14 | 15 | bool IsCursorEnabled(); 16 | void IsCursorEnabled(bool value); 17 | bool IsCapturePaused(); 18 | 19 | void OnOverlayDataRefresh(); 20 | 21 | void PauseCapture(bool pause); 22 | void StopCapture(); 23 | 24 | private: 25 | void StartCaptureFromItem(winrt::Windows::Graphics::Capture::GraphicsCaptureItem item); 26 | void OnCaptureItemClosed(winrt::Windows::Graphics::Capture::GraphicsCaptureItem const&, winrt::Windows::Foundation::IInspectable const&); 27 | 28 | private: 29 | winrt::Windows::System::DispatcherQueue m_CaptureMainThread{ nullptr }; 30 | 31 | winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice m_Device { nullptr }; 32 | std::unique_ptr m_Capture { nullptr }; 33 | winrt::Windows::Graphics::Capture::GraphicsCaptureItem::Closed_revoker m_ItemClosedRevoker; 34 | winrt::Windows::Graphics::DirectX::DirectXPixelFormat m_PixelFormat = winrt::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized; 35 | 36 | DPWinRTThreadData& m_ThreadData; 37 | DWORD m_GlobalMainThreadID; 38 | }; -------------------------------------------------------------------------------- /src/DesktopPlusWinRT/CommonHeaders.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | // WinRT 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | // STL 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | // D3D 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | // DWM 32 | #include 33 | 34 | // WIL 35 | #include 36 | 37 | // Helpers 38 | #include "util/direct3d11.interop.h" 39 | #include "util/capture.desktop.interop.h" 40 | #include "util/dispatcherqueue.desktop.interop.h" 41 | #include "util/hwnd.interop.h" -------------------------------------------------------------------------------- /src/DesktopPlusWinRT/DesktopPlusWinRT.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/src/DesktopPlusWinRT/DesktopPlusWinRT.rc -------------------------------------------------------------------------------- /src/DesktopPlusWinRT/DesktopPlusWinRT.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | Shared 8 | 9 | 10 | Shared 11 | 12 | 13 | 14 | Shared 15 | 16 | 17 | 18 | 19 | Util 20 | 21 | 22 | Util 23 | 24 | 25 | Util 26 | 27 | 28 | Util 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | Shared 37 | 38 | 39 | Shared 40 | 41 | 42 | Util 43 | 44 | 45 | Shared 46 | 47 | 48 | Shared 49 | 50 | 51 | 52 | Shared 53 | 54 | 55 | 56 | 57 | {bd52fd2f-19e3-47c1-afb1-969ba28603f5} 58 | 59 | 60 | {58894ab8-4129-462f-9ab7-503477dec788} 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/DesktopPlusWinRT/DesktopPlusWinRT.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | $(TargetDir)\DesktopPlus.exe 5 | WindowsLocalDebugger 6 | $(TargetDir) 7 | 8 | 9 | $(TargetDir)\DesktopPlus.exe 10 | WindowsLocalDebugger 11 | $(TargetDir) 12 | 13 | -------------------------------------------------------------------------------- /src/DesktopPlusWinRT/OverlayCapture.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "ThreadData.h" 6 | #include "OUtoSBSConverter.h" 7 | 8 | class OverlayCapture 9 | { 10 | public: 11 | OverlayCapture(winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice const& device, winrt::Windows::Graphics::Capture::GraphicsCaptureItem const& item, 12 | winrt::Windows::Graphics::DirectX::DirectXPixelFormat pixel_format, DWORD global_main_thread_id, const std::vector& overlays, HWND source_window); 13 | ~OverlayCapture() { Close(); } 14 | 15 | void StartCapture(); 16 | void RestartCapture(); 17 | 18 | bool IsCursorEnabled() { return m_CursorEnabled; } 19 | void IsCursorEnabled(bool value); 20 | winrt::Windows::Graphics::Capture::GraphicsCaptureItem CaptureItem() { return m_Item; } 21 | 22 | void PauseCapture(bool pause) { m_Paused = pause; OnOverlayDataRefresh(); } 23 | bool IsPaused() { return m_Paused; } 24 | 25 | void OnOverlayDataRefresh(); 26 | 27 | void Close(); 28 | 29 | private: 30 | void OnFrameArrived(winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool const& sender, winrt::Windows::Foundation::IInspectable const& args); 31 | 32 | inline void CheckClosed() 33 | { 34 | if (m_Closed.load() == true) 35 | { 36 | throw winrt::hresult_error(RO_E_CLOSED); 37 | } 38 | } 39 | 40 | private: 41 | winrt::Windows::Graphics::Capture::GraphicsCaptureItem m_Item { nullptr }; 42 | winrt::Windows::Graphics::Capture::Direct3D11CaptureFramePool m_FramePool { nullptr }; 43 | winrt::Windows::Graphics::Capture::GraphicsCaptureSession m_Session { nullptr }; 44 | winrt::Windows::Graphics::SizeInt32 m_LastContentSize { 0, 0 }; 45 | 46 | winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice m_Device { nullptr }; 47 | winrt::com_ptr m_D3DContext { nullptr }; 48 | winrt::Windows::Graphics::DirectX::DirectXPixelFormat m_PixelFormat; 49 | 50 | std::atomic m_Closed = false; 51 | 52 | //Below are only accessed while on the capture's main thread 53 | const std::vector& m_Overlays; 54 | const HWND m_SourceWindow; 55 | DWORD m_GlobalMainThreadID = 0; 56 | 57 | bool m_Paused = false; 58 | bool m_CursorEnabled = true; //Public cursor enabled state. False is always off, but true may be overridden by m_CursorEnabledInternal 59 | bool m_CursorEnabledInternal = true; //Internal cursor enabled state, which may override m_CursorEnabled during window capture 60 | int m_OverlaySharedTextureSetupsNeeded = 2; 61 | 62 | bool m_InitialSizingDone = false; 63 | winrt::Windows::Graphics::SizeInt32 m_LastTextureSize { 0, 0 }; 64 | bool m_RestartPending = false; 65 | 66 | bool m_UseMinIntervalLimiter = false; //True if MinUpdateInterval is being used instead of our own limiter 67 | LARGE_INTEGER m_UpdateLimiterStartingTime = {INT_MAX, INT_MAX}; //Init to high value so the first frame is never falls below the minimum interval 68 | LARGE_INTEGER m_UpdateLimiterFrequency = {0, 0}; 69 | LARGE_INTEGER m_UpdateLimiterDelay = {0, 0}; 70 | 71 | int m_FrameCount = 0; 72 | int m_FrameCountLast = -1; 73 | ULONGLONG m_FrameCountStartTick = 0; 74 | 75 | std::vector m_OUConverters; //Rarely used, so the cache is kept here instead of directly as part of the overlay data 76 | }; -------------------------------------------------------------------------------- /src/DesktopPlusWinRT/ThreadData.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define WIN32_LEAN_AND_MEAN 4 | #define NOMINMAX 5 | #include 6 | 7 | #include 8 | #include "openvr.h" 9 | 10 | struct DPWinRTOverlayData 11 | { 12 | vr::VROverlayHandle_t Handle = vr::k_ulOverlayHandleInvalid; 13 | bool IsPaused = false; 14 | LARGE_INTEGER UpdateLimiterDelay = {0}; 15 | bool IsOverUnder3D = false; 16 | int OU3D_crop_x = 0; 17 | int OU3D_crop_y = 0; 18 | int OU3D_crop_width = 1; 19 | int OU3D_crop_height = 1; 20 | }; 21 | 22 | struct DPWinRTThreadData 23 | { 24 | HANDLE ThreadHandle = nullptr; 25 | DWORD ThreadID = 0; 26 | std::vector Overlays; 27 | HWND SourceWindow = nullptr; 28 | int DesktopID = -2; 29 | bool IsCursorEnabledInitial = true; 30 | }; -------------------------------------------------------------------------------- /src/DesktopPlusWinRT/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/DesktopPlusWinRT/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by DesktopPlusWinRT.rc 4 | 5 | // Next default values for new objects 6 | // 7 | #ifdef APSTUDIO_INVOKED 8 | #ifndef APSTUDIO_READONLY_SYMBOLS 9 | #define _APS_NEXT_RESOURCE_VALUE 101 10 | #define _APS_NEXT_COMMAND_VALUE 40001 11 | #define _APS_NEXT_CONTROL_VALUE 1001 12 | #define _APS_NEXT_SYMED_VALUE 101 13 | #endif 14 | #endif 15 | -------------------------------------------------------------------------------- /src/DesktopPlusWinRT/util/DesktopWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "hwnd.interop.h" 3 | 4 | namespace util::desktop 5 | { 6 | // adapted from https://gist.github.com/kennykerr/64e0248323267b9b158acd26b51b3c8b 7 | template 8 | struct DesktopWindow 9 | { 10 | using base_type = DesktopWindow; 11 | HWND m_window = nullptr; 12 | 13 | static T* GetThisFromHandle(HWND const window) noexcept 14 | { 15 | return reinterpret_cast(GetWindowLongPtr(window, GWLP_USERDATA)); 16 | } 17 | 18 | static LRESULT __stdcall WndProc(HWND const window, UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept 19 | { 20 | WINRT_ASSERT(window); 21 | 22 | if (WM_NCCREATE == message) 23 | { 24 | auto cs = reinterpret_cast(lparam); 25 | T* that = static_cast(cs->lpCreateParams); 26 | WINRT_ASSERT(that); 27 | WINRT_ASSERT(!that->m_window); 28 | that->m_window = window; 29 | SetWindowLongPtr(window, GWLP_USERDATA, reinterpret_cast(that)); 30 | } 31 | else if (T* that = GetThisFromHandle(window)) 32 | { 33 | return that->MessageHandler(message, wparam, lparam); 34 | } 35 | 36 | return DefWindowProc(window, message, wparam, lparam); 37 | } 38 | 39 | LRESULT MessageHandler(UINT const message, WPARAM const wparam, LPARAM const lparam) noexcept 40 | { 41 | if (WM_DESTROY == message) 42 | { 43 | PostQuitMessage(0); 44 | return 0; 45 | } 46 | 47 | return DefWindowProc(m_window, message, wparam, lparam); 48 | } 49 | 50 | void InitializeObjectWithWindowHandle(winrt::Windows::Foundation::IUnknown const& object) 51 | { 52 | auto initializer = object.as(); 53 | winrt::check_hresult(initializer->Initialize(m_window)); 54 | } 55 | }; 56 | } 57 | 58 | -------------------------------------------------------------------------------- /src/DesktopPlusWinRT/util/capture.desktop.interop.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | 6 | namespace util 7 | { 8 | inline auto CreateCaptureItemForWindow(HWND hwnd) 9 | { 10 | auto interop_factory = winrt::get_activation_factory(); 11 | winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = { nullptr }; 12 | winrt::check_hresult(interop_factory->CreateForWindow(hwnd, winrt::guid_of(), winrt::put_abi(item))); 13 | return item; 14 | } 15 | 16 | inline auto CreateCaptureItemForMonitor(HMONITOR hmon) 17 | { 18 | auto interop_factory = winrt::get_activation_factory(); 19 | winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = { nullptr }; 20 | winrt::check_hresult(interop_factory->CreateForMonitor(hmon, winrt::guid_of(), winrt::put_abi(item))); 21 | return item; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/DesktopPlusWinRT/util/direct3d11.interop.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | extern "C" 5 | { 6 | HRESULT __stdcall CreateDirect3D11DeviceFromDXGIDevice(::IDXGIDevice* dxgiDevice, 7 | ::IInspectable** graphicsDevice); 8 | 9 | HRESULT __stdcall CreateDirect3D11SurfaceFromDXGISurface(::IDXGISurface* dgxiSurface, 10 | ::IInspectable** graphicsSurface); 11 | } 12 | 13 | struct __declspec(uuid("A9B3D012-3DF2-4EE3-B8D1-8695F457D3C1")) 14 | IDirect3DDxgiInterfaceAccess : ::IUnknown 15 | { 16 | virtual HRESULT __stdcall GetInterface(GUID const& id, void** object) = 0; 17 | }; 18 | 19 | inline auto CreateDirect3DDevice(IDXGIDevice* dxgi_device) 20 | { 21 | winrt::com_ptr<::IInspectable> d3d_device; 22 | winrt::check_hresult(CreateDirect3D11DeviceFromDXGIDevice(dxgi_device, d3d_device.put())); 23 | return d3d_device.as(); 24 | } 25 | 26 | inline auto CreateDirect3DSurface(IDXGISurface* dxgi_surface) 27 | { 28 | winrt::com_ptr<::IInspectable> d3d_surface; 29 | winrt::check_hresult(CreateDirect3D11SurfaceFromDXGISurface(dxgi_surface, d3d_surface.put())); 30 | return d3d_surface.as(); 31 | } 32 | 33 | template 34 | auto GetDXGIInterfaceFromObject(winrt::Windows::Foundation::IInspectable const& object) 35 | { 36 | auto access = object.as(); 37 | winrt::com_ptr result; 38 | winrt::check_hresult(access->GetInterface(winrt::guid_of(), result.put_void())); 39 | return result; 40 | } -------------------------------------------------------------------------------- /src/DesktopPlusWinRT/util/dispatcherqueue.desktop.interop.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | namespace util::desktop 6 | { 7 | inline auto CreateDispatcherQueueControllerForCurrentThread() 8 | { 9 | namespace abi = ABI::Windows::System; 10 | 11 | DispatcherQueueOptions options 12 | { 13 | sizeof(DispatcherQueueOptions), 14 | DQTYPE_THREAD_CURRENT, 15 | DQTAT_COM_NONE 16 | }; 17 | 18 | winrt::Windows::System::DispatcherQueueController controller{ nullptr }; 19 | winrt::check_hresult(CreateDispatcherQueueController(options, reinterpret_cast(winrt::put_abi(controller)))); 20 | return controller; 21 | } 22 | } -------------------------------------------------------------------------------- /src/DesktopPlusWinRT/util/hwnd.interop.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | namespace util::desktop 5 | { 6 | // Taken from shobjidl_core.h 7 | struct __declspec(uuid("3E68D4BD-7135-4D10-8018-9FB6D9F33FA1")) 8 | IInitializeWithWindow : ::IUnknown 9 | { 10 | virtual HRESULT __stdcall Initialize(HWND hwnd) = 0; 11 | }; 12 | } 13 | -------------------------------------------------------------------------------- /src/Shared/AppProfiles.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include "Actions.h" 6 | 7 | struct AppProfile 8 | { 9 | bool IsEnabled = false; 10 | std::string LastApplicationName; //Used when SteamVR isn't running or can't find the application from the app key 11 | std::string OverlayProfileFileName; 12 | ActionUID ActionUIDEnter = k_ActionUID_Invalid; 13 | ActionUID ActionUIDLeave = k_ActionUID_Invalid; 14 | 15 | std::string Serialize() const; //Serializes into binary data stored as string (contains NUL bytes), not suitable for storage 16 | void Deserialize(const std::string& str); //Deserializes from strings created by above function 17 | }; 18 | 19 | class AppProfileManager 20 | { 21 | private: 22 | std::unordered_map m_Profiles; 23 | AppProfile m_NullProfile; 24 | 25 | std::string m_AppKeyActiveProfile; 26 | std::string m_AppNameActiveProfile; 27 | bool m_IsProfileActiveWithOverlayProfile = false; 28 | 29 | std::string GetCurrentSceneAppKey() const; 30 | std::string GetProcessAppKey(uint32_t pid) const; 31 | 32 | public: 33 | bool LoadProfilesFromFile(); 34 | void SaveProfilesToFile(); 35 | 36 | const AppProfile& GetProfile(const std::string& app_key); 37 | bool ProfileExists(const std::string& app_key) const; 38 | bool StoreProfile(const std::string& app_key, const AppProfile& profile); //Returns true if a new overlay profile was loaded after change of active profile 39 | bool RemoveProfile(const std::string& app_key); //Returns true if a new overlay profile was loaded after removal of active profile 40 | void RemoveAllProfiles(); 41 | 42 | bool ActivateProfile(const std::string& app_key); //Returns true if a new overlay profile was loaded 43 | bool ActivateProfileForCurrentSceneApp(); //^ 44 | bool ActivateProfileForProcess(uint32_t pid); //^ 45 | const std::string& GetActiveProfileAppKey(); 46 | const std::string& GetActiveProfileAppName(); 47 | bool IsActiveProfileWithOverlayProfile() const; //Returns if the active app profile loaded an overlay profile 48 | 49 | std::vector GetProfileAppKeyList() const; 50 | }; -------------------------------------------------------------------------------- /src/Shared/DPRect.h: -------------------------------------------------------------------------------- 1 | //This is pretty much a straight adaption of Dear ImGui's internal ImRect class 2 | 3 | #pragma once 4 | 5 | #include "Util.h" 6 | #include "Vectors.h" 7 | 8 | // 2D axis aligned bounding-box 9 | class DPRect 10 | { 11 | public: 12 | Vector2Int Min; // Upper-left 13 | Vector2Int Max; // Lower-right 14 | 15 | DPRect() : Min(0, 0), Max(0, 0) {} 16 | DPRect(const Vector2Int& min, const Vector2Int& max) : Min(min), Max(max) {} 17 | DPRect(int x1, int y1, int x2, int y2) : Min(x1, y1), Max(x2, y2) {} 18 | 19 | Vector2Int GetCenter() const { return Vector2Int(int((Min.x + Max.x) * 0.5f), int((Min.y + Max.y) * 0.5f)); } 20 | Vector2Int GetSize() const { return Vector2Int(Max.x - Min.x, Max.y - Min.y); } 21 | int GetWidth() const { return Max.x - Min.x; } 22 | int GetHeight() const { return Max.y - Min.y; } 23 | Vector2Int GetTL() const { return Min; } // Top-left 24 | Vector2Int GetTR() const { return Vector2Int(Max.x, Min.y); } // Top-right 25 | Vector2Int GetBL() const { return Vector2Int(Min.x, Max.y); } // Bottom-left 26 | Vector2Int GetBR() const { return Max; } // Bottom-right 27 | bool Contains(const Vector2Int& p) const { return p.x >= Min.x && p.y >= Min.y && p.x < Max.x && p.y < Max.y; } 28 | bool Contains(const DPRect& r) const { return r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x <= Max.x && r.Max.y <= Max.y; } 29 | bool Overlaps(const DPRect& r) const { return r.Min.y < Max.y && r.Max.y > Min.y && r.Min.x < Max.x && r.Max.x > Min.x; } 30 | void Add(const Vector2Int& p) { if (Min.x > p.x) Min.x = p.x; if (Min.y > p.y) Min.y = p.y; if (Max.x < p.x) Max.x = p.x; if (Max.y < p.y) Max.y = p.y; } 31 | void Add(const DPRect& r) { if (Min.x > r.Min.x) Min.x = r.Min.x; if (Min.y > r.Min.y) Min.y = r.Min.y; if (Max.x < r.Max.x) Max.x = r.Max.x; if (Max.y < r.Max.y) Max.y = r.Max.y; } 32 | void Expand(const int amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; } 33 | void Expand(const Vector2Int& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; } 34 | void Translate(const Vector2Int& d) { Min.x += d.x; Min.y += d.y; Max.x += d.x; Max.y += d.y; } 35 | void TranslateX(int dx) { Min.x += dx; Max.x += dx; } 36 | void TranslateY(int dy) { Min.y += dy; Max.y += dy; } 37 | void ClipWith(const DPRect& r) { Min = Vector2Int::vec_max(Min, r.Min); Max = Vector2Int::vec_min(Max, r.Max); } // Simple version, may lead to an inverted rectangle, which is fine for Contains/Overlaps test but not for display. 38 | void ClipWithFull(const DPRect& r) { Min = Vector2Int::vec_clamp(Min, r.Min, r.Max); Max = Vector2Int::vec_clamp(Max, r.Min, r.Max); } // Full version, ensure both points are fully clipped. 39 | bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; } 40 | uint64_t Pack16() const 41 | { 42 | uint64_t min_x = (uint16_t)Min.x, min_y = (uint16_t)Min.y, max_x = (uint16_t)Max.x, max_y = (uint16_t)Max.y; 43 | return (min_x << 48) | (min_y << 32) | (max_x << 16) | max_y; 44 | } 45 | void Unpack16(uint64_t value) 46 | { 47 | Min.x = int16_t((value & 0xFFFF000000000000) >> 48); 48 | Min.y = int16_t((value & 0x0000FFFF00000000) >> 32); 49 | Max.x = int16_t((value & 0x00000000FFFF0000) >> 16); 50 | Max.y = int16_t (value & 0x000000000000FFFF); 51 | } 52 | 53 | bool operator==(const DPRect& r) const { return r.Min == Min && r.Max == Max; } 54 | }; -------------------------------------------------------------------------------- /src/Shared/Ini.h: -------------------------------------------------------------------------------- 1 | //Small Ini class to make handling settings a bit less painful, see Ini.cpp for details 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | typedef struct ini_t ini_t; 9 | 10 | class Ini 11 | { 12 | private: 13 | std::wstring m_WFileName; 14 | ini_t* m_IniPtr; 15 | 16 | public: 17 | Ini(const std::wstring& filename, bool replace_contents = false); 18 | Ini(const Ini&) = delete; 19 | ~Ini(); 20 | 21 | bool Save(); 22 | bool Save(const std::wstring& filename); 23 | 24 | std::string ReadString(const char* section, const char* key, const char* default_value = "") const; 25 | int ReadInt(const char* section, const char* key, int default_value = -1) const; 26 | bool ReadBool(const char* section, const char* key, bool default_value = false) const; 27 | void WriteString(const char* section, const char* key, const char* value); 28 | void WriteInt(const char* section, const char* key, int value); 29 | void WriteBool(const char* section, const char* key, bool value); 30 | 31 | bool SectionExists(const char* section) const; 32 | bool KeyExists(const char* section, const char* key) const; 33 | bool RenameSection(const char* section, const char* new_name); 34 | void RemoveSection(const char* section); 35 | void RemoveKey(const char* section, const char* key); 36 | 37 | std::vector GetSectionList(); 38 | }; -------------------------------------------------------------------------------- /src/Shared/Logging.h: -------------------------------------------------------------------------------- 1 | //Just log rotation/unified init plus some common info logs on top of Loguru 2 | 3 | #pragma once 4 | 5 | #include "loguru.hpp" 6 | 7 | //Version string logged and displayed in the UI 8 | //DPLUS_SHA is set externally for nightly builds to use the commit hash in version string 9 | //DPLUS_SHA is also always defined but usually empty... so we detect this with some constexpr trickery instead of messing with the build system even more 10 | constexpr const char* const k_pch_DesktopPlusVersion = (sizeof("" DPLUS_SHA) <= 1) ? "Desktop+ 3.2" : "Desktop+ " DPLUS_SHA; 11 | 12 | //Version written to config file 13 | //Only really increased when backward incompatible changes were made (we fall back to default values when things are missing usually) 14 | static const int k_nDesktopPlusConfigVersion = 2; 15 | 16 | void DPLog_Init(const char* name); 17 | void DPLog_SteamVR_SystemInfo(); 18 | void DPLog_DPWinRT_SupportInfo(); -------------------------------------------------------------------------------- /src/Shared/OUtoSBSConverter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifndef NOMINMAX 4 | #define NOMINMAX 5 | #endif 6 | #include 7 | #include 8 | 9 | #include "Vectors.h" 10 | 11 | //This class rearranges an OU 3D texture to a SBS 3D texture 12 | class OUtoSBSConverter 13 | { 14 | private: 15 | Microsoft::WRL::ComPtr m_TexSBS; //Owned by device 16 | Microsoft::WRL::ComPtr m_MultiGPUTexSBSStaging; //Staging texture, owned by device 17 | Microsoft::WRL::ComPtr m_MultiGPUTexSBSTarget; //Target texture to copy to, owned by multi_gpu_device 18 | Vector2Int m_TextSizeSBS; 19 | 20 | public: 21 | ID3D11Texture2D* GetTexture() const; //Does not add a reference 22 | Vector2Int GetTextureSizeSBS() const; 23 | HRESULT Convert(ID3D11Device* device, ID3D11DeviceContext* device_context, ID3D11Device* multi_gpu_device, ID3D11DeviceContext* multi_gpu_device_context, 24 | ID3D11Texture2D* tex_source, int tex_source_width, int tex_source_height, int crop_x, int crop_y, int crop_width, int crop_height); 25 | void CleanRefs(); 26 | 27 | }; -------------------------------------------------------------------------------- /src/Shared/OverlayDragger.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Matrices.h" 4 | #include "ConfigManager.h" 5 | 6 | //Class handling dragging overlays with motion controllers, with support for all Desktop+ overlay origins 7 | class OverlayDragger 8 | { 9 | private: 10 | int m_DragModeDeviceID; //-1 if not dragging 11 | unsigned int m_DragModeOverlayID; 12 | vr::VROverlayHandle_t m_DragModeOverlayHandle; 13 | OverlayOrigin m_DragModeOverlayOrigin; 14 | OverlayOriginConfig m_DragModeOverlayOriginConfig; 15 | float m_DragModeMaxWidth; 16 | 17 | Matrix4 m_DragModeMatrixTargetStart; 18 | Matrix4 m_DragModeMatrixSourceStart; 19 | Matrix4 m_DragModeMatrixTargetCurrent; 20 | float m_DragModeSnappedExtraWidth; 21 | 22 | bool m_DragGestureActive; 23 | float m_DragGestureScaleDistanceStart; 24 | float m_DragGestureScaleWidthStart; 25 | float m_DragGestureScaleDistanceLast; 26 | Matrix4 m_DragGestureRotateMatLast; 27 | 28 | bool m_AbsoluteModeActive; //Absolute mode forces the overlay to stay centered on the controller tip + offset 29 | float m_AbsoluteModeOffsetForward; 30 | 31 | Matrix4 m_DashboardMatLast; 32 | float m_DashboardHMD_Y; //The HMDs y-position when the dashboard was activated. Used for dashboard-relative positioning 33 | Vector3 m_TempStandingPosition; //Standing position updated when the dashboard tab is activated or drag-mode activated while dashboard tab closed. Used as semi-fixed reference point 34 | 35 | void DragStartBase(bool is_gesture_drag = false); 36 | void DragGestureStartBase(); 37 | 38 | void TransformForceUpright(Matrix4& transform) const; 39 | void TransformForceDistance(Matrix4& transform, Vector3 reference_pos, float distance, bool use_cylinder_shape = false, bool auto_tilt = false) const; 40 | void TransformSnapRotation(Matrix4& transform, float degrees, bool snap_x, bool snap_y, bool snap_z) const; 41 | 42 | public: 43 | OverlayDragger(); 44 | 45 | Matrix4 GetBaseOffsetMatrix(); 46 | Matrix4 GetBaseOffsetMatrix(OverlayOrigin overlay_origin); //Not recommended to use with origins that have config values 47 | Matrix4 GetBaseOffsetMatrix(OverlayOrigin overlay_origin, const OverlayOriginConfig& origin_config); 48 | void ApplyDashboardScale(Matrix4& matrix); 49 | 50 | void DragStart(unsigned int overlay_id); 51 | void DragStart(vr::VROverlayHandle_t overlay_handle, OverlayOrigin overlay_origin = ovrl_origin_room); //Not recommended to use with origins that have config values 52 | void DragUpdate(); 53 | void DragAddDistance(float distance); 54 | float DragAddWidth(float width); //Returns new width 55 | void DragSetMaxWidth(float max_width); //Maximum width applied whenever width would otherwise change. Resets on drag start, so set after 56 | Matrix4 DragFinish(); //Returns new overlay origin-relative transform 57 | void DragCancel(); //Stops drag without applying any changes 58 | 59 | void DragGestureStart(unsigned int overlay_id); 60 | void DragGestureStart(vr::VROverlayHandle_t overlay_handle, OverlayOrigin overlay_origin = ovrl_origin_room); 61 | void DragGestureUpdate(); 62 | Matrix4 DragGestureFinish(); //Returns new overlay origin-relative transform 63 | 64 | void AbsoluteModeSet(bool is_active, float offset_forward); //Automatically reset on DragFinish() 65 | 66 | void UpdateDashboardHMD_Y(); 67 | void UpdateTempStandingPosition(); 68 | 69 | bool IsDragActive() const; //Doesn't include active gesture drag 70 | bool IsDragGestureActive() const; 71 | int GetDragDeviceID() const; 72 | unsigned int GetDragOverlayID() const; 73 | vr::VROverlayHandle_t GetDragOverlayHandle() const; 74 | const Matrix4& GetDragOverlayMatrix() const; //Only valid while IsDragActive() returns true 75 | }; -------------------------------------------------------------------------------- /src/Shared/Util.h: -------------------------------------------------------------------------------- 1 | //Some misc utility functions shared between both applications 2 | 3 | #pragma once 4 | 5 | #include 6 | #include 7 | 8 | #ifndef NOMINMAX 9 | #define NOMINMAX 10 | #endif 11 | #include 12 | #include 13 | 14 | #include "Matrices.h" 15 | 16 | //String conversion functions using win32's conversion. Return empty string on failure 17 | std::string StringConvertFromUTF16(LPCWSTR str); 18 | std::wstring WStringConvertFromUTF8(const char* str); 19 | std::wstring WStringConvertFromLocalEncoding(const char* str); 20 | 21 | //Algorithm helpers 22 | template T clamp(const T& value, const T& value_min, const T& value_max) 23 | { 24 | return std::max(value_min, std::min(value, value_max)); 25 | } 26 | 27 | template int sgn(T val) 28 | { 29 | return (T(0) < val) - (val < T(0)); 30 | } 31 | 32 | template inline typename std::enable_if_t && std::is_trivially_copyable_v, T_out> pun_cast(const T_in& value) 33 | { 34 | //Do type punning, but actually legal 35 | T_out value_out = T_out(0); 36 | std::memcpy(&value_out, &value, (sizeof(value_out) < sizeof(value)) ? sizeof(value_out) : sizeof(value) ); 37 | return value_out; 38 | } 39 | 40 | inline float smoothstep(float step, float value_min, float value_max) 41 | { 42 | return ((step) * (step) * (3 - 2 * (step))) * (value_max - value_min) + value_min; 43 | } 44 | 45 | inline float lin2log(float value_normalized) 46 | { 47 | return value_normalized * (logf(value_normalized + 1.0f) / logf(2.0f)); 48 | } 49 | 50 | //64-bit packed value helpers for window messages (we don't support building for 32-bit so this is fine) 51 | #define MAKEQWORD(a, b) ((DWORD64)(((DWORD)(((DWORD64)(a)) & 0xffffffff)) | ((DWORD64)((DWORD)(((DWORD64)(b)) & 0xffffffff))) << 32)) 52 | #define LODWORD(qw) ((DWORD)(qw)) 53 | #define HIDWORD(qw) ((DWORD)(((qw) >> 32) & 0xffffffff)) 54 | 55 | //Display stuff 56 | DEVMODE GetDevmodeForDisplayID(int display_id, bool wmr_ignore_vscreens, HMONITOR* hmon = nullptr); //DEVMODE.dmSize != 0 on success 57 | int GetDisplayIDFromHMonitor(HMONITOR monitor_handle, bool wmr_ignore_vscreens); //Returns -1 on failure 58 | int GetMonitorRefreshRate(int display_id, bool wmr_ignore_vscreens); 59 | void CenterRectToMonitor(LPRECT prc); 60 | void CenterWindowToMonitor(HWND hwnd, bool use_cursor_pos = false); 61 | void ForceScreenRefresh(); 62 | 63 | //Misc 64 | bool IsProcessElevated(); 65 | bool IsProcessElevated(DWORD process_id); 66 | bool ShellExecuteUnelevated(LPCWSTR lpFile, LPCWSTR lpParameters = nullptr, LPCWSTR lpDirectory = nullptr, LPCWSTR lpOperation = nullptr, INT nShowCmd = SW_SHOWNORMAL); 67 | bool FileExists(LPCTSTR path); 68 | bool DirectoryExists(LPCTSTR path); 69 | void StopProcessByWindowClass(LPCTSTR class_name); //Used to stop the previous instance of the application 70 | HWND FindMainWindow(DWORD pid); 71 | unsigned int GetKeyboardModifierState(); 72 | void StringReplaceAll(std::string& source, const std::string& from, const std::string& to); 73 | void WStringReplaceAll(std::wstring& source, const std::wstring& from, const std::wstring& to); 74 | bool IsWCharInvalidForFileName(wchar_t wchar); 75 | void SanitizeFileNameWString(std::wstring& str); 76 | bool WStringCompareNatural(std::wstring& str1, std::wstring& str2); 77 | 78 | //Virtual Keycode string mapping 79 | const char* GetStringForKeyCode(unsigned char keycode); 80 | unsigned char GetKeyCodeForListID(unsigned char list_id); //Used for a more natural sort when doing direct listing -------------------------------------------------------------------------------- /src/Shared/icon_desktop.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/src/Shared/icon_desktop.ico -------------------------------------------------------------------------------- /src/Shared/openvr_api.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/elvissteinjr/DesktopPlus/89eb2353203f34b3856b02386e182afa8238fdbb/src/Shared/openvr_api.lib --------------------------------------------------------------------------------