mirror of
https://github.com/hyprwm/Hyprland.git
synced 2025-05-19 08:30:22 -07:00
protocols: Support content-type-v1 proto (#9226)
This commit is contained in:
parent
70d94fec13
commit
31431a9271
@ -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(hyprutils_dep REQUIRED IMPORTED_TARGET hyprutils>=0.5.0)
|
||||||
pkg_check_modules(hyprgraphics_dep REQUIRED IMPORTED_TARGET hyprgraphics>=0.1.1)
|
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="${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(HYPRLANG_VERSION="${hyprlang_dep_VERSION}")
|
||||||
add_compile_definitions(HYPRUTILS_VERSION="${hyprutils_dep_VERSION}")
|
add_compile_definitions(HYPRUTILS_VERSION="${hyprutils_dep_VERSION}")
|
||||||
add_compile_definitions(HYPRCURSOR_VERSION="${hyprcursor_dep_VERSION}")
|
add_compile_definitions(HYPRCURSOR_VERSION="${hyprcursor_dep_VERSION}")
|
||||||
@ -368,6 +376,7 @@ protocolnew("staging/linux-drm-syncobj" "linux-drm-syncobj-v1" false)
|
|||||||
protocolnew("staging/xdg-dialog" "xdg-dialog-v1" false)
|
protocolnew("staging/xdg-dialog" "xdg-dialog-v1" false)
|
||||||
protocolnew("staging/single-pixel-buffer" "single-pixel-buffer-v1" false)
|
protocolnew("staging/single-pixel-buffer" "single-pixel-buffer-v1" false)
|
||||||
protocolnew("staging/security-context" "security-context-v1" false)
|
protocolnew("staging/security-context" "security-context-v1" false)
|
||||||
|
protocolnew("staging/content-type" "content-type-v1" false)
|
||||||
|
|
||||||
protocolwayland()
|
protocolwayland()
|
||||||
|
|
||||||
|
@ -36,7 +36,11 @@ hyprcursor = dependency('hyprcursor', version: '>=0.1.7')
|
|||||||
hyprgraphics = dependency('hyprgraphics', version: '>= 0.1.1')
|
hyprgraphics = dependency('hyprgraphics', version: '>= 0.1.1')
|
||||||
hyprlang = dependency('hyprlang', version: '>= 0.3.2')
|
hyprlang = dependency('hyprlang', version: '>= 0.3.2')
|
||||||
hyprutils = dependency('hyprutils', version: '>= 0.2.3')
|
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="@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(['-DHYPRCURSOR_VERSION="@0@"'.format(hyprcursor.version())], language: 'cpp')
|
||||||
add_project_arguments(['-DHYPRGRAPHICS_VERSION="@0@"'.format(hyprgraphics.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')
|
add_project_arguments(['-DHYPRLANG_VERSION="@0@"'.format(hyprlang.version())], language: 'cpp')
|
||||||
|
@ -70,6 +70,7 @@ protocols = [
|
|||||||
wayland_protocol_dir / 'staging/xdg-dialog/xdg-dialog-v1.xml',
|
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/single-pixel-buffer/single-pixel-buffer-v1.xml',
|
||||||
wayland_protocol_dir / 'staging/security-context/security-context-v1.xml',
|
wayland_protocol_dir / 'staging/security-context/security-context-v1.xml',
|
||||||
|
wayland_protocol_dir / 'staging/content-type/content-type-v1.xml',
|
||||||
]
|
]
|
||||||
|
|
||||||
wl_protocols = []
|
wl_protocols = []
|
||||||
|
@ -72,6 +72,7 @@
|
|||||||
|
|
||||||
using namespace Hyprutils::String;
|
using namespace Hyprutils::String;
|
||||||
using namespace Aquamarine;
|
using namespace Aquamarine;
|
||||||
|
using enum NContentType::eContentType;
|
||||||
|
|
||||||
static int handleCritSignal(int signo, void* data) {
|
static int handleCritSignal(int signo, void* data) {
|
||||||
Debug::log(LOG, "Hyprland received signal {}", signo);
|
Debug::log(LOG, "Hyprland received signal {}", signo);
|
||||||
@ -2323,7 +2324,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.
|
// send a scanout tranche if we are entering fullscreen, and send a regular one if we aren't.
|
||||||
// ignore if DS is disabled.
|
// 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_pHyprRenderer->setSurfaceScanoutMode(PWINDOW->m_pWLSurface->resource(), EFFECTIVE_MODE != FSMODE_NONE ? PMONITOR->self.lock() : nullptr);
|
||||||
|
|
||||||
g_pConfigManager->ensureVRR(PMONITOR);
|
g_pConfigManager->ensureVRR(PMONITOR);
|
||||||
|
@ -1314,9 +1314,9 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "render:direct_scanout",
|
.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 "
|
.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.",
|
"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_BOOL,
|
.type = CONFIG_OPTION_INT,
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
.data = SConfigOptionDescription::SRangeData{.value = 0, .min = 0, .max = 2},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "render:expand_undersized_textures",
|
.value = "render:expand_undersized_textures",
|
||||||
@ -1362,9 +1362,10 @@ inline static const std::vector<SConfigOptionDescription> CONFIG_OPTIONS = {
|
|||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "cursor:no_break_fs_vrr",
|
.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)",
|
.description = "disables scheduling new frames on cursor movement for fullscreen apps with VRR enabled to avoid framerate spikes (may require no_hardware_cursors = true) "
|
||||||
.type = CONFIG_OPTION_BOOL,
|
"0 - off, 1 - on, 2 - auto (on with content type 'game')",
|
||||||
.data = SConfigOptionDescription::SBoolData{false},
|
.type = CONFIG_OPTION_INT,
|
||||||
|
.data = SConfigOptionDescription::SRangeData{.value = 2, .min = 0, .max = 2},
|
||||||
},
|
},
|
||||||
SConfigOptionDescription{
|
SConfigOptionDescription{
|
||||||
.value = "cursor:min_refresh_rate",
|
.value = "cursor:min_refresh_rate",
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "../plugins/PluginSystem.hpp"
|
#include "../plugins/PluginSystem.hpp"
|
||||||
|
|
||||||
#include "managers/HookSystemManager.hpp"
|
#include "managers/HookSystemManager.hpp"
|
||||||
|
#include "protocols/types/ContentType.hpp"
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <hyprutils/path/Path.hpp>
|
#include <hyprutils/path/Path.hpp>
|
||||||
@ -621,7 +622,7 @@ CConfigManager::CConfigManager() {
|
|||||||
m_pConfig->addConfigValue("opengl:nvidia_anti_flicker", Hyprlang::INT{1});
|
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_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:min_refresh_rate", Hyprlang::INT{24});
|
||||||
m_pConfig->addConfigValue("cursor:hotspot_padding", Hyprlang::INT{0});
|
m_pConfig->addConfigValue("cursor:hotspot_padding", Hyprlang::INT{0});
|
||||||
m_pConfig->addConfigValue("cursor:inactive_timeout", {0.f});
|
m_pConfig->addConfigValue("cursor:inactive_timeout", {0.f});
|
||||||
@ -1347,6 +1348,14 @@ std::vector<SP<CWindowRule>> CConfigManager::getMatchingRules(PHLWINDOW pWindow,
|
|||||||
continue;
|
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()) {
|
if (!rule->szWorkspace.empty()) {
|
||||||
const auto PWORKSPACE = pWindow->m_pWorkspace;
|
const auto PWORKSPACE = pWindow->m_pWorkspace;
|
||||||
|
|
||||||
@ -2361,6 +2370,7 @@ std::optional<std::string> CConfigManager::handleWindowRuleV2(const std::string&
|
|||||||
const auto FOCUSPOS = VALUE.find("focus:");
|
const auto FOCUSPOS = VALUE.find("focus:");
|
||||||
const auto FULLSCREENSTATEPOS = VALUE.find("fullscreenstate:");
|
const auto FULLSCREENSTATEPOS = VALUE.find("fullscreenstate:");
|
||||||
const auto ONWORKSPACEPOS = VALUE.find("onworkspace:");
|
const auto ONWORKSPACEPOS = VALUE.find("onworkspace:");
|
||||||
|
const auto CONTENTTYPEPOS = VALUE.find("content:");
|
||||||
|
|
||||||
// find workspacepos that isn't onworkspacepos
|
// find workspacepos that isn't onworkspacepos
|
||||||
size_t WORKSPACEPOS = std::string::npos;
|
size_t WORKSPACEPOS = std::string::npos;
|
||||||
@ -2373,8 +2383,8 @@ std::optional<std::string> CConfigManager::handleWindowRuleV2(const std::string&
|
|||||||
currentPos = VALUE.find("workspace:", currentPos + 1);
|
currentPos = VALUE.find("workspace:", currentPos + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto checkPos = std::unordered_set{TAGPOS, TITLEPOS, CLASSPOS, INITIALTITLEPOS, INITIALCLASSPOS, X11POS, FLOATPOS,
|
const auto checkPos = std::unordered_set{TAGPOS, TITLEPOS, CLASSPOS, INITIALTITLEPOS, INITIALCLASSPOS, X11POS, FLOATPOS,
|
||||||
FULLSCREENPOS, PINNEDPOS, FULLSCREENSTATEPOS, WORKSPACEPOS, FOCUSPOS, ONWORKSPACEPOS};
|
FULLSCREENPOS, PINNEDPOS, FULLSCREENSTATEPOS, WORKSPACEPOS, FOCUSPOS, ONWORKSPACEPOS, CONTENTTYPEPOS};
|
||||||
if (checkPos.size() == 1 && checkPos.contains(std::string::npos)) {
|
if (checkPos.size() == 1 && checkPos.contains(std::string::npos)) {
|
||||||
Debug::log(ERR, "Invalid rulev2 syntax: {}", VALUE);
|
Debug::log(ERR, "Invalid rulev2 syntax: {}", VALUE);
|
||||||
return "Invalid rulev2 syntax: " + VALUE;
|
return "Invalid rulev2 syntax: " + VALUE;
|
||||||
@ -2411,6 +2421,8 @@ std::optional<std::string> CConfigManager::handleWindowRuleV2(const std::string&
|
|||||||
min = WORKSPACEPOS;
|
min = WORKSPACEPOS;
|
||||||
if (FOCUSPOS > pos && FOCUSPOS < min)
|
if (FOCUSPOS > pos && FOCUSPOS < min)
|
||||||
min = FOCUSPOS;
|
min = FOCUSPOS;
|
||||||
|
if (CONTENTTYPEPOS > pos && CONTENTTYPEPOS < min)
|
||||||
|
min = CONTENTTYPEPOS;
|
||||||
|
|
||||||
result = result.substr(0, min - pos);
|
result = result.substr(0, min - pos);
|
||||||
|
|
||||||
@ -2469,6 +2481,9 @@ std::optional<std::string> CConfigManager::handleWindowRuleV2(const std::string&
|
|||||||
if (ONWORKSPACEPOS != std::string::npos)
|
if (ONWORKSPACEPOS != std::string::npos)
|
||||||
rule->szOnWorkspace = extract(ONWORKSPACEPOS + 12);
|
rule->szOnWorkspace = extract(ONWORKSPACEPOS + 12);
|
||||||
|
|
||||||
|
if (CONTENTTYPEPOS != std::string::npos)
|
||||||
|
rule->szContentType = extract(CONTENTTYPEPOS + 8);
|
||||||
|
|
||||||
if (RULE == "unset") {
|
if (RULE == "unset") {
|
||||||
std::erase_if(m_vWindowRules, [&](const auto& other) {
|
std::erase_if(m_vWindowRules, [&](const auto& other) {
|
||||||
if (!other->v2)
|
if (!other->v2)
|
||||||
@ -2513,6 +2528,9 @@ std::optional<std::string> CConfigManager::handleWindowRuleV2(const std::string&
|
|||||||
if (!rule->szOnWorkspace.empty() && rule->szOnWorkspace != other->szOnWorkspace)
|
if (!rule->szOnWorkspace.empty() && rule->szOnWorkspace != other->szOnWorkspace)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (!rule->szContentType.empty() && rule->szContentType != other->szContentType)
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "../managers/AnimationManager.hpp"
|
#include "../managers/AnimationManager.hpp"
|
||||||
#include "../protocols/XDGShell.hpp"
|
#include "../protocols/XDGShell.hpp"
|
||||||
#include "../protocols/core/Compositor.hpp"
|
#include "../protocols/core/Compositor.hpp"
|
||||||
|
#include "../protocols/ContentType.hpp"
|
||||||
#include "../xwayland/XWayland.hpp"
|
#include "../xwayland/XWayland.hpp"
|
||||||
#include "../helpers/Color.hpp"
|
#include "../helpers/Color.hpp"
|
||||||
#include "../events/Events.hpp"
|
#include "../events/Events.hpp"
|
||||||
@ -29,6 +30,7 @@
|
|||||||
|
|
||||||
using namespace Hyprutils::String;
|
using namespace Hyprutils::String;
|
||||||
using namespace Hyprutils::Animation;
|
using namespace Hyprutils::Animation;
|
||||||
|
using enum NContentType::eContentType;
|
||||||
|
|
||||||
PHLWINDOW CWindow::create(SP<CXWaylandSurface> surface) {
|
PHLWINDOW CWindow::create(SP<CXWaylandSurface> surface) {
|
||||||
PHLWINDOW pWindow = SP<CWindow>(new CWindow(surface));
|
PHLWINDOW pWindow = SP<CWindow>(new CWindow(surface));
|
||||||
@ -1724,3 +1726,16 @@ void CWindow::sendWindowSize(Vector2D size, bool force, std::optional<Vector2D>
|
|||||||
else if (m_pXDGSurface && m_pXDGSurface->toplevel)
|
else if (m_pXDGSurface && m_pXDGSurface->toplevel)
|
||||||
m_vPendingSizeAcks.emplace_back(m_pXDGSurface->toplevel->setSize(size), size.floor());
|
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;
|
||||||
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
#include "WLSurface.hpp"
|
#include "WLSurface.hpp"
|
||||||
#include "Workspace.hpp"
|
#include "Workspace.hpp"
|
||||||
#include "WindowRule.hpp"
|
#include "WindowRule.hpp"
|
||||||
|
#include "protocols/types/ContentType.hpp"
|
||||||
|
|
||||||
class CXDGSurfaceResource;
|
class CXDGSurfaceResource;
|
||||||
class CXWaylandSurface;
|
class CXWaylandSurface;
|
||||||
@ -393,85 +394,87 @@ class CWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// methods
|
// methods
|
||||||
CBox getFullWindowBoundingBox();
|
CBox getFullWindowBoundingBox();
|
||||||
SBoxExtents getFullWindowExtents();
|
SBoxExtents getFullWindowExtents();
|
||||||
CBox getWindowBoxUnified(uint64_t props);
|
CBox getWindowBoxUnified(uint64_t props);
|
||||||
CBox getWindowIdealBoundingBoxIgnoreReserved();
|
CBox getWindowIdealBoundingBoxIgnoreReserved();
|
||||||
void addWindowDeco(UP<IHyprWindowDecoration> deco);
|
void addWindowDeco(UP<IHyprWindowDecoration> deco);
|
||||||
void updateWindowDecos();
|
void updateWindowDecos();
|
||||||
void removeWindowDeco(IHyprWindowDecoration* deco);
|
void removeWindowDeco(IHyprWindowDecoration* deco);
|
||||||
void uncacheWindowDecos();
|
void uncacheWindowDecos();
|
||||||
bool checkInputOnDecos(const eInputType, const Vector2D&, std::any = {});
|
bool checkInputOnDecos(const eInputType, const Vector2D&, std::any = {});
|
||||||
pid_t getPID();
|
pid_t getPID();
|
||||||
IHyprWindowDecoration* getDecorationByType(eDecorationType);
|
IHyprWindowDecoration* getDecorationByType(eDecorationType);
|
||||||
void updateToplevel();
|
void updateToplevel();
|
||||||
void updateSurfaceScaleTransformDetails(bool force = false);
|
void updateSurfaceScaleTransformDetails(bool force = false);
|
||||||
void moveToWorkspace(PHLWORKSPACE);
|
void moveToWorkspace(PHLWORKSPACE);
|
||||||
PHLWINDOW x11TransientFor();
|
PHLWINDOW x11TransientFor();
|
||||||
void onUnmap();
|
void onUnmap();
|
||||||
void onMap();
|
void onMap();
|
||||||
void setHidden(bool hidden);
|
void setHidden(bool hidden);
|
||||||
bool isHidden();
|
bool isHidden();
|
||||||
void applyDynamicRule(const SP<CWindowRule>& r);
|
void applyDynamicRule(const SP<CWindowRule>& r);
|
||||||
void updateDynamicRules();
|
void updateDynamicRules();
|
||||||
SBoxExtents getFullWindowReservedArea();
|
SBoxExtents getFullWindowReservedArea();
|
||||||
Vector2D middle();
|
Vector2D middle();
|
||||||
bool opaque();
|
bool opaque();
|
||||||
float rounding();
|
float rounding();
|
||||||
float roundingPower();
|
float roundingPower();
|
||||||
bool canBeTorn();
|
bool canBeTorn();
|
||||||
void setSuspended(bool suspend);
|
void setSuspended(bool suspend);
|
||||||
bool visibleOnMonitor(PHLMONITOR pMonitor);
|
bool visibleOnMonitor(PHLMONITOR pMonitor);
|
||||||
WORKSPACEID workspaceID();
|
WORKSPACEID workspaceID();
|
||||||
MONITORID monitorID();
|
MONITORID monitorID();
|
||||||
bool onSpecialWorkspace();
|
bool onSpecialWorkspace();
|
||||||
void activate(bool force = false);
|
void activate(bool force = false);
|
||||||
int surfacesCount();
|
int surfacesCount();
|
||||||
void clampWindowSize(const std::optional<Vector2D> minSize, const std::optional<Vector2D> maxSize);
|
void clampWindowSize(const std::optional<Vector2D> minSize, const std::optional<Vector2D> maxSize);
|
||||||
bool isFullscreen();
|
bool isFullscreen();
|
||||||
bool isEffectiveInternalFSMode(const eFullscreenMode);
|
bool isEffectiveInternalFSMode(const eFullscreenMode);
|
||||||
int getRealBorderSize();
|
int getRealBorderSize();
|
||||||
float getScrollMouse();
|
float getScrollMouse();
|
||||||
float getScrollTouchpad();
|
float getScrollTouchpad();
|
||||||
void updateWindowData();
|
void updateWindowData();
|
||||||
void updateWindowData(const struct SWorkspaceRule&);
|
void updateWindowData(const struct SWorkspaceRule&);
|
||||||
void onBorderAngleAnimEnd(WP<Hyprutils::Animation::CBaseAnimatedVariable> pav);
|
void onBorderAngleAnimEnd(WP<Hyprutils::Animation::CBaseAnimatedVariable> pav);
|
||||||
bool isInCurvedCorner(double x, double y);
|
bool isInCurvedCorner(double x, double y);
|
||||||
bool hasPopupAt(const Vector2D& pos);
|
bool hasPopupAt(const Vector2D& pos);
|
||||||
int popupsCount();
|
int popupsCount();
|
||||||
void applyGroupRules();
|
void applyGroupRules();
|
||||||
void createGroup();
|
void createGroup();
|
||||||
void destroyGroup();
|
void destroyGroup();
|
||||||
PHLWINDOW getGroupHead();
|
PHLWINDOW getGroupHead();
|
||||||
PHLWINDOW getGroupTail();
|
PHLWINDOW getGroupTail();
|
||||||
PHLWINDOW getGroupCurrent();
|
PHLWINDOW getGroupCurrent();
|
||||||
PHLWINDOW getGroupPrevious();
|
PHLWINDOW getGroupPrevious();
|
||||||
PHLWINDOW getGroupWindowByIndex(int);
|
PHLWINDOW getGroupWindowByIndex(int);
|
||||||
int getGroupSize();
|
int getGroupSize();
|
||||||
bool canBeGroupedInto(PHLWINDOW pWindow);
|
bool canBeGroupedInto(PHLWINDOW pWindow);
|
||||||
void setGroupCurrent(PHLWINDOW pWindow);
|
void setGroupCurrent(PHLWINDOW pWindow);
|
||||||
void insertWindowToGroup(PHLWINDOW pWindow);
|
void insertWindowToGroup(PHLWINDOW pWindow);
|
||||||
void updateGroupOutputs();
|
void updateGroupOutputs();
|
||||||
void switchWithWindowInGroup(PHLWINDOW pWindow);
|
void switchWithWindowInGroup(PHLWINDOW pWindow);
|
||||||
void setAnimationsToMove();
|
void setAnimationsToMove();
|
||||||
void onWorkspaceAnimUpdate();
|
void onWorkspaceAnimUpdate();
|
||||||
void onFocusAnimUpdate();
|
void onFocusAnimUpdate();
|
||||||
void onUpdateState();
|
void onUpdateState();
|
||||||
void onUpdateMeta();
|
void onUpdateMeta();
|
||||||
void onX11Configure(CBox box);
|
void onX11Configure(CBox box);
|
||||||
void onResourceChangeX11();
|
void onResourceChangeX11();
|
||||||
std::string fetchTitle();
|
std::string fetchTitle();
|
||||||
std::string fetchClass();
|
std::string fetchClass();
|
||||||
void warpCursor(bool force = false);
|
void warpCursor(bool force = false);
|
||||||
PHLWINDOW getSwallower();
|
PHLWINDOW getSwallower();
|
||||||
void unsetWindowData(eOverridePriority priority);
|
void unsetWindowData(eOverridePriority priority);
|
||||||
bool isX11OverrideRedirect();
|
bool isX11OverrideRedirect();
|
||||||
bool isModal();
|
bool isModal();
|
||||||
Vector2D requestedMinSize();
|
Vector2D requestedMinSize();
|
||||||
Vector2D requestedMaxSize();
|
Vector2D requestedMaxSize();
|
||||||
void sendWindowSize(Vector2D size, bool force = false, std::optional<Vector2D> overridePos = std::nullopt);
|
void sendWindowSize(Vector2D size, bool force = false, std::optional<Vector2D> overridePos = std::nullopt);
|
||||||
|
NContentType::eContentType getContentType();
|
||||||
|
void setContentType(NContentType::eContentType contentType);
|
||||||
|
|
||||||
CBox getWindowMainSurfaceBox() const {
|
CBox getWindowMainSurfaceBox() const {
|
||||||
return {m_vRealPosition->value().x, m_vRealPosition->value().y, m_vRealSize->value().x, m_vRealSize->value().y};
|
return {m_vRealPosition->value().x, m_vRealPosition->value().y, m_vRealSize->value().x, m_vRealSize->value().y};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,8 +8,9 @@ static const auto RULES = std::unordered_set<std::string>{
|
|||||||
"float", "fullscreen", "maximize", "noinitialfocus", "pin", "stayfocused", "tile", "renderunfocused",
|
"float", "fullscreen", "maximize", "noinitialfocus", "pin", "stayfocused", "tile", "renderunfocused",
|
||||||
};
|
};
|
||||||
static const auto RULES_PREFIX = std::unordered_set<std::string>{
|
static const auto RULES_PREFIX = std::unordered_set<std::string>{
|
||||||
"animation", "bordercolor", "bordersize", "center", "fullscreenstate", "group", "idleinhibit", "maxsize", "minsize", "monitor", "move", "opacity",
|
"animation", "bordercolor", "bordersize", "center", "content", "fullscreenstate", "group", "idleinhibit", "maxsize", "minsize",
|
||||||
"plugin:", "prop", "pseudo", "rounding", "roundingpower", "scrollmouse", "scrolltouchpad", "size", "suppressevent", "tag", "workspace", "xray",
|
"monitor", "move", "opacity", "plugin:", "prop", "pseudo", "rounding", "roundingpower", "scrollmouse", "scrolltouchpad",
|
||||||
|
"size", "suppressevent", "tag", "workspace", "xray",
|
||||||
};
|
};
|
||||||
|
|
||||||
CWindowRule::CWindowRule(const std::string& rule, const std::string& value, bool isV2, bool isExecRule) : szValue(value), szRule(rule), v2(isV2), execRule(isExecRule) {
|
CWindowRule::CWindowRule(const std::string& rule, const std::string& value, bool isV2, bool isExecRule) : szValue(value), szRule(rule), v2(isV2), execRule(isExecRule) {
|
||||||
@ -74,6 +75,8 @@ CWindowRule::CWindowRule(const std::string& rule, const std::string& value, bool
|
|||||||
ruleType = RULE_WORKSPACE;
|
ruleType = RULE_WORKSPACE;
|
||||||
else if (rule.starts_with("prop"))
|
else if (rule.starts_with("prop"))
|
||||||
ruleType = RULE_PROP;
|
ruleType = RULE_PROP;
|
||||||
|
else if (rule.starts_with("content"))
|
||||||
|
ruleType = RULE_CONTENT;
|
||||||
else {
|
else {
|
||||||
// check if this is a prop.
|
// check if this is a prop.
|
||||||
const CVarList VARS(rule, 0, 's', true);
|
const CVarList VARS(rule, 0, 's', true);
|
||||||
|
@ -36,6 +36,7 @@ class CWindowRule {
|
|||||||
RULE_TAG,
|
RULE_TAG,
|
||||||
RULE_WORKSPACE,
|
RULE_WORKSPACE,
|
||||||
RULE_PROP,
|
RULE_PROP,
|
||||||
|
RULE_CONTENT,
|
||||||
};
|
};
|
||||||
|
|
||||||
eRuleType ruleType = RULE_INVALID;
|
eRuleType ruleType = RULE_INVALID;
|
||||||
@ -58,6 +59,7 @@ class CWindowRule {
|
|||||||
std::string szFullscreenState = ""; // empty means any
|
std::string szFullscreenState = ""; // empty means any
|
||||||
std::string szOnWorkspace = ""; // empty means any
|
std::string szOnWorkspace = ""; // empty means any
|
||||||
std::string szWorkspace = ""; // empty means any
|
std::string szWorkspace = ""; // empty means any
|
||||||
|
std::string szContentType = ""; // empty means any
|
||||||
|
|
||||||
// precompiled regexes
|
// precompiled regexes
|
||||||
CRuleRegexContainer rTitle;
|
CRuleRegexContainer rTitle;
|
||||||
|
@ -11,11 +11,11 @@
|
|||||||
#include "../protocols/XDGShell.hpp"
|
#include "../protocols/XDGShell.hpp"
|
||||||
#include "../protocols/core/Compositor.hpp"
|
#include "../protocols/core/Compositor.hpp"
|
||||||
#include "../protocols/ToplevelExport.hpp"
|
#include "../protocols/ToplevelExport.hpp"
|
||||||
|
#include "protocols/types/ContentType.hpp"
|
||||||
#include "../xwayland/XSurface.hpp"
|
#include "../xwayland/XSurface.hpp"
|
||||||
#include "managers/AnimationManager.hpp"
|
#include "managers/AnimationManager.hpp"
|
||||||
#include "managers/PointerManager.hpp"
|
#include "managers/PointerManager.hpp"
|
||||||
#include "../desktop/LayerSurface.hpp"
|
#include "../desktop/LayerSurface.hpp"
|
||||||
#include "../managers/input/InputManager.hpp"
|
|
||||||
#include "../managers/LayoutManager.hpp"
|
#include "../managers/LayoutManager.hpp"
|
||||||
#include "../managers/EventManager.hpp"
|
#include "../managers/EventManager.hpp"
|
||||||
#include "../managers/AnimationManager.hpp"
|
#include "../managers/AnimationManager.hpp"
|
||||||
@ -307,6 +307,13 @@ void Events::listener_mapWindow(void* owner, void* data) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case CWindowRule::RULE_CONTENT: {
|
||||||
|
const CVarList VARS(r->szRule, 0, ' ');
|
||||||
|
try {
|
||||||
|
PWINDOW->setContentType(NContentType::fromString(VARS[1]));
|
||||||
|
} catch (std::exception& e) { Debug::log(ERR, "Rule \"{}\" failed with: {}", r->szRule, e.what()); }
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
using namespace Hyprutils::String;
|
using namespace Hyprutils::String;
|
||||||
using namespace Hyprutils::Utils;
|
using namespace Hyprutils::Utils;
|
||||||
using namespace Hyprutils::OS;
|
using namespace Hyprutils::OS;
|
||||||
|
using enum NContentType::eContentType;
|
||||||
|
|
||||||
static int ratHandler(void* data) {
|
static int ratHandler(void* data) {
|
||||||
g_pHyprRenderer->renderMonitor(((CMonitor*)data)->self.lock());
|
g_pHyprRenderer->renderMonitor(((CMonitor*)data)->self.lock());
|
||||||
@ -799,8 +800,8 @@ bool CMonitor::shouldSkipScheduleFrameOnMouseEvent() {
|
|||||||
static auto PMINRR = CConfigValue<Hyprlang::INT>("cursor:min_refresh_rate");
|
static auto PMINRR = CConfigValue<Hyprlang::INT>("cursor:min_refresh_rate");
|
||||||
|
|
||||||
// skip scheduling extra frames for fullsreen apps with vrr
|
// skip scheduling extra frames for fullsreen apps with vrr
|
||||||
bool shouldSkip =
|
const bool shouldSkip = activeWorkspace && activeWorkspace->m_bHasFullscreenWindow && activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN &&
|
||||||
*PNOBREAK && output->state->state().adaptiveSync && activeWorkspace && activeWorkspace->m_bHasFullscreenWindow && activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN;
|
(*PNOBREAK == 1 || (*PNOBREAK == 2 && activeWorkspace->getFullscreenWindow()->getContentType() == CONTENT_TYPE_GAME)) && output->state->state().adaptiveSync;
|
||||||
|
|
||||||
// keep requested minimum refresh rate
|
// keep requested minimum refresh rate
|
||||||
if (shouldSkip && *PMINRR && lastPresentationTimer.getMillis() > 1000.0f / *PMINRR) {
|
if (shouldSkip && *PMINRR && lastPresentationTimer.getMillis() > 1000.0f / *PMINRR) {
|
||||||
|
@ -111,6 +111,7 @@
|
|||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define AQUAMARINE_VERSION_NUMBER (AQUAMARINE_VERSION_MAJOR * 10000 + AQUAMARINE_VERSION_MINOR * 100 + AQUAMARINE_VERSION_PATCH)
|
||||||
#define AQUAMARINE_FORWARD(name) \
|
#define AQUAMARINE_FORWARD(name) \
|
||||||
namespace Aquamarine { \
|
namespace Aquamarine { \
|
||||||
class name; \
|
class name; \
|
||||||
|
@ -58,10 +58,12 @@
|
|||||||
#include "../protocols/core/Shm.hpp"
|
#include "../protocols/core/Shm.hpp"
|
||||||
#include "../protocols/ColorManagement.hpp"
|
#include "../protocols/ColorManagement.hpp"
|
||||||
#include "../protocols/FrogColorManagement.hpp"
|
#include "../protocols/FrogColorManagement.hpp"
|
||||||
|
#include "../protocols/ContentType.hpp"
|
||||||
|
|
||||||
#include "../helpers/Monitor.hpp"
|
#include "../helpers/Monitor.hpp"
|
||||||
#include "../render/Renderer.hpp"
|
#include "../render/Renderer.hpp"
|
||||||
#include "../Compositor.hpp"
|
#include "../Compositor.hpp"
|
||||||
|
#include "content-type-v1.hpp"
|
||||||
|
|
||||||
#include <aquamarine/buffer/Buffer.hpp>
|
#include <aquamarine/buffer/Buffer.hpp>
|
||||||
#include <aquamarine/backend/Backend.hpp>
|
#include <aquamarine/backend/Backend.hpp>
|
||||||
@ -169,6 +171,7 @@ CProtocolManager::CProtocolManager() {
|
|||||||
PROTO::securityContext = makeUnique<CSecurityContextProtocol>(&wp_security_context_manager_v1_interface, 1, "SecurityContext");
|
PROTO::securityContext = makeUnique<CSecurityContextProtocol>(&wp_security_context_manager_v1_interface, 1, "SecurityContext");
|
||||||
PROTO::ctm = makeUnique<CHyprlandCTMControlProtocol>(&hyprland_ctm_control_manager_v1_interface, 2, "CTMControl");
|
PROTO::ctm = makeUnique<CHyprlandCTMControlProtocol>(&hyprland_ctm_control_manager_v1_interface, 2, "CTMControl");
|
||||||
PROTO::hyprlandSurface = makeUnique<CHyprlandSurfaceProtocol>(&hyprland_surface_manager_v1_interface, 2, "HyprlandSurface");
|
PROTO::hyprlandSurface = makeUnique<CHyprlandSurfaceProtocol>(&hyprland_surface_manager_v1_interface, 2, "HyprlandSurface");
|
||||||
|
PROTO::contentType = makeUnique<CContentTypeProtocol>(&wp_content_type_manager_v1_interface, 1, "ContentType");
|
||||||
|
|
||||||
if (*PENABLEXXCM) {
|
if (*PENABLEXXCM) {
|
||||||
PROTO::colorManagement = makeUnique<CColorManagementProtocol>(&xx_color_manager_v4_interface, 1, "ColorManagement");
|
PROTO::colorManagement = makeUnique<CColorManagementProtocol>(&xx_color_manager_v4_interface, 1, "ColorManagement");
|
||||||
|
95
src/protocols/ContentType.cpp
Normal file
95
src/protocols/ContentType.cpp
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
#include "ContentType.hpp"
|
||||||
|
#include "content-type-v1.hpp"
|
||||||
|
#include "protocols/types/ContentType.hpp"
|
||||||
|
|
||||||
|
CContentTypeManager::CContentTypeManager(SP<CWpContentTypeManagerV1> resource) : m_resource(resource) {
|
||||||
|
if UNLIKELY (!good())
|
||||||
|
return;
|
||||||
|
|
||||||
|
resource->setDestroy([](CWpContentTypeManagerV1* r) {});
|
||||||
|
resource->setOnDestroy([this](CWpContentTypeManagerV1* r) { PROTO::contentType->destroyResource(this); });
|
||||||
|
|
||||||
|
resource->setGetSurfaceContentType([](CWpContentTypeManagerV1* r, uint32_t id, wl_resource* surface) {
|
||||||
|
LOGM(TRACE, "Get surface for id={}, surface={}", id, (uintptr_t)surface);
|
||||||
|
auto SURF = CWLSurfaceResource::fromResource(surface);
|
||||||
|
|
||||||
|
if (!SURF) {
|
||||||
|
LOGM(ERR, "No surface for resource {}", (uintptr_t)surface);
|
||||||
|
r->error(-1, "Invalid surface (2)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SURF->colorManagement) {
|
||||||
|
r->error(WP_CONTENT_TYPE_MANAGER_V1_ERROR_ALREADY_CONSTRUCTED, "CT manager already exists");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto RESOURCE = PROTO::contentType->m_vContentTypes.emplace_back(makeShared<CContentType>(makeShared<CWpContentTypeV1>(r->client(), r->version(), id)));
|
||||||
|
if UNLIKELY (!RESOURCE->good()) {
|
||||||
|
r->noMemory();
|
||||||
|
PROTO::contentType->m_vContentTypes.pop_back();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
RESOURCE->self = RESOURCE;
|
||||||
|
|
||||||
|
SURF->contentType = RESOURCE;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CContentTypeManager::good() {
|
||||||
|
return m_resource->resource();
|
||||||
|
}
|
||||||
|
|
||||||
|
CContentType::CContentType(WP<CWLSurfaceResource> surface) {
|
||||||
|
destroy = surface->events.destroy.registerListener([this](std::any d) { PROTO::contentType->destroyResource(this); });
|
||||||
|
}
|
||||||
|
|
||||||
|
CContentType::CContentType(SP<CWpContentTypeV1> resource) : m_resource(resource) {
|
||||||
|
if UNLIKELY (!good())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_pClient = resource->client();
|
||||||
|
|
||||||
|
resource->setDestroy([this](CWpContentTypeV1* r) { PROTO::contentType->destroyResource(this); });
|
||||||
|
resource->setOnDestroy([this](CWpContentTypeV1* r) { PROTO::contentType->destroyResource(this); });
|
||||||
|
|
||||||
|
resource->setSetContentType([this](CWpContentTypeV1* r, wpContentTypeV1Type type) { value = NContentType::fromWP(type); });
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CContentType::good() {
|
||||||
|
return m_resource && m_resource->resource();
|
||||||
|
}
|
||||||
|
|
||||||
|
wl_client* CContentType::client() {
|
||||||
|
return m_pClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
CContentTypeProtocol::CContentTypeProtocol(const wl_interface* iface, const int& ver, const std::string& name) : IWaylandProtocol(iface, ver, name) {
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CContentTypeProtocol::bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id) {
|
||||||
|
const auto RESOURCE = m_vManagers.emplace_back(makeShared<CContentTypeManager>(makeShared<CWpContentTypeManagerV1>(client, ver, id)));
|
||||||
|
|
||||||
|
if UNLIKELY (!RESOURCE->good()) {
|
||||||
|
wl_client_post_no_memory(client);
|
||||||
|
m_vManagers.pop_back();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SP<CContentType> CContentTypeProtocol::getContentType(WP<CWLSurfaceResource> surface) {
|
||||||
|
if (surface->contentType.valid())
|
||||||
|
return surface->contentType.lock();
|
||||||
|
|
||||||
|
return m_vContentTypes.emplace_back(makeShared<CContentType>(surface));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CContentTypeProtocol::destroyResource(CContentTypeManager* resource) {
|
||||||
|
std::erase_if(m_vManagers, [&](const auto& other) { return other.get() == resource; });
|
||||||
|
}
|
||||||
|
|
||||||
|
void CContentTypeProtocol::destroyResource(CContentType* resource) {
|
||||||
|
std::erase_if(m_vContentTypes, [&](const auto& other) { return other.get() == resource; });
|
||||||
|
}
|
59
src/protocols/ContentType.hpp
Normal file
59
src/protocols/ContentType.hpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "WaylandProtocol.hpp"
|
||||||
|
#include "core/Compositor.hpp"
|
||||||
|
#include "content-type-v1.hpp"
|
||||||
|
#include "protocols/types/ContentType.hpp"
|
||||||
|
|
||||||
|
class CContentTypeManager {
|
||||||
|
public:
|
||||||
|
CContentTypeManager(SP<CWpContentTypeManagerV1> resource);
|
||||||
|
|
||||||
|
bool good();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SP<CWpContentTypeManagerV1> m_resource;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CContentType {
|
||||||
|
public:
|
||||||
|
CContentType(SP<CWpContentTypeV1> resource);
|
||||||
|
CContentType(WP<CWLSurfaceResource> surface);
|
||||||
|
|
||||||
|
bool good();
|
||||||
|
wl_client* client();
|
||||||
|
NContentType::eContentType value = NContentType::CONTENT_TYPE_NONE;
|
||||||
|
|
||||||
|
WP<CContentType> self;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SP<CWpContentTypeV1> m_resource;
|
||||||
|
wl_client* m_pClient = nullptr;
|
||||||
|
|
||||||
|
CHyprSignalListener destroy;
|
||||||
|
|
||||||
|
friend class CContentTypeProtocol;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CContentTypeProtocol : public IWaylandProtocol {
|
||||||
|
public:
|
||||||
|
CContentTypeProtocol(const wl_interface* iface, const int& ver, const std::string& name);
|
||||||
|
|
||||||
|
virtual void bindManager(wl_client* client, void* data, uint32_t ver, uint32_t id);
|
||||||
|
|
||||||
|
SP<CContentType> getContentType(WP<CWLSurfaceResource> surface);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void destroyResource(CContentTypeManager* resource);
|
||||||
|
void destroyResource(CContentType* resource);
|
||||||
|
|
||||||
|
std::vector<SP<CContentTypeManager>> m_vManagers;
|
||||||
|
std::vector<SP<CContentType>> m_vContentTypes;
|
||||||
|
|
||||||
|
friend class CContentTypeManager;
|
||||||
|
friend class CContentType;
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace PROTO {
|
||||||
|
inline UP<CContentTypeProtocol> contentType;
|
||||||
|
};
|
@ -26,6 +26,7 @@ class CViewportResource;
|
|||||||
class CDRMSyncobjSurfaceResource;
|
class CDRMSyncobjSurfaceResource;
|
||||||
class CColorManagementSurface;
|
class CColorManagementSurface;
|
||||||
class CFrogColorManagementSurface;
|
class CFrogColorManagementSurface;
|
||||||
|
class CContentType;
|
||||||
|
|
||||||
class CWLCallbackResource {
|
class CWLCallbackResource {
|
||||||
public:
|
public:
|
||||||
@ -123,6 +124,7 @@ class CWLSurfaceResource {
|
|||||||
WP<CViewportResource> viewportResource;
|
WP<CViewportResource> viewportResource;
|
||||||
WP<CDRMSyncobjSurfaceResource> syncobj; // may not be present
|
WP<CDRMSyncobjSurfaceResource> syncobj; // may not be present
|
||||||
WP<CColorManagementSurface> colorManagement;
|
WP<CColorManagementSurface> colorManagement;
|
||||||
|
WP<CContentType> contentType;
|
||||||
|
|
||||||
void breadthfirst(std::function<void(SP<CWLSurfaceResource>, const Vector2D&, void*)> fn, void* data);
|
void breadthfirst(std::function<void(SP<CWLSurfaceResource>, const Vector2D&, void*)> fn, void* data);
|
||||||
CRegion accumulateCurrentBufferDamage();
|
CRegion accumulateCurrentBufferDamage();
|
||||||
|
37
src/protocols/types/ContentType.cpp
Normal file
37
src/protocols/types/ContentType.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#include "ContentType.hpp"
|
||||||
|
#include <drm_mode.h>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <format>
|
||||||
|
|
||||||
|
namespace NContentType {
|
||||||
|
static std::unordered_map<std::string, eContentType> const table = {
|
||||||
|
{"none", CONTENT_TYPE_NONE}, {"photo", CONTENT_TYPE_PHOTO}, {"video", CONTENT_TYPE_VIDEO}, {"game", CONTENT_TYPE_GAME}};
|
||||||
|
|
||||||
|
eContentType fromString(const std::string name) {
|
||||||
|
auto it = table.find(name);
|
||||||
|
if (it != table.end())
|
||||||
|
return it->second;
|
||||||
|
else
|
||||||
|
throw std::invalid_argument(std::format("Unknown content type {}", name));
|
||||||
|
}
|
||||||
|
|
||||||
|
eContentType fromWP(wpContentTypeV1Type contentType) {
|
||||||
|
switch (contentType) {
|
||||||
|
case WP_CONTENT_TYPE_V1_TYPE_NONE: return CONTENT_TYPE_NONE;
|
||||||
|
case WP_CONTENT_TYPE_V1_TYPE_PHOTO: return CONTENT_TYPE_PHOTO;
|
||||||
|
case WP_CONTENT_TYPE_V1_TYPE_VIDEO: return CONTENT_TYPE_VIDEO;
|
||||||
|
case WP_CONTENT_TYPE_V1_TYPE_GAME: return CONTENT_TYPE_GAME;
|
||||||
|
default: return CONTENT_TYPE_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t toDRM(eContentType contentType) {
|
||||||
|
switch (contentType) {
|
||||||
|
case CONTENT_TYPE_NONE: return DRM_MODE_CONTENT_TYPE_GRAPHICS;
|
||||||
|
case CONTENT_TYPE_PHOTO: return DRM_MODE_CONTENT_TYPE_PHOTO;
|
||||||
|
case CONTENT_TYPE_VIDEO: return DRM_MODE_CONTENT_TYPE_CINEMA;
|
||||||
|
case CONTENT_TYPE_GAME: return DRM_MODE_CONTENT_TYPE_GAME;
|
||||||
|
default: return DRM_MODE_CONTENT_TYPE_NO_DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
src/protocols/types/ContentType.hpp
Normal file
18
src/protocols/types/ContentType.hpp
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "content-type-v1.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace NContentType {
|
||||||
|
|
||||||
|
enum eContentType : uint8_t {
|
||||||
|
CONTENT_TYPE_NONE = 0,
|
||||||
|
CONTENT_TYPE_PHOTO = 1,
|
||||||
|
CONTENT_TYPE_VIDEO = 2,
|
||||||
|
CONTENT_TYPE_GAME = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
eContentType fromString(const std::string name);
|
||||||
|
eContentType fromWP(wpContentTypeV1Type contentType);
|
||||||
|
uint16_t toDRM(eContentType contentType);
|
||||||
|
}
|
@ -33,10 +33,14 @@
|
|||||||
#include "pass/SurfacePassElement.hpp"
|
#include "pass/SurfacePassElement.hpp"
|
||||||
#include "debug/Log.hpp"
|
#include "debug/Log.hpp"
|
||||||
#include "protocols/ColorManagement.hpp"
|
#include "protocols/ColorManagement.hpp"
|
||||||
|
#if AQUAMARINE_VERSION_NUMBER > 702 // >0.7.2
|
||||||
|
#include "protocols/types/ContentType.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <hyprutils/utils/ScopeGuard.hpp>
|
#include <hyprutils/utils/ScopeGuard.hpp>
|
||||||
using namespace Hyprutils::Utils;
|
using namespace Hyprutils::Utils;
|
||||||
using namespace Hyprutils::OS;
|
using namespace Hyprutils::OS;
|
||||||
|
using enum NContentType::eContentType;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <xf86drm.h>
|
#include <xf86drm.h>
|
||||||
@ -1192,7 +1196,7 @@ void CHyprRenderer::renderMonitor(PHLMONITOR pMonitor) {
|
|||||||
|
|
||||||
pMonitor->tearingState.activelyTearing = shouldTear;
|
pMonitor->tearingState.activelyTearing = shouldTear;
|
||||||
|
|
||||||
if (*PDIRECTSCANOUT && !shouldTear) {
|
if ((*PDIRECTSCANOUT == 1 || (*PDIRECTSCANOUT == 2 && pMonitor->activeWorkspace->getFullscreenWindow()->getContentType() == CONTENT_TYPE_GAME)) && !shouldTear) {
|
||||||
if (pMonitor->attemptDirectScanout()) {
|
if (pMonitor->attemptDirectScanout()) {
|
||||||
return;
|
return;
|
||||||
} else if (!pMonitor->lastScanout.expired()) {
|
} else if (!pMonitor->lastScanout.expired()) {
|
||||||
@ -1509,6 +1513,14 @@ bool CHyprRenderer::commitPendingAndDoExplicitSync(PHLMONITOR pMonitor) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if AQUAMARINE_VERSION_NUMBER > 702 // >0.7.2
|
||||||
|
if (pMonitor->activeWorkspace && pMonitor->activeWorkspace->m_bHasFullscreenWindow && pMonitor->activeWorkspace->m_efFullscreenMode == FSMODE_FULLSCREEN) {
|
||||||
|
const auto WINDOW = pMonitor->activeWorkspace->getFullscreenWindow();
|
||||||
|
pMonitor->output->state->setContentType(NContentType::toDRM(WINDOW->getContentType()));
|
||||||
|
} else
|
||||||
|
pMonitor->output->state->setContentType(NContentType::toDRM(CONTENT_TYPE_NONE));
|
||||||
|
#endif
|
||||||
|
|
||||||
if (pMonitor->ctmUpdated) {
|
if (pMonitor->ctmUpdated) {
|
||||||
pMonitor->ctmUpdated = false;
|
pMonitor->ctmUpdated = false;
|
||||||
pMonitor->output->state->setCTM(pMonitor->ctm);
|
pMonitor->output->state->setCTM(pMonitor->ctm);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user