Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Support content-type-v1 proto #9226

Merged
merged 12 commits into from
Feb 2, 2025
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,15 @@ pkg_check_modules(hyprcursor_dep REQUIRED IMPORTED_TARGET hyprcursor>=0.1.7)
pkg_check_modules(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.5.0)
pkg_check_modules(hyprgraphics_dep REQUIRED IMPORTED_TARGET hyprgraphics>=0.1.1)

string(REPLACE "." ";" AQ_VERSION_LIST ${aquamarine_dep_VERSION})
list(GET AQ_VERSION_LIST 0 AQ_VERSION_MAJOR)
list(GET AQ_VERSION_LIST 1 AQ_VERSION_MINOR)
list(GET AQ_VERSION_LIST 2 AQ_VERSION_PATCH)

add_compile_definitions(AQUAMARINE_VERSION="${aquamarine_dep_VERSION}")
add_compile_definitions(AQUAMARINE_VERSION_MAJOR=${AQ_VERSION_MAJOR})
add_compile_definitions(AQUAMARINE_VERSION_MINOR=${AQ_VERSION_MINOR})
add_compile_definitions(AQUAMARINE_VERSION_PATCH=${AQ_VERSION_PATCH})
add_compile_definitions(HYPRLANG_VERSION="${hyprlang_dep_VERSION}")
add_compile_definitions(HYPRUTILS_VERSION="${hyprutils_dep_VERSION}")
add_compile_definitions(HYPRCURSOR_VERSION="${hyprcursor_dep_VERSION}")
Expand Down Expand Up @@ -368,6 +376,7 @@ protocolnew("staging/linux-drm-syncobj" "linux-drm-syncobj-v1" false)
protocolnew("staging/xdg-dialog" "xdg-dialog-v1" false)
protocolnew("staging/single-pixel-buffer" "single-pixel-buffer-v1" false)
protocolnew("staging/security-context" "security-context-v1" false)
protocolnew("staging/content-type" "content-type-v1" false)

protocolwayland()

Expand Down
4 changes: 4 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,11 @@ hyprcursor = dependency('hyprcursor', version: '>=0.1.7')
hyprgraphics = dependency('hyprgraphics', version: '>= 0.1.1')
hyprlang = dependency('hyprlang', version: '>= 0.3.2')
hyprutils = dependency('hyprutils', version: '>= 0.2.3')
aquamarine_version_list = aquamarine.version().split('.')
add_project_arguments(['-DAQUAMARINE_VERSION="@0@"'.format(aquamarine.version())], language: 'cpp')
add_project_arguments(['-DAQUAMARINE_VERSION_MAJOR=@0@'.format(aquamarine_version_list.get(0))], language: 'cpp')
add_project_arguments(['-DAQUAMARINE_VERSION_MINOR=@0@'.format(aquamarine_version_list.get(1))], language: 'cpp')
add_project_arguments(['-DAQUAMARINE_VERSION_PATCH=@0@'.format(aquamarine_version_list.get(2))], language: 'cpp')
add_project_arguments(['-DHYPRCURSOR_VERSION="@0@"'.format(hyprcursor.version())], language: 'cpp')
add_project_arguments(['-DHYPRGRAPHICS_VERSION="@0@"'.format(hyprgraphics.version())], language: 'cpp')
add_project_arguments(['-DHYPRLANG_VERSION="@0@"'.format(hyprlang.version())], language: 'cpp')
Expand Down
1 change: 1 addition & 0 deletions protocols/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ protocols = [
wayland_protocol_dir / 'staging/xdg-dialog/xdg-dialog-v1.xml',
wayland_protocol_dir / 'staging/single-pixel-buffer/single-pixel-buffer-v1.xml',
wayland_protocol_dir / 'staging/security-context/security-context-v1.xml',
wayland_protocol_dir / 'staging/content-type/content-type-v1.xml',
]

wl_protocols = []
Expand Down
3 changes: 2 additions & 1 deletion src/Compositor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@

using namespace Hyprutils::String;
using namespace Aquamarine;
using enum NContentType::eContentType;

static int handleCritSignal(int signo, void* data) {
Debug::log(LOG, "Hyprland received signal {}", signo);
Expand Down Expand Up @@ -2335,7 +2336,7 @@ void CCompositor::setWindowFullscreenState(const PHLWINDOW PWINDOW, SFullscreenS

// send a scanout tranche if we are entering fullscreen, and send a regular one if we aren't.
// ignore if DS is disabled.
if (*PDIRECTSCANOUT)
if (*PDIRECTSCANOUT == 1 || (*PDIRECTSCANOUT == 2 && PWINDOW->getContentType() == CONTENT_TYPE_GAME))
g_pHyprRenderer->setSurfaceScanoutMode(PWINDOW->m_pWLSurface->resource(), EFFECTIVE_MODE != FSMODE_NONE ? PMONITOR->self.lock() : nullptr);

g_pConfigManager->ensureVRR(PMONITOR);
Expand Down
13 changes: 7 additions & 6 deletions src/config/ConfigDescriptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1314,9 +1314,9 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
SConfigOptionDescription{
.value = "render:direct_scanout",
.description = "Enables direct scanout. Direct scanout attempts to reduce lag when there is only one fullscreen application on a screen (e.g. game). It is also "
"recommended to set this to false if the fullscreen application shows graphical glitches.",
.type = CONFIG_OPTION_BOOL,
.data = SConfigOptionDescription::SBoolData{false},
"recommended to set this to false if the fullscreen application shows graphical glitches. 0 - off, 1 - on, 2 - auto (on with content type 'game')",
.type = CONFIG_OPTION_INT,
.data = SConfigOptionDescription::SRangeData{.value = 0, .min = 0, .max = 2},
},
SConfigOptionDescription{
.value = "render:expand_undersized_textures",
Expand Down Expand Up @@ -1362,9 +1362,10 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
},
SConfigOptionDescription{
.value = "cursor:no_break_fs_vrr",
.description = "disables scheduling new frames on cursor movement for fullscreen apps with VRR enabled to avoid framerate spikes (requires no_hardware_cursors = true)",
.type = CONFIG_OPTION_BOOL,
.data = SConfigOptionDescription::SBoolData{false},
.description = "disables scheduling new frames on cursor movement for fullscreen apps with VRR enabled to avoid framerate spikes (may require no_hardware_cursors = true) "
"0 - off, 1 - on, 2 - auto (on with content type 'game')",
.type = CONFIG_OPTION_INT,
.data = SConfigOptionDescription::SRangeData{.value = 2, .min = 0, .max = 2},
},
SConfigOptionDescription{
.value = "cursor:min_refresh_rate",
Expand Down
24 changes: 21 additions & 3 deletions src/config/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "../plugins/PluginSystem.hpp"

#include "managers/HookSystemManager.hpp"
#include "protocols/types/ContentType.hpp"
#include <cstddef>
#include <cstdint>
#include <hyprutils/path/Path.hpp>
Expand Down Expand Up @@ -621,7 +622,7 @@ CConfigManager::CConfigManager() {
m_pConfig->addConfigValue("opengl:nvidia_anti_flicker", Hyprlang::INT{1});

m_pConfig->addConfigValue("cursor:no_hardware_cursors", Hyprlang::INT{0});
m_pConfig->addConfigValue("cursor:no_break_fs_vrr", Hyprlang::INT{0});
m_pConfig->addConfigValue("cursor:no_break_fs_vrr", Hyprlang::INT{2});
m_pConfig->addConfigValue("cursor:min_refresh_rate", Hyprlang::INT{24});
m_pConfig->addConfigValue("cursor:hotspot_padding", Hyprlang::INT{0});
m_pConfig->addConfigValue("cursor:inactive_timeout", {0.f});
Expand Down Expand Up @@ -1347,6 +1348,14 @@ std::vector<SP<CWindowRule>> CConfigManager::getMatchingRules(PHLWINDOW pWindow,
continue;
}

if (!rule->szContentType.empty()) {
try {
const auto contentType = NContentType::fromString(rule->szContentType);
if (pWindow->getContentType() != contentType)
continue;
} catch (std::exception& e) { Debug::log(ERR, "Rule \"content:{}\" failed with: {}", rule->szContentType, e.what()); }
}

if (!rule->szWorkspace.empty()) {
const auto PWORKSPACE = pWindow->m_pWorkspace;

Expand Down Expand Up @@ -2361,6 +2370,7 @@ std::optional<std::string> CConfigManager::handleWindowRuleV2(const std::string&
const auto FOCUSPOS = VALUE.find("focus:");
const auto FULLSCREENSTATEPOS = VALUE.find("fullscreenstate:");
const auto ONWORKSPACEPOS = VALUE.find("onworkspace:");
const auto CONTENTTYPEPOS = VALUE.find("content:");

// find workspacepos that isn't onworkspacepos
size_t WORKSPACEPOS = std::string::npos;
Expand All @@ -2373,8 +2383,8 @@ std::optional<std::string> CConfigManager::handleWindowRuleV2(const std::string&
currentPos = VALUE.find("workspace:", currentPos + 1);
}

const auto checkPos = std::unordered_set{TAGPOS, TITLEPOS, CLASSPOS, INITIALTITLEPOS, INITIALCLASSPOS, X11POS, FLOATPOS,
FULLSCREENPOS, PINNEDPOS, FULLSCREENSTATEPOS, WORKSPACEPOS, FOCUSPOS, ONWORKSPACEPOS};
const auto checkPos = std::unordered_set{TAGPOS, TITLEPOS, CLASSPOS, INITIALTITLEPOS, INITIALCLASSPOS, X11POS, FLOATPOS,
FULLSCREENPOS, PINNEDPOS, FULLSCREENSTATEPOS, WORKSPACEPOS, FOCUSPOS, ONWORKSPACEPOS, CONTENTTYPEPOS};
if (checkPos.size() == 1 && checkPos.contains(std::string::npos)) {
Debug::log(ERR, "Invalid rulev2 syntax: {}", VALUE);
return "Invalid rulev2 syntax: " + VALUE;
Expand Down Expand Up @@ -2411,6 +2421,8 @@ std::optional<std::string> CConfigManager::handleWindowRuleV2(const std::string&
min = WORKSPACEPOS;
if (FOCUSPOS > pos && FOCUSPOS < min)
min = FOCUSPOS;
if (CONTENTTYPEPOS > pos && CONTENTTYPEPOS < min)
min = CONTENTTYPEPOS;

result = result.substr(0, min - pos);

Expand Down Expand Up @@ -2469,6 +2481,9 @@ std::optional<std::string> CConfigManager::handleWindowRuleV2(const std::string&
if (ONWORKSPACEPOS != std::string::npos)
rule->szOnWorkspace = extract(ONWORKSPACEPOS + 12);

if (CONTENTTYPEPOS != std::string::npos)
rule->szContentType = extract(CONTENTTYPEPOS + 8);

if (RULE == "unset") {
std::erase_if(m_vWindowRules, [&](const auto& other) {
if (!other->v2)
Expand Down Expand Up @@ -2513,6 +2528,9 @@ std::optional<std::string> CConfigManager::handleWindowRuleV2(const std::string&
if (!rule->szOnWorkspace.empty() && rule->szOnWorkspace != other->szOnWorkspace)
return false;

if (!rule->szContentType.empty() && rule->szContentType != other->szContentType)
return false;

return true;
}
});
Expand Down
15 changes: 15 additions & 0 deletions src/desktop/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "../managers/AnimationManager.hpp"
#include "../protocols/XDGShell.hpp"
#include "../protocols/core/Compositor.hpp"
#include "../protocols/ContentType.hpp"
#include "../xwayland/XWayland.hpp"
#include "../helpers/Color.hpp"
#include "../events/Events.hpp"
Expand All @@ -29,6 +30,7 @@

using namespace Hyprutils::String;
using namespace Hyprutils::Animation;
using enum NContentType::eContentType;

PHLWINDOW CWindow::create(SP<CXWaylandSurface> surface) {
PHLWINDOW pWindow = SP<CWindow>(new CWindow(surface));
Expand Down Expand Up @@ -1724,3 +1726,16 @@ void CWindow::sendWindowSize(Vector2D size, bool force, std::optional<Vector2D>
else if (m_pXDGSurface && m_pXDGSurface->toplevel)
m_vPendingSizeAcks.emplace_back(m_pXDGSurface->toplevel->setSize(size), size.floor());
}

NContentType::eContentType CWindow::getContentType() {
return m_pWLSurface->resource()->contentType.valid() ? m_pWLSurface->resource()->contentType->value : CONTENT_TYPE_NONE;
}

void CWindow::setContentType(NContentType::eContentType contentType) {
if (!m_pWLSurface->resource()->contentType.valid())
m_pWLSurface->resource()->contentType = PROTO::contentType->getContentType(m_pWLSurface->resource());
// else disallow content type change if proto is used?

Debug::log(INFO, "ContentType for window {}", (int)contentType);
m_pWLSurface->resource()->contentType->value = contentType;
}
Loading
Loading