mirror of
https://github.com/hyprwm/hyprpaper.git
synced 2024-12-22 04:19:47 +01:00
core: migrate to hyprwayland-scanner
Additionally: - format - yeet clang-tidy - fixup clang-format
This commit is contained in:
parent
f3a6e51d92
commit
3cbc90bf94
31 changed files with 518 additions and 751 deletions
117
.clang-format
117
.clang-format
|
@ -1,114 +1,65 @@
|
||||||
---
|
---
|
||||||
Language: Cpp
|
Language: Cpp
|
||||||
Standard: Auto
|
BasedOnStyle: LLVM
|
||||||
AccessModifierOffset: -4
|
|
||||||
AlignAfterOpenBracket: DontAlign
|
AccessModifierOffset: -2
|
||||||
AlignArrayOfStructures: None
|
AlignAfterOpenBracket: Align
|
||||||
AlignConsecutiveAssignments: None
|
AlignConsecutiveMacros: true
|
||||||
AlignConsecutiveBitFields: Consecutive
|
AlignConsecutiveAssignments: true
|
||||||
AlignConsecutiveDeclarations: None
|
|
||||||
AlignConsecutiveMacros: None
|
|
||||||
AlignEscapedNewlines: Right
|
AlignEscapedNewlines: Right
|
||||||
AlignOperands: DontAlign
|
AlignOperands: false
|
||||||
AlignTrailingComments: true
|
AlignTrailingComments: true
|
||||||
AllowAllArgumentsOnNextLine: false
|
AllowAllArgumentsOnNextLine: true
|
||||||
AllowAllConstructorInitializersOnNextLine: true
|
AllowAllConstructorInitializersOnNextLine: true
|
||||||
AllowAllParametersOfDeclarationOnNextLine: false
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
AllowShortBlocksOnASingleLine: Empty
|
AllowShortBlocksOnASingleLine: true
|
||||||
AllowShortCaseLabelsOnASingleLine: false
|
AllowShortCaseLabelsOnASingleLine: true
|
||||||
AllowShortEnumsOnASingleLine: true
|
AllowShortFunctionsOnASingleLine: Empty
|
||||||
AllowShortFunctionsOnASingleLine: All
|
|
||||||
AllowShortIfStatementsOnASingleLine: Never
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
AllowShortLambdasOnASingleLine: All
|
AllowShortLambdasOnASingleLine: All
|
||||||
AllowShortLoopsOnASingleLine: false
|
AllowShortLoopsOnASingleLine: false
|
||||||
AlwaysBreakAfterDefinitionReturnType: None
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
AlwaysBreakAfterReturnType: None
|
AlwaysBreakAfterReturnType: None
|
||||||
AlwaysBreakBeforeMultilineStrings: false
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
AlwaysBreakTemplateDeclarations: MultiLine
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
BinPackArguments: true
|
BreakBeforeBraces: Attach
|
||||||
BinPackParameters: true
|
BreakBeforeTernaryOperators: false
|
||||||
BitFieldColonSpacing: Both
|
BreakConstructorInitializers: AfterColon
|
||||||
BreakAfterJavaFieldAnnotations: true
|
ColumnLimit: 180
|
||||||
BreakBeforeBinaryOperators: NonAssignment
|
CompactNamespaces: false
|
||||||
BreakBeforeConceptDeclarations: true
|
|
||||||
BreakBeforeInheritanceComma: false
|
|
||||||
BreakBeforeTernaryOperators: true
|
|
||||||
BreakConstructorInitializers: BeforeComma
|
|
||||||
BreakConstructorInitializersBeforeComma: false
|
|
||||||
BreakInheritanceList: BeforeColon
|
|
||||||
BreakStringLiterals: true
|
|
||||||
ColumnLimit: 0
|
|
||||||
CompactNamespaces: true
|
|
||||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
ConstructorInitializerIndentWidth: 8
|
ExperimentalAutoDetectBinPacking: false
|
||||||
ContinuationIndentWidth: 4
|
|
||||||
DeriveLineEnding: true
|
|
||||||
DerivePointerAlignment: false
|
|
||||||
DisableFormat: false
|
|
||||||
EmptyLineAfterAccessModifier: Never
|
|
||||||
EmptyLineBeforeAccessModifier: LogicalBlock
|
|
||||||
FixNamespaceComments: false
|
FixNamespaceComments: false
|
||||||
IncludeBlocks: Preserve
|
IncludeBlocks: Preserve
|
||||||
IncludeIsMainRegex: (Test)?$
|
|
||||||
IncludeIsMainSourceRegex: ''
|
|
||||||
IndentAccessModifiers: false
|
|
||||||
IndentCaseBlocks: false
|
|
||||||
IndentCaseLabels: true
|
IndentCaseLabels: true
|
||||||
IndentExternBlock: AfterExternBlock
|
|
||||||
IndentGotoLabels: true
|
|
||||||
IndentPPDirectives: None
|
|
||||||
IndentWidth: 4
|
IndentWidth: 4
|
||||||
IndentWrappedFunctionNames: false
|
|
||||||
InsertTrailingCommas: None
|
|
||||||
JavaScriptQuotes: Leave
|
|
||||||
JavaScriptWrapImports: true
|
|
||||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
|
||||||
LambdaBodyIndentation: Signature
|
|
||||||
MaxEmptyLinesToKeep: 1
|
|
||||||
NamespaceIndentation: All
|
|
||||||
PPIndentWidth: -1
|
|
||||||
PackConstructorInitializers: BinPack
|
|
||||||
PenaltyBreakAssignment: 2
|
|
||||||
PenaltyBreakBeforeFirstCallParameter: 19
|
|
||||||
PenaltyBreakComment: 300
|
|
||||||
PenaltyBreakFirstLessLess: 120
|
|
||||||
PenaltyBreakOpenParenthesis: 0
|
|
||||||
PenaltyBreakString: 1000
|
|
||||||
PenaltyBreakTemplateDeclaration: 10
|
|
||||||
PenaltyExcessCharacter: 1000000
|
|
||||||
PenaltyIndentedWhitespace: 0
|
|
||||||
PenaltyReturnTypeOnItsOwnLine: 60
|
|
||||||
PointerAlignment: Left
|
PointerAlignment: Left
|
||||||
QualifierAlignment: Leave
|
ReflowComments: false
|
||||||
ReferenceAlignment: Pointer
|
SortIncludes: false
|
||||||
ReflowComments: true
|
SortUsingDeclarations: false
|
||||||
RemoveBracesLLVM: false
|
|
||||||
SeparateDefinitionBlocks: Leave
|
|
||||||
ShortNamespaceLines: 1
|
|
||||||
SortIncludes: CaseSensitive
|
|
||||||
SortJavaStaticImport: Before
|
|
||||||
SortUsingDeclarations: true
|
|
||||||
SpaceAfterCStyleCast: false
|
SpaceAfterCStyleCast: false
|
||||||
SpaceAfterLogicalNot: false
|
SpaceAfterLogicalNot: false
|
||||||
SpaceAfterTemplateKeyword: true
|
SpaceAfterTemplateKeyword: true
|
||||||
SpaceAroundPointerQualifiers: Default
|
|
||||||
SpaceBeforeAssignmentOperators: true
|
|
||||||
SpaceBeforeCaseColon: false
|
|
||||||
SpaceBeforeCtorInitializerColon: true
|
SpaceBeforeCtorInitializerColon: true
|
||||||
SpaceBeforeInheritanceColon: true
|
SpaceBeforeInheritanceColon: true
|
||||||
SpaceBeforeParens: ControlStatements
|
SpaceBeforeParens: ControlStatements
|
||||||
SpaceBeforeRangeBasedForLoopColon: true
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
SpaceBeforeSquareBrackets: false
|
|
||||||
SpaceInEmptyBlock: true
|
|
||||||
SpaceInEmptyParentheses: false
|
SpaceInEmptyParentheses: false
|
||||||
SpacesBeforeTrailingComments: 1
|
SpacesBeforeTrailingComments: 1
|
||||||
SpacesInAngles: Never
|
SpacesInAngles: false
|
||||||
SpacesInCStyleCastParentheses: false
|
SpacesInCStyleCastParentheses: false
|
||||||
SpacesInConditionalStatement: false
|
SpacesInContainerLiterals: false
|
||||||
SpacesInContainerLiterals: true
|
|
||||||
SpacesInParentheses: false
|
SpacesInParentheses: false
|
||||||
SpacesInSquareBrackets: false
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Auto
|
||||||
TabWidth: 4
|
TabWidth: 4
|
||||||
UseCRLF: false
|
|
||||||
UseTab: Never
|
UseTab: Never
|
||||||
...
|
|
||||||
|
AllowShortEnumsOnASingleLine: false
|
||||||
|
|
||||||
|
BraceWrapping:
|
||||||
|
AfterEnum: false
|
||||||
|
|
||||||
|
AlignConsecutiveDeclarations: AcrossEmptyLines
|
||||||
|
|
||||||
|
NamespaceIndentation: All
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
---
|
|
||||||
Checks: '-*,clang-diagnostic-*,bugprone-*,cert-*,misc-*,modernize-*,performance-*,readability-*,hicpp-exception-baseclass,hicpp-avoid-goto,-clang-diagnostic-address-of-packed-member,-cert-dcl16-c,-cert-dcl21-cpp,-cert-err58-cpp,-misc-unused-parameters,-misc-non-private-member-variables-in-classes,-modernize-avoid-c-arrays,-modernize-concat-nested-namespaces,-modernize-raw-string-literal,-modernize-use-default-member-init,-modernize-use-nodiscard,-modernize-use-override,-modernize-use-trailing-return-type,-readability-else-after-return,-readability-identifier-naming,-readability-implicit-bool-cast,-readability-implicit-bool-conversion,-readability-magic-numbers,-readability-named-parameter,-readability-qualified-auto,-readability-redundant-access-specifiers,-readability-redundant-member-init,-readability-uppercase-literal-suffix'
|
|
||||||
WarningsAsErrors: '*'
|
|
||||||
HeaderFilterRegex: ''
|
|
||||||
FormatStyle: none
|
|
||||||
...
|
|
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -19,6 +19,11 @@ result
|
||||||
*-protocol.h
|
*-protocol.h
|
||||||
.ccls-cache
|
.ccls-cache
|
||||||
|
|
||||||
|
protocols/*.hpp
|
||||||
|
protocols/*.cpp
|
||||||
|
|
||||||
|
.cache/
|
||||||
|
|
||||||
hyprctl/hyprctl
|
hyprctl/hyprctl
|
||||||
|
|
||||||
gmon.out
|
gmon.out
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
cmake_minimum_required(VERSION 3.4)
|
cmake_minimum_required(VERSION 3.12)
|
||||||
project(hyprpaper
|
project(hyprpaper
|
||||||
DESCRIPTION "A blazing fast wayland wallpaper utility"
|
DESCRIPTION "A blazing fast wayland wallpaper utility"
|
||||||
VERSION 0.7.0
|
VERSION 0.7.0
|
||||||
|
@ -36,35 +36,6 @@ execute_process(
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
find_program(WaylandScanner NAMES wayland-scanner)
|
|
||||||
message(STATUS "Found WaylandScanner at ${WaylandScanner}")
|
|
||||||
execute_process(
|
|
||||||
COMMAND pkg-config --variable=pkgdatadir wayland-protocols
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
|
||||||
OUTPUT_VARIABLE WAYLAND_PROTOCOLS_DIR
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
||||||
message(STATUS "Found wayland-protocols at ${WAYLAND_PROTOCOLS_DIR}")
|
|
||||||
|
|
||||||
function(protocol protoPath protoName external)
|
|
||||||
if (external)
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${WaylandScanner} client-header ${protoPath} ${protoName}-protocol.h
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${WaylandScanner} private-code ${protoPath} ${protoName}-protocol.c
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
|
||||||
target_sources(hyprpaper PRIVATE ${protoName}-protocol.h ${protoName}-protocol.c)
|
|
||||||
else()
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${WaylandScanner} client-header ${WAYLAND_PROTOCOLS_DIR}/${protoPath} ${protoName}-protocol.h
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
|
||||||
execute_process(
|
|
||||||
COMMAND ${WaylandScanner} private-code ${WAYLAND_PROTOCOLS_DIR}/${protoPath} ${protoName}-protocol.c
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
|
|
||||||
target_sources(hyprpaper PRIVATE ${protoName}-protocol.h ${protoName}-protocol.c)
|
|
||||||
endif()
|
|
||||||
endfunction()
|
|
||||||
|
|
||||||
include_directories(.)
|
include_directories(.)
|
||||||
set(CMAKE_CXX_STANDARD 23)
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
add_compile_options(-DWLR_USE_UNSTABLE)
|
add_compile_options(-DWLR_USE_UNSTABLE)
|
||||||
|
@ -72,16 +43,50 @@ add_compile_options(-Wall -Wextra -Wno-unused-parameter -Wno-unused-value -Wno-m
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
find_package(PkgConfig REQUIRED)
|
find_package(PkgConfig REQUIRED)
|
||||||
pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-client wayland-protocols cairo pango pangocairo libjpeg libwebp hyprlang>=0.2.0 hyprutils>=0.2.0)
|
pkg_check_modules(deps REQUIRED IMPORTED_TARGET wayland-client wayland-protocols cairo pango pangocairo libjpeg libwebp hyprlang>=0.2.0 hyprutils>=0.2.0 hyprwayland-scanner>=0.4.0)
|
||||||
|
|
||||||
file(GLOB_RECURSE SRCFILES "src/*.cpp")
|
file(GLOB_RECURSE SRCFILES "src/*.cpp")
|
||||||
|
|
||||||
add_executable(hyprpaper ${SRCFILES})
|
add_executable(hyprpaper ${SRCFILES})
|
||||||
|
|
||||||
protocol("protocols/wlr-layer-shell-unstable-v1.xml" "wlr-layer-shell-unstable-v1" true)
|
pkg_get_variable(WAYLAND_PROTOCOLS_DIR wayland-protocols pkgdatadir)
|
||||||
protocol("stable/xdg-shell/xdg-shell.xml" "xdg-shell" false)
|
message(STATUS "Found wayland-protocols at ${WAYLAND_PROTOCOLS_DIR}")
|
||||||
protocol("stable/viewporter/viewporter.xml" "viewporter" false)
|
pkg_get_variable(WAYLAND_CLIENT_DIR wayland-client pkgdatadir)
|
||||||
protocol("staging/fractional-scale/fractional-scale-v1.xml" "fractional-scale-v1" false)
|
message(STATUS "Found wayland-client at ${WAYLAND_CLIENT_DIR}")
|
||||||
|
|
||||||
|
function(protocolNew protoPath protoName external)
|
||||||
|
if (external)
|
||||||
|
set(path ${CMAKE_SOURCE_DIR}/${protoPath})
|
||||||
|
else()
|
||||||
|
set(path ${WAYLAND_PROTOCOLS_DIR}/${protoPath})
|
||||||
|
endif()
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${CMAKE_SOURCE_DIR}/protocols/${protoName}.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/protocols/${protoName}.hpp
|
||||||
|
COMMAND hyprwayland-scanner --client ${path}/${protoName}.xml ${CMAKE_SOURCE_DIR}/protocols/
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
)
|
||||||
|
target_sources(hyprpaper PRIVATE protocols/${protoName}.cpp protocols/${protoName}.hpp)
|
||||||
|
endfunction()
|
||||||
|
function(protocolWayland)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${CMAKE_SOURCE_DIR}/protocols/wayland.cpp
|
||||||
|
${CMAKE_SOURCE_DIR}/protocols/wayland.hpp
|
||||||
|
COMMAND hyprwayland-scanner --wayland-enums --client ${WAYLAND_CLIENT_DIR}/wayland.xml ${CMAKE_SOURCE_DIR}/protocols/
|
||||||
|
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||||
|
)
|
||||||
|
target_sources(hyprpaper PRIVATE protocols/wayland.cpp protocols/wayland.hpp)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
protocolWayland()
|
||||||
|
|
||||||
|
protocolNew("protocols" "wlr-layer-shell-unstable-v1" true)
|
||||||
|
protocolNew("stable/linux-dmabuf" "linux-dmabuf-v1" false)
|
||||||
|
protocolNew("staging/fractional-scale" "fractional-scale-v1" false)
|
||||||
|
protocolNew("stable/viewporter" "viewporter" false)
|
||||||
|
protocolNew("stable/xdg-shell" "xdg-shell" false)
|
||||||
|
protocolNew("staging/cursor-shape" "cursor-shape-v1" false)
|
||||||
|
protocolNew("stable/tablet" "tablet-v2" false)
|
||||||
|
|
||||||
target_compile_definitions(hyprpaper PRIVATE "-DGIT_COMMIT_HASH=\"${GIT_COMMIT_HASH}\"")
|
target_compile_definitions(hyprpaper PRIVATE "-DGIT_COMMIT_HASH=\"${GIT_COMMIT_HASH}\"")
|
||||||
target_compile_definitions(hyprpaper PRIVATE "-DGIT_BRANCH=\"${GIT_BRANCH}\"")
|
target_compile_definitions(hyprpaper PRIVATE "-DGIT_BRANCH=\"${GIT_BRANCH}\"")
|
||||||
|
|
11
README.md
11
README.md
|
@ -30,23 +30,22 @@ The development files of these packages need to be installed on the system for `
|
||||||
- libjpeg-turbo
|
- libjpeg-turbo
|
||||||
- libwebp
|
- libwebp
|
||||||
- hyprlang
|
- hyprlang
|
||||||
|
- hyprutils
|
||||||
Please note hyprpaper > 0.5.0 depends on [hyprlang](https://github.com/hyprwm/hyprlang) which is new
|
- hyprwayland-scanner
|
||||||
and might not be packaged for your distro yet. If that's the case, build and install it from source.
|
|
||||||
|
|
||||||
To install all of these in Fedora, run this command:
|
To install all of these in Fedora, run this command:
|
||||||
```
|
```
|
||||||
sudo dnf install wayland-devel wayland-protocols-devel hyprlang-devel pango-devel cairo-devel file-devel libglvnd-devel libglvnd-core-devel libjpeg-turbo-devel libwebp-devel gcc-c++
|
sudo dnf install wayland-devel wayland-protocols-devel hyprlang-devel pango-devel cairo-devel file-devel libglvnd-devel libglvnd-core-devel libjpeg-turbo-devel libwebp-devel gcc-c++ hyprutils-devel hyprwayland-scanner
|
||||||
```
|
```
|
||||||
|
|
||||||
On Arch:
|
On Arch:
|
||||||
```
|
```
|
||||||
sudo pacman -S ninja gcc wayland-protocols libjpeg-turbo libwebp pango cairo pkgconf cmake libglvnd wayland
|
sudo pacman -S ninja gcc wayland-protocols libjpeg-turbo libwebp pango cairo pkgconf cmake libglvnd wayland hyprutils hyprwayland-scanner hyprlang
|
||||||
```
|
```
|
||||||
|
|
||||||
On OpenSUSE:
|
On OpenSUSE:
|
||||||
```
|
```
|
||||||
sudo zypper install ninja gcc-c++ wayland-protocols-devel Mesa-libGLESv3-devel file-devel
|
sudo zypper install ninja gcc-c++ wayland-protocols-devel Mesa-libGLESv3-devel file-devel hyprutils-devel hyprwayland-scanner
|
||||||
```
|
```
|
||||||
|
|
||||||
### Building
|
### Building
|
||||||
|
|
|
@ -6,6 +6,47 @@
|
||||||
|
|
||||||
CHyprpaper::CHyprpaper() = default;
|
CHyprpaper::CHyprpaper() = default;
|
||||||
|
|
||||||
|
static void handleGlobal(CCWlRegistry* registry, uint32_t name, const char* interface, uint32_t version) {
|
||||||
|
if (strcmp(interface, wl_compositor_interface.name) == 0) {
|
||||||
|
g_pHyprpaper->m_pCompositor = makeShared<CCWlCompositor>((wl_proxy*)wl_registry_bind((wl_registry*)registry->resource(), name, &wl_compositor_interface, 4));
|
||||||
|
} else if (strcmp(interface, wl_shm_interface.name) == 0) {
|
||||||
|
g_pHyprpaper->m_pSHM = makeShared<CCWlShm>((wl_proxy*)wl_registry_bind((wl_registry*)registry->resource(), name, &wl_shm_interface, 1));
|
||||||
|
} else if (strcmp(interface, wl_output_interface.name) == 0) {
|
||||||
|
g_pHyprpaper->m_mtTickMutex.lock();
|
||||||
|
|
||||||
|
const auto PMONITOR = g_pHyprpaper->m_vMonitors.emplace_back(std::make_unique<SMonitor>()).get();
|
||||||
|
PMONITOR->wayland_name = name;
|
||||||
|
PMONITOR->name = "";
|
||||||
|
PMONITOR->output = makeShared<CCWlOutput>((wl_proxy*)wl_registry_bind((wl_registry*)registry->resource(), name, &wl_output_interface, 4));
|
||||||
|
PMONITOR->registerListeners();
|
||||||
|
|
||||||
|
g_pHyprpaper->m_mtTickMutex.unlock();
|
||||||
|
} else if (strcmp(interface, wl_seat_interface.name) == 0) {
|
||||||
|
g_pHyprpaper->createSeat(makeShared<CCWlSeat>((wl_proxy*)wl_registry_bind((wl_registry*)registry->resource(), name, &wl_seat_interface, 1)));
|
||||||
|
} else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
|
||||||
|
g_pHyprpaper->m_pLayerShell = makeShared<CCZwlrLayerShellV1>((wl_proxy*)wl_registry_bind((wl_registry*)registry->resource(), name, &zwlr_layer_shell_v1_interface, 1));
|
||||||
|
} else if (strcmp(interface, wp_fractional_scale_manager_v1_interface.name) == 0 && !g_pHyprpaper->m_bNoFractionalScale) {
|
||||||
|
g_pHyprpaper->m_pFractionalScale =
|
||||||
|
makeShared<CCWpFractionalScaleManagerV1>((wl_proxy*)wl_registry_bind((wl_registry*)registry->resource(), name, &wp_fractional_scale_manager_v1_interface, 1));
|
||||||
|
} else if (strcmp(interface, wp_viewporter_interface.name) == 0) {
|
||||||
|
g_pHyprpaper->m_pViewporter = makeShared<CCWpViewporter>((wl_proxy*)wl_registry_bind((wl_registry*)registry->resource(), name, &wp_viewporter_interface, 1));
|
||||||
|
} else if (strcmp(interface, wp_cursor_shape_manager_v1_interface.name) == 0) {
|
||||||
|
g_pHyprpaper->m_pCursorShape =
|
||||||
|
makeShared<CCWpCursorShapeManagerV1>((wl_proxy*)wl_registry_bind((wl_registry*)registry->resource(), name, &wp_cursor_shape_manager_v1_interface, 1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void handleGlobalRemove(CCWlRegistry* registry, uint32_t name) {
|
||||||
|
for (auto& m : g_pHyprpaper->m_vMonitors) {
|
||||||
|
if (m->wayland_name == name) {
|
||||||
|
Debug::log(LOG, "Destroying output %s", m->name.c_str());
|
||||||
|
g_pHyprpaper->clearWallpaperFromMonitor(m->name);
|
||||||
|
std::erase_if(g_pHyprpaper->m_vMonitors, [&](const auto& other) { return other->wayland_name == name; });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CHyprpaper::init() {
|
void CHyprpaper::init() {
|
||||||
|
|
||||||
if (!lockSingleInstance()) {
|
if (!lockSingleInstance()) {
|
||||||
|
@ -23,8 +64,9 @@ void CHyprpaper::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// run
|
// run
|
||||||
wl_registry* registry = wl_display_get_registry(m_sDisplay);
|
auto REGISTRY = makeShared<CCWlRegistry>((wl_proxy*)wl_display_get_registry(m_sDisplay));
|
||||||
wl_registry_add_listener(registry, &Events::registryListener, nullptr);
|
REGISTRY->setGlobal(::handleGlobal);
|
||||||
|
REGISTRY->setGlobalRemove(::handleGlobalRemove);
|
||||||
|
|
||||||
wl_display_roundtrip(m_sDisplay);
|
wl_display_roundtrip(m_sDisplay);
|
||||||
|
|
||||||
|
@ -33,7 +75,7 @@ void CHyprpaper::init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pConfigManager = std::make_unique<CConfigManager>();
|
g_pConfigManager = std::make_unique<CConfigManager>();
|
||||||
g_pIPCSocket = std::make_unique<CIPCSocket>();
|
g_pIPCSocket = std::make_unique<CIPCSocket>();
|
||||||
|
|
||||||
g_pConfigManager->parse();
|
g_pConfigManager->parse();
|
||||||
|
|
||||||
|
@ -130,9 +172,9 @@ void CHyprpaper::preloadAllWallpapersFromConfig() {
|
||||||
|
|
||||||
m_mWallpaperTargets[wp] = CWallpaperTarget();
|
m_mWallpaperTargets[wp] = CWallpaperTarget();
|
||||||
if (std::filesystem::is_symlink(wp)) {
|
if (std::filesystem::is_symlink(wp)) {
|
||||||
auto real_wp = std::filesystem::read_symlink(wp);
|
auto real_wp = std::filesystem::read_symlink(wp);
|
||||||
std::filesystem::path absolute_path = std::filesystem::path(wp).parent_path() / real_wp;
|
std::filesystem::path absolute_path = std::filesystem::path(wp).parent_path() / real_wp;
|
||||||
absolute_path = absolute_path.lexically_normal();
|
absolute_path = absolute_path.lexically_normal();
|
||||||
m_mWallpaperTargets[wp].create(absolute_path);
|
m_mWallpaperTargets[wp].create(absolute_path);
|
||||||
} else {
|
} else {
|
||||||
m_mWallpaperTargets[wp].create(wp);
|
m_mWallpaperTargets[wp].create(wp);
|
||||||
|
@ -148,8 +190,28 @@ void CHyprpaper::recheckAllMonitors() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprpaper::createSeat(wl_seat* pSeat) {
|
void CHyprpaper::createSeat(SP<CCWlSeat> pSeat) {
|
||||||
wl_seat_add_listener(pSeat, &Events::seatListener, pSeat);
|
m_pSeat = pSeat;
|
||||||
|
|
||||||
|
pSeat->setCapabilities([this](CCWlSeat* r, wl_seat_capability caps) {
|
||||||
|
if (caps & WL_SEAT_CAPABILITY_POINTER) {
|
||||||
|
m_pSeatPointer = makeShared<CCWlPointer>(m_pSeat->sendGetPointer());
|
||||||
|
if (!m_pCursorShape)
|
||||||
|
Debug::log(WARN, "No cursor-shape-v1 support from the compositor: cursor will be blank");
|
||||||
|
else
|
||||||
|
m_pSeatCursorShapeDevice = makeShared<CCWpCursorShapeDeviceV1>(m_pCursorShape->sendGetPointer(m_pSeatPointer->resource()));
|
||||||
|
|
||||||
|
m_pSeatPointer->setEnter([this](CCWlPointer* r, uint32_t serial, wl_resource* surface, wl_fixed_t x, wl_fixed_t y) {
|
||||||
|
if (!m_pCursorShape) {
|
||||||
|
m_pSeatPointer->sendSetCursor(serial, nullptr, 0, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_pSeatCursorShapeDevice->sendSetShape(serial, wpCursorShapeDeviceV1Shape::WP_CURSOR_SHAPE_DEVICE_V1_SHAPE_DEFAULT);
|
||||||
|
});
|
||||||
|
} else
|
||||||
|
Debug::log(LOG, "No pointer capability from the compositor");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprpaper::recheckMonitor(SMonitor* pMonitor) {
|
void CHyprpaper::recheckMonitor(SMonitor* pMonitor) {
|
||||||
|
@ -157,24 +219,7 @@ void CHyprpaper::recheckMonitor(SMonitor* pMonitor) {
|
||||||
|
|
||||||
if (pMonitor->wantsACK) {
|
if (pMonitor->wantsACK) {
|
||||||
pMonitor->wantsACK = false;
|
pMonitor->wantsACK = false;
|
||||||
zwlr_layer_surface_v1_ack_configure(pMonitor->pCurrentLayerSurface->pLayerSurface, pMonitor->configureSerial);
|
pMonitor->pCurrentLayerSurface->pLayerSurface->sendAckConfigure(pMonitor->configureSerial);
|
||||||
|
|
||||||
if (!pMonitor->pCurrentLayerSurface->pCursorImg) {
|
|
||||||
int XCURSOR_SIZE = 24;
|
|
||||||
if (const auto CURSORSIZENV = getenv("XCURSOR_SIZE"); CURSORSIZENV) {
|
|
||||||
try {
|
|
||||||
if (XCURSOR_SIZE = std::stoi(CURSORSIZENV); XCURSOR_SIZE <= 0) {
|
|
||||||
throw std::exception();
|
|
||||||
}
|
|
||||||
} catch (...) {
|
|
||||||
Debug::log(WARN, "XCURSOR_SIZE environment variable is set incorrectly");
|
|
||||||
XCURSOR_SIZE = 24;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pMonitor->pCurrentLayerSurface->pCursorTheme = wl_cursor_theme_load(getenv("XCURSOR_THEME"), XCURSOR_SIZE * pMonitor->scale, m_sSHM);
|
|
||||||
pMonitor->pCurrentLayerSurface->pCursorImg = wl_cursor_theme_get_cursor(pMonitor->pCurrentLayerSurface->pCursorTheme, "left_ptr")->images[0];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pMonitor->wantsReload) {
|
if (pMonitor->wantsReload) {
|
||||||
|
@ -184,7 +229,7 @@ void CHyprpaper::recheckMonitor(SMonitor* pMonitor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprpaper::removeOldHyprpaperImages() {
|
void CHyprpaper::removeOldHyprpaperImages() {
|
||||||
int cleaned = 0;
|
int cleaned = 0;
|
||||||
uint64_t memoryFreed = 0;
|
uint64_t memoryFreed = 0;
|
||||||
|
|
||||||
for (const auto& entry : std::filesystem::directory_iterator(std::string(getenv("XDG_RUNTIME_DIR")))) {
|
for (const auto& entry : std::filesystem::directory_iterator(std::string(getenv("XDG_RUNTIME_DIR")))) {
|
||||||
|
@ -209,11 +254,11 @@ void CHyprpaper::removeOldHyprpaperImages() {
|
||||||
}
|
}
|
||||||
|
|
||||||
SMonitor* CHyprpaper::getMonitorFromName(const std::string& monname) {
|
SMonitor* CHyprpaper::getMonitorFromName(const std::string& monname) {
|
||||||
bool useDesc = false;
|
bool useDesc = false;
|
||||||
std::string desc = "";
|
std::string desc = "";
|
||||||
if (monname.find("desc:") == 0) {
|
if (monname.find("desc:") == 0) {
|
||||||
useDesc = true;
|
useDesc = true;
|
||||||
desc = monname.substr(5);
|
desc = monname.substr(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto& m : m_vMonitors) {
|
for (auto& m : m_vMonitors) {
|
||||||
|
@ -285,10 +330,10 @@ void CHyprpaper::clearWallpaperFromMonitor(const std::string& monname) {
|
||||||
|
|
||||||
PMONITOR->pCurrentLayerSurface = nullptr;
|
PMONITOR->pCurrentLayerSurface = nullptr;
|
||||||
|
|
||||||
PMONITOR->wantsACK = false;
|
PMONITOR->wantsACK = false;
|
||||||
PMONITOR->wantsReload = false;
|
PMONITOR->wantsReload = false;
|
||||||
PMONITOR->initialized = false;
|
PMONITOR->initialized = false;
|
||||||
PMONITOR->readyForLS = true;
|
PMONITOR->readyForLS = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,7 +345,7 @@ void CHyprpaper::ensureMonitorHasActiveWallpaper(SMonitor* pMonitor) {
|
||||||
|
|
||||||
if (it == m_mMonitorActiveWallpaperTargets.end()) {
|
if (it == m_mMonitorActiveWallpaperTargets.end()) {
|
||||||
m_mMonitorActiveWallpaperTargets[pMonitor] = nullptr;
|
m_mMonitorActiveWallpaperTargets[pMonitor] = nullptr;
|
||||||
it = m_mMonitorActiveWallpaperTargets.find(pMonitor);
|
it = m_mMonitorActiveWallpaperTargets.find(pMonitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (it->second)
|
if (it->second)
|
||||||
|
@ -411,10 +456,10 @@ int CHyprpaper::createPoolFile(size_t size, std::string& name) {
|
||||||
|
|
||||||
void CHyprpaper::createBuffer(SPoolBuffer* pBuffer, int32_t w, int32_t h, uint32_t format) {
|
void CHyprpaper::createBuffer(SPoolBuffer* pBuffer, int32_t w, int32_t h, uint32_t format) {
|
||||||
const size_t STRIDE = w * 4;
|
const size_t STRIDE = w * 4;
|
||||||
const size_t SIZE = STRIDE * h;
|
const size_t SIZE = STRIDE * h;
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
const auto FD = createPoolFile(SIZE, name);
|
const auto FD = createPoolFile(SIZE, name);
|
||||||
|
|
||||||
if (FD == -1) {
|
if (FD == -1) {
|
||||||
Debug::log(CRIT, "Unable to create pool file!");
|
Debug::log(CRIT, "Unable to create pool file!");
|
||||||
|
@ -422,22 +467,22 @@ void CHyprpaper::createBuffer(SPoolBuffer* pBuffer, int32_t w, int32_t h, uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto DATA = mmap(nullptr, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, FD, 0);
|
const auto DATA = mmap(nullptr, SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, FD, 0);
|
||||||
const auto POOL = wl_shm_create_pool(g_pHyprpaper->m_sSHM, FD, SIZE);
|
auto POOL = makeShared<CCWlShmPool>(g_pHyprpaper->m_pSHM->sendCreatePool(FD, SIZE));
|
||||||
pBuffer->buffer = wl_shm_pool_create_buffer(POOL, 0, w, h, STRIDE, format);
|
pBuffer->buffer = makeShared<CCWlBuffer>(POOL->sendCreateBuffer(0, w, h, STRIDE, format));
|
||||||
wl_shm_pool_destroy(POOL);
|
POOL.reset();
|
||||||
|
|
||||||
close(FD);
|
close(FD);
|
||||||
|
|
||||||
pBuffer->size = SIZE;
|
pBuffer->size = SIZE;
|
||||||
pBuffer->data = DATA;
|
pBuffer->data = DATA;
|
||||||
pBuffer->surface = cairo_image_surface_create_for_data((unsigned char*)DATA, CAIRO_FORMAT_ARGB32, w, h, STRIDE);
|
pBuffer->surface = cairo_image_surface_create_for_data((unsigned char*)DATA, CAIRO_FORMAT_ARGB32, w, h, STRIDE);
|
||||||
pBuffer->cairo = cairo_create(pBuffer->surface);
|
pBuffer->cairo = cairo_create(pBuffer->surface);
|
||||||
pBuffer->pixelSize = Vector2D(w, h);
|
pBuffer->pixelSize = Vector2D(w, h);
|
||||||
pBuffer->name = name;
|
pBuffer->name = name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHyprpaper::destroyBuffer(SPoolBuffer* pBuffer) {
|
void CHyprpaper::destroyBuffer(SPoolBuffer* pBuffer) {
|
||||||
wl_buffer_destroy(pBuffer->buffer);
|
pBuffer->buffer.reset();
|
||||||
cairo_destroy(pBuffer->cairo);
|
cairo_destroy(pBuffer->cairo);
|
||||||
cairo_surface_destroy(pBuffer->surface);
|
cairo_surface_destroy(pBuffer->surface);
|
||||||
munmap(pBuffer->data, pBuffer->size);
|
munmap(pBuffer->data, pBuffer->size);
|
||||||
|
@ -447,7 +492,10 @@ void CHyprpaper::destroyBuffer(SPoolBuffer* pBuffer) {
|
||||||
|
|
||||||
SPoolBuffer* CHyprpaper::getPoolBuffer(SMonitor* pMonitor, CWallpaperTarget* pWallpaperTarget) {
|
SPoolBuffer* CHyprpaper::getPoolBuffer(SMonitor* pMonitor, CWallpaperTarget* pWallpaperTarget) {
|
||||||
const auto IT = std::find_if(m_vBuffers.begin(), m_vBuffers.end(), [&](const std::unique_ptr<SPoolBuffer>& el) {
|
const auto IT = std::find_if(m_vBuffers.begin(), m_vBuffers.end(), [&](const std::unique_ptr<SPoolBuffer>& el) {
|
||||||
auto scale = std::round((pMonitor->pCurrentLayerSurface && pMonitor->pCurrentLayerSurface->pFractionalScaleInfo ? pMonitor->pCurrentLayerSurface->fScale : pMonitor->scale) * 120.0) / 120.0;
|
auto scale =
|
||||||
|
std::round((pMonitor->pCurrentLayerSurface && pMonitor->pCurrentLayerSurface->pFractionalScaleInfo ? pMonitor->pCurrentLayerSurface->fScale : pMonitor->scale) *
|
||||||
|
120.0) /
|
||||||
|
120.0;
|
||||||
return el->target == pWallpaperTarget->m_szPath && vectorDeltaLessThan(el->pixelSize, pMonitor->size * scale, 1);
|
return el->target == pWallpaperTarget->m_szPath && vectorDeltaLessThan(el->pixelSize, pMonitor->size * scale, 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -464,7 +512,7 @@ void CHyprpaper::renderWallpaperForMonitor(SMonitor* pMonitor) {
|
||||||
recheckMonitor(pMonitor);
|
recheckMonitor(pMonitor);
|
||||||
|
|
||||||
const auto PWALLPAPERTARGET = m_mMonitorActiveWallpaperTargets[pMonitor];
|
const auto PWALLPAPERTARGET = m_mMonitorActiveWallpaperTargets[pMonitor];
|
||||||
const auto CONTAIN = m_mMonitorWallpaperRenderData[pMonitor->name].contain;
|
const auto CONTAIN = m_mMonitorWallpaperRenderData[pMonitor->name].contain;
|
||||||
|
|
||||||
if (!PWALLPAPERTARGET) {
|
if (!PWALLPAPERTARGET) {
|
||||||
Debug::log(CRIT, "wallpaper target null in render??");
|
Debug::log(CRIT, "wallpaper target null in render??");
|
||||||
|
@ -485,10 +533,10 @@ void CHyprpaper::renderWallpaperForMonitor(SMonitor* pMonitor) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const double SURFACESCALE = pMonitor->pCurrentLayerSurface && pMonitor->pCurrentLayerSurface->pFractionalScaleInfo ? pMonitor->pCurrentLayerSurface->fScale : pMonitor->scale;
|
const double SURFACESCALE = pMonitor->pCurrentLayerSurface && pMonitor->pCurrentLayerSurface->pFractionalScaleInfo ? pMonitor->pCurrentLayerSurface->fScale : pMonitor->scale;
|
||||||
const Vector2D DIMENSIONS = Vector2D{std::round(pMonitor->size.x * SURFACESCALE), std::round(pMonitor->size.y * SURFACESCALE)};
|
const Vector2D DIMENSIONS = Vector2D{std::round(pMonitor->size.x * SURFACESCALE), std::round(pMonitor->size.y * SURFACESCALE)};
|
||||||
|
|
||||||
const auto PCAIRO = PBUFFER->cairo;
|
const auto PCAIRO = PBUFFER->cairo;
|
||||||
cairo_save(PCAIRO);
|
cairo_save(PCAIRO);
|
||||||
cairo_set_operator(PCAIRO, CAIRO_OPERATOR_CLEAR);
|
cairo_set_operator(PCAIRO, CAIRO_OPERATOR_CLEAR);
|
||||||
cairo_paint(PCAIRO);
|
cairo_paint(PCAIRO);
|
||||||
|
@ -502,19 +550,20 @@ void CHyprpaper::renderWallpaperForMonitor(SMonitor* pMonitor) {
|
||||||
|
|
||||||
// get scale
|
// get scale
|
||||||
// we always do cover
|
// we always do cover
|
||||||
double scale;
|
double scale;
|
||||||
Vector2D origin;
|
Vector2D origin;
|
||||||
|
|
||||||
const bool LOWASPECTRATIO = pMonitor->size.x / pMonitor->size.y > PWALLPAPERTARGET->m_vSize.x / PWALLPAPERTARGET->m_vSize.y;
|
const bool LOWASPECTRATIO = pMonitor->size.x / pMonitor->size.y > PWALLPAPERTARGET->m_vSize.x / PWALLPAPERTARGET->m_vSize.y;
|
||||||
if ((CONTAIN && !LOWASPECTRATIO) || (!CONTAIN && LOWASPECTRATIO)) {
|
if ((CONTAIN && !LOWASPECTRATIO) || (!CONTAIN && LOWASPECTRATIO)) {
|
||||||
scale = DIMENSIONS.x / PWALLPAPERTARGET->m_vSize.x;
|
scale = DIMENSIONS.x / PWALLPAPERTARGET->m_vSize.x;
|
||||||
origin.y = -(PWALLPAPERTARGET->m_vSize.y * scale - DIMENSIONS.y) / 2.0 / scale;
|
origin.y = -(PWALLPAPERTARGET->m_vSize.y * scale - DIMENSIONS.y) / 2.0 / scale;
|
||||||
} else {
|
} else {
|
||||||
scale = DIMENSIONS.y / PWALLPAPERTARGET->m_vSize.y;
|
scale = DIMENSIONS.y / PWALLPAPERTARGET->m_vSize.y;
|
||||||
origin.x = -(PWALLPAPERTARGET->m_vSize.x * scale - DIMENSIONS.x) / 2.0 / scale;
|
origin.x = -(PWALLPAPERTARGET->m_vSize.x * scale - DIMENSIONS.x) / 2.0 / scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
Debug::log(LOG, "Image data for %s: %s at [%.2f, %.2f], scale: %.2f (original image size: [%i, %i])", pMonitor->name.c_str(), PWALLPAPERTARGET->m_szPath.c_str(), origin.x, origin.y, scale, (int)PWALLPAPERTARGET->m_vSize.x, (int)PWALLPAPERTARGET->m_vSize.y);
|
Debug::log(LOG, "Image data for %s: %s at [%.2f, %.2f], scale: %.2f (original image size: [%i, %i])", pMonitor->name.c_str(), PWALLPAPERTARGET->m_szPath.c_str(), origin.x,
|
||||||
|
origin.y, scale, (int)PWALLPAPERTARGET->m_vSize.x, (int)PWALLPAPERTARGET->m_vSize.y);
|
||||||
|
|
||||||
cairo_scale(PCAIRO, scale, scale);
|
cairo_scale(PCAIRO, scale, scale);
|
||||||
cairo_set_source_surface(PCAIRO, PWALLPAPERTARGET->m_pCairoSurface, origin.x, origin.y);
|
cairo_set_source_surface(PCAIRO, PWALLPAPERTARGET->m_pCairoSurface, origin.x, origin.y);
|
||||||
|
@ -536,14 +585,16 @@ void CHyprpaper::renderWallpaperForMonitor(SMonitor* pMonitor) {
|
||||||
|
|
||||||
Debug::log(LOG, "Splash color: %x", **PSPLASHCOLOR);
|
Debug::log(LOG, "Splash color: %x", **PSPLASHCOLOR);
|
||||||
|
|
||||||
cairo_set_source_rgba(PCAIRO, ((**PSPLASHCOLOR >> 16) & 0xFF) / 255.0, ((**PSPLASHCOLOR >> 8) & 0xFF) / 255.0, (**PSPLASHCOLOR & 0xFF) / 255.0, ((**PSPLASHCOLOR >> 24) & 0xFF) / 255.0);
|
cairo_set_source_rgba(PCAIRO, ((**PSPLASHCOLOR >> 16) & 0xFF) / 255.0, ((**PSPLASHCOLOR >> 8) & 0xFF) / 255.0, (**PSPLASHCOLOR & 0xFF) / 255.0,
|
||||||
|
((**PSPLASHCOLOR >> 24) & 0xFF) / 255.0);
|
||||||
|
|
||||||
cairo_text_extents_t textExtents;
|
cairo_text_extents_t textExtents;
|
||||||
cairo_text_extents(PCAIRO, SPLASH.c_str(), &textExtents);
|
cairo_text_extents(PCAIRO, SPLASH.c_str(), &textExtents);
|
||||||
|
|
||||||
cairo_move_to(PCAIRO, ((DIMENSIONS.x - textExtents.width * scale) / 2.0) / scale, ((DIMENSIONS.y * (100 - **PSPLASHOFFSET)) / 100 - textExtents.height * scale) / scale);
|
cairo_move_to(PCAIRO, ((DIMENSIONS.x - textExtents.width * scale) / 2.0) / scale, ((DIMENSIONS.y * (100 - **PSPLASHOFFSET)) / 100 - textExtents.height * scale) / scale);
|
||||||
|
|
||||||
Debug::log(LOG, "Splash font size: %d, pos: %.2f, %.2f", FONTSIZE, (DIMENSIONS.x - textExtents.width) / 2.0 / scale, ((DIMENSIONS.y * (100 - **PSPLASHOFFSET)) / 100 - textExtents.height * scale) / scale);
|
Debug::log(LOG, "Splash font size: %d, pos: %.2f, %.2f", FONTSIZE, (DIMENSIONS.x - textExtents.width) / 2.0 / scale,
|
||||||
|
((DIMENSIONS.y * (100 - **PSPLASHOFFSET)) / 100 - textExtents.height * scale) / scale);
|
||||||
|
|
||||||
cairo_show_text(PCAIRO, SPLASH.c_str());
|
cairo_show_text(PCAIRO, SPLASH.c_str());
|
||||||
|
|
||||||
|
@ -553,22 +604,21 @@ void CHyprpaper::renderWallpaperForMonitor(SMonitor* pMonitor) {
|
||||||
cairo_restore(PCAIRO);
|
cairo_restore(PCAIRO);
|
||||||
|
|
||||||
if (pMonitor->pCurrentLayerSurface) {
|
if (pMonitor->pCurrentLayerSurface) {
|
||||||
wl_surface_attach(pMonitor->pCurrentLayerSurface->pSurface, PBUFFER->buffer, 0, 0);
|
pMonitor->pCurrentLayerSurface->pSurface->sendAttach(PBUFFER->buffer.get(), 0, 0);
|
||||||
wl_surface_set_buffer_scale(pMonitor->pCurrentLayerSurface->pSurface, pMonitor->pCurrentLayerSurface->pFractionalScaleInfo ? 1 : pMonitor->scale);
|
pMonitor->pCurrentLayerSurface->pSurface->sendSetBufferScale(pMonitor->pCurrentLayerSurface->pFractionalScaleInfo ? 1 : pMonitor->scale);
|
||||||
wl_surface_damage_buffer(pMonitor->pCurrentLayerSurface->pSurface, 0, 0, 0xFFFF, 0xFFFF);
|
pMonitor->pCurrentLayerSurface->pSurface->sendDamageBuffer(0, 0, 0xFFFF, 0xFFFF);
|
||||||
|
|
||||||
// our wps are always opaque
|
// our wps are always opaque
|
||||||
auto opaqueRegion = wl_compositor_create_region(g_pHyprpaper->m_sCompositor);
|
auto opaqueRegion = makeShared<CCWlRegion>(g_pHyprpaper->m_pCompositor->sendCreateRegion());
|
||||||
wl_region_add(opaqueRegion, 0, 0, PBUFFER->pixelSize.x, PBUFFER->pixelSize.y);
|
opaqueRegion->sendAdd(0, 0, PBUFFER->pixelSize.x, PBUFFER->pixelSize.y);
|
||||||
wl_surface_set_opaque_region(pMonitor->pCurrentLayerSurface->pSurface, opaqueRegion);
|
pMonitor->pCurrentLayerSurface->pSurface->sendSetOpaqueRegion(opaqueRegion.get());
|
||||||
|
|
||||||
if (pMonitor->pCurrentLayerSurface->pFractionalScaleInfo) {
|
if (pMonitor->pCurrentLayerSurface->pFractionalScaleInfo) {
|
||||||
Debug::log(LOG, "Submitting viewport dest size %ix%i for %x", static_cast<int>(std::round(pMonitor->size.x)), static_cast<int>(std::round(pMonitor->size.y)), pMonitor->pCurrentLayerSurface);
|
Debug::log(LOG, "Submitting viewport dest size %ix%i for %x", static_cast<int>(std::round(pMonitor->size.x)), static_cast<int>(std::round(pMonitor->size.y)),
|
||||||
wp_viewport_set_destination(pMonitor->pCurrentLayerSurface->pViewport, static_cast<int>(std::round(pMonitor->size.x)), static_cast<int>(std::round(pMonitor->size.y)));
|
pMonitor->pCurrentLayerSurface);
|
||||||
|
pMonitor->pCurrentLayerSurface->pViewport->sendSetDestination(static_cast<int>(std::round(pMonitor->size.x)), static_cast<int>(std::round(pMonitor->size.y)));
|
||||||
}
|
}
|
||||||
wl_surface_commit(pMonitor->pCurrentLayerSurface->pSurface);
|
pMonitor->pCurrentLayerSurface->pSurface->sendCommit();
|
||||||
|
|
||||||
wl_region_destroy(opaqueRegion);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we dont need to remove a wallpaper
|
// check if we dont need to remove a wallpaper
|
||||||
|
@ -585,20 +635,18 @@ void CHyprpaper::renderWallpaperForMonitor(SMonitor* pMonitor) {
|
||||||
bool CHyprpaper::lockSingleInstance() {
|
bool CHyprpaper::lockSingleInstance() {
|
||||||
const std::string XDG_RUNTIME_DIR = getenv("XDG_RUNTIME_DIR");
|
const std::string XDG_RUNTIME_DIR = getenv("XDG_RUNTIME_DIR");
|
||||||
|
|
||||||
const auto LOCKFILE = XDG_RUNTIME_DIR + "/hyprpaper.lock";
|
const auto LOCKFILE = XDG_RUNTIME_DIR + "/hyprpaper.lock";
|
||||||
|
|
||||||
if (std::filesystem::exists(LOCKFILE)) {
|
if (std::filesystem::exists(LOCKFILE)) {
|
||||||
std::ifstream ifs(LOCKFILE);
|
std::ifstream ifs(LOCKFILE);
|
||||||
std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
|
std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>()));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
kill(std::stoull(content), 0);
|
kill(std::stoull(content), 0);
|
||||||
|
|
||||||
if (errno != ESRCH)
|
if (errno != ESRCH)
|
||||||
return false;
|
return false;
|
||||||
} catch (std::exception& e) {
|
} catch (std::exception& e) { ; }
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create lockfile
|
// create lockfile
|
||||||
|
@ -613,6 +661,6 @@ bool CHyprpaper::lockSingleInstance() {
|
||||||
|
|
||||||
void CHyprpaper::unlockSingleInstance() {
|
void CHyprpaper::unlockSingleInstance() {
|
||||||
const std::string XDG_RUNTIME_DIR = getenv("XDG_RUNTIME_DIR");
|
const std::string XDG_RUNTIME_DIR = getenv("XDG_RUNTIME_DIR");
|
||||||
const auto LOCKFILE = XDG_RUNTIME_DIR + "/hyprpaper.lock";
|
const auto LOCKFILE = XDG_RUNTIME_DIR + "/hyprpaper.lock";
|
||||||
unlink(LOCKFILE.c_str());
|
unlink(LOCKFILE.c_str());
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include "config/ConfigManager.hpp"
|
#include "config/ConfigManager.hpp"
|
||||||
#include "defines.hpp"
|
#include "defines.hpp"
|
||||||
#include "events/Events.hpp"
|
|
||||||
#include "helpers/MiscFunctions.hpp"
|
#include "helpers/MiscFunctions.hpp"
|
||||||
#include "helpers/Monitor.hpp"
|
#include "helpers/Monitor.hpp"
|
||||||
#include "helpers/PoolBuffer.hpp"
|
#include "helpers/PoolBuffer.hpp"
|
||||||
|
@ -10,61 +9,72 @@
|
||||||
#include "render/WallpaperTarget.hpp"
|
#include "render/WallpaperTarget.hpp"
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
#include "protocols/cursor-shape-v1.hpp"
|
||||||
|
#include "protocols/fractional-scale-v1.hpp"
|
||||||
|
#include "protocols/linux-dmabuf-v1.hpp"
|
||||||
|
#include "protocols/viewporter.hpp"
|
||||||
|
#include "protocols/wayland.hpp"
|
||||||
|
#include "protocols/wlr-layer-shell-unstable-v1.hpp"
|
||||||
|
|
||||||
struct SWallpaperRenderData {
|
struct SWallpaperRenderData {
|
||||||
bool contain = false;
|
bool contain = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CHyprpaper {
|
class CHyprpaper {
|
||||||
public:
|
public:
|
||||||
// important
|
// important
|
||||||
wl_display* m_sDisplay; // assured
|
wl_display* m_sDisplay = nullptr;
|
||||||
wl_compositor* m_sCompositor; // assured
|
SP<CCWlCompositor> m_pCompositor;
|
||||||
wl_shm* m_sSHM; // assured
|
SP<CCWlShm> m_pSHM;
|
||||||
zwlr_layer_shell_v1* m_sLayerShell = nullptr; // expected
|
SP<CCZwlrLayerShellV1> m_pLayerShell;
|
||||||
wp_fractional_scale_manager_v1* m_sFractionalScale = nullptr; // will remain null if not bound
|
SP<CCWpFractionalScaleManagerV1> m_pFractionalScale;
|
||||||
wp_viewporter* m_sViewporter = nullptr; // expected
|
SP<CCWpViewporter> m_pViewporter;
|
||||||
|
SP<CCWlSeat> m_pSeat;
|
||||||
|
SP<CCWlPointer> m_pSeatPointer;
|
||||||
|
SP<CCWpCursorShapeDeviceV1> m_pSeatCursorShapeDevice;
|
||||||
|
SP<CCWpCursorShapeManagerV1> m_pCursorShape;
|
||||||
|
|
||||||
// init the utility
|
// init the utility
|
||||||
CHyprpaper();
|
CHyprpaper();
|
||||||
void init();
|
void init();
|
||||||
void tick(bool force);
|
void tick(bool force);
|
||||||
|
|
||||||
std::unordered_map<std::string, CWallpaperTarget> m_mWallpaperTargets;
|
std::unordered_map<std::string, CWallpaperTarget> m_mWallpaperTargets;
|
||||||
std::unordered_map<std::string, std::string> m_mMonitorActiveWallpapers;
|
std::unordered_map<std::string, std::string> m_mMonitorActiveWallpapers;
|
||||||
std::unordered_map<std::string, SWallpaperRenderData> m_mMonitorWallpaperRenderData;
|
std::unordered_map<std::string, SWallpaperRenderData> m_mMonitorWallpaperRenderData;
|
||||||
std::unordered_map<SMonitor*, CWallpaperTarget*> m_mMonitorActiveWallpaperTargets;
|
std::unordered_map<SMonitor*, CWallpaperTarget*> m_mMonitorActiveWallpaperTargets;
|
||||||
std::vector<std::unique_ptr<SPoolBuffer>> m_vBuffers;
|
std::vector<std::unique_ptr<SPoolBuffer>> m_vBuffers;
|
||||||
std::vector<std::unique_ptr<SMonitor>> m_vMonitors;
|
std::vector<std::unique_ptr<SMonitor>> m_vMonitors;
|
||||||
|
|
||||||
std::string m_szExplicitConfigPath;
|
std::string m_szExplicitConfigPath;
|
||||||
bool m_bNoFractionalScale = false;
|
bool m_bNoFractionalScale = false;
|
||||||
|
|
||||||
void removeOldHyprpaperImages();
|
void removeOldHyprpaperImages();
|
||||||
void preloadAllWallpapersFromConfig();
|
void preloadAllWallpapersFromConfig();
|
||||||
void recheckAllMonitors();
|
void recheckAllMonitors();
|
||||||
void ensureMonitorHasActiveWallpaper(SMonitor*);
|
void ensureMonitorHasActiveWallpaper(SMonitor*);
|
||||||
void createLSForMonitor(SMonitor*);
|
void createLSForMonitor(SMonitor*);
|
||||||
void renderWallpaperForMonitor(SMonitor*);
|
void renderWallpaperForMonitor(SMonitor*);
|
||||||
void createBuffer(SPoolBuffer*, int32_t, int32_t, uint32_t);
|
void createBuffer(SPoolBuffer*, int32_t, int32_t, uint32_t);
|
||||||
void destroyBuffer(SPoolBuffer*);
|
void destroyBuffer(SPoolBuffer*);
|
||||||
int createPoolFile(size_t, std::string&);
|
int createPoolFile(size_t, std::string&);
|
||||||
bool setCloexec(const int&);
|
bool setCloexec(const int&);
|
||||||
void clearWallpaperFromMonitor(const std::string&);
|
void clearWallpaperFromMonitor(const std::string&);
|
||||||
SMonitor* getMonitorFromName(const std::string&);
|
SMonitor* getMonitorFromName(const std::string&);
|
||||||
bool isPreloaded(const std::string&);
|
bool isPreloaded(const std::string&);
|
||||||
void recheckMonitor(SMonitor*);
|
void recheckMonitor(SMonitor*);
|
||||||
void ensurePoolBuffersPresent();
|
void ensurePoolBuffersPresent();
|
||||||
SPoolBuffer* getPoolBuffer(SMonitor*, CWallpaperTarget*);
|
SPoolBuffer* getPoolBuffer(SMonitor*, CWallpaperTarget*);
|
||||||
void unloadWallpaper(const std::string&);
|
void unloadWallpaper(const std::string&);
|
||||||
void createSeat(wl_seat*);
|
void createSeat(SP<CCWlSeat>);
|
||||||
bool lockSingleInstance(); // fails on multi-instance
|
bool lockSingleInstance(); // fails on multi-instance
|
||||||
void unlockSingleInstance();
|
void unlockSingleInstance();
|
||||||
|
|
||||||
std::mutex m_mtTickMutex;
|
std::mutex m_mtTickMutex;
|
||||||
|
|
||||||
SMonitor* m_pLastMonitor = nullptr;
|
SMonitor* m_pLastMonitor = nullptr;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_bShouldExit = false;
|
bool m_bShouldExit = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "ConfigManager.hpp"
|
#include "ConfigManager.hpp"
|
||||||
#include "../Hyprpaper.hpp"
|
#include "../Hyprpaper.hpp"
|
||||||
#include <hyprutils/path/Path.hpp>
|
#include <hyprutils/path/Path.hpp>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
static Hyprlang::CParseResult handleWallpaper(const char* C, const char* V) {
|
static Hyprlang::CParseResult handleWallpaper(const char* C, const char* V) {
|
||||||
const std::string COMMAND = C;
|
const std::string COMMAND = C;
|
||||||
|
@ -12,19 +13,19 @@ static Hyprlang::CParseResult handleWallpaper(const char* C, const char* V) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto MONITOR = VALUE.substr(0, VALUE.find_first_of(','));
|
auto MONITOR = VALUE.substr(0, VALUE.find_first_of(','));
|
||||||
auto WALLPAPER = g_pConfigManager->trimPath(VALUE.substr(VALUE.find_first_of(',') + 1));
|
auto WALLPAPER = g_pConfigManager->trimPath(VALUE.substr(VALUE.find_first_of(',') + 1));
|
||||||
|
|
||||||
bool contain = false;
|
bool contain = false;
|
||||||
|
|
||||||
if (WALLPAPER.find("contain:") == 0) {
|
if (WALLPAPER.find("contain:") == 0) {
|
||||||
WALLPAPER = WALLPAPER.substr(8);
|
WALLPAPER = WALLPAPER.substr(8);
|
||||||
contain = true;
|
contain = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WALLPAPER[0] == '~') {
|
if (WALLPAPER[0] == '~') {
|
||||||
static const char* const ENVHOME = getenv("HOME");
|
static const char* const ENVHOME = getenv("HOME");
|
||||||
WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1);
|
WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
|
@ -34,20 +35,21 @@ static Hyprlang::CParseResult handleWallpaper(const char* C, const char* V) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (std::find(g_pConfigManager->m_dRequestedPreloads.begin(), g_pConfigManager->m_dRequestedPreloads.end(), WALLPAPER) == g_pConfigManager->m_dRequestedPreloads.end() && !g_pHyprpaper->isPreloaded(WALLPAPER)) {
|
if (std::find(g_pConfigManager->m_dRequestedPreloads.begin(), g_pConfigManager->m_dRequestedPreloads.end(), WALLPAPER) == g_pConfigManager->m_dRequestedPreloads.end() &&
|
||||||
|
!g_pHyprpaper->isPreloaded(WALLPAPER)) {
|
||||||
result.setError("wallpaper failed (not preloaded)");
|
result.setError("wallpaper failed (not preloaded)");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pHyprpaper->clearWallpaperFromMonitor(MONITOR);
|
g_pHyprpaper->clearWallpaperFromMonitor(MONITOR);
|
||||||
g_pHyprpaper->m_mMonitorActiveWallpapers[MONITOR] = WALLPAPER;
|
g_pHyprpaper->m_mMonitorActiveWallpapers[MONITOR] = WALLPAPER;
|
||||||
g_pHyprpaper->m_mMonitorWallpaperRenderData[MONITOR].contain = contain;
|
g_pHyprpaper->m_mMonitorWallpaperRenderData[MONITOR].contain = contain;
|
||||||
|
|
||||||
if (MONITOR.empty()) {
|
if (MONITOR.empty()) {
|
||||||
for (auto& m : g_pHyprpaper->m_vMonitors) {
|
for (auto& m : g_pHyprpaper->m_vMonitors) {
|
||||||
if (!m->hasATarget || m->wildcard) {
|
if (!m->hasATarget || m->wildcard) {
|
||||||
g_pHyprpaper->clearWallpaperFromMonitor(m->name);
|
g_pHyprpaper->clearWallpaperFromMonitor(m->name);
|
||||||
g_pHyprpaper->m_mMonitorActiveWallpapers[m->name] = WALLPAPER;
|
g_pHyprpaper->m_mMonitorActiveWallpapers[m->name] = WALLPAPER;
|
||||||
g_pHyprpaper->m_mMonitorWallpaperRenderData[m->name].contain = contain;
|
g_pHyprpaper->m_mMonitorWallpaperRenderData[m->name].contain = contain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,13 +63,13 @@ static Hyprlang::CParseResult handleWallpaper(const char* C, const char* V) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static Hyprlang::CParseResult handlePreload(const char* C, const char* V) {
|
static Hyprlang::CParseResult handlePreload(const char* C, const char* V) {
|
||||||
const std::string COMMAND = C;
|
const std::string COMMAND = C;
|
||||||
const std::string VALUE = V;
|
const std::string VALUE = V;
|
||||||
auto WALLPAPER = VALUE;
|
auto WALLPAPER = VALUE;
|
||||||
|
|
||||||
if (WALLPAPER[0] == '~') {
|
if (WALLPAPER[0] == '~') {
|
||||||
static const char* const ENVHOME = getenv("HOME");
|
static const char* const ENVHOME = getenv("HOME");
|
||||||
WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1);
|
WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::error_code ec;
|
std::error_code ec;
|
||||||
|
@ -84,8 +86,8 @@ static Hyprlang::CParseResult handlePreload(const char* C, const char* V) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static Hyprlang::CParseResult handleUnloadAll(const char* C, const char* V) {
|
static Hyprlang::CParseResult handleUnloadAll(const char* C, const char* V) {
|
||||||
const std::string COMMAND = C;
|
const std::string COMMAND = C;
|
||||||
const std::string VALUE = V;
|
const std::string VALUE = V;
|
||||||
std::vector<std::string> toUnload;
|
std::vector<std::string> toUnload;
|
||||||
|
|
||||||
for (auto& [name, target] : g_pHyprpaper->m_mWallpaperTargets) {
|
for (auto& [name, target] : g_pHyprpaper->m_mWallpaperTargets) {
|
||||||
|
@ -112,16 +114,16 @@ static Hyprlang::CParseResult handleUnloadAll(const char* C, const char* V) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static Hyprlang::CParseResult handleUnload(const char* C, const char* V) {
|
static Hyprlang::CParseResult handleUnload(const char* C, const char* V) {
|
||||||
const std::string COMMAND = C;
|
const std::string COMMAND = C;
|
||||||
const std::string VALUE = V;
|
const std::string VALUE = V;
|
||||||
auto WALLPAPER = VALUE;
|
auto WALLPAPER = VALUE;
|
||||||
|
|
||||||
if (VALUE == "all" || VALUE == "unused")
|
if (VALUE == "all" || VALUE == "unused")
|
||||||
return handleUnloadAll(C, V);
|
return handleUnloadAll(C, V);
|
||||||
|
|
||||||
if (WALLPAPER[0] == '~') {
|
if (WALLPAPER[0] == '~') {
|
||||||
static const char* const ENVHOME = getenv("HOME");
|
static const char* const ENVHOME = getenv("HOME");
|
||||||
WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1);
|
WALLPAPER = std::string(ENVHOME) + WALLPAPER.substr(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_pHyprpaper->unloadWallpaper(WALLPAPER);
|
g_pHyprpaper->unloadWallpaper(WALLPAPER);
|
||||||
|
@ -131,9 +133,9 @@ static Hyprlang::CParseResult handleUnload(const char* C, const char* V) {
|
||||||
|
|
||||||
static Hyprlang::CParseResult handleReload(const char* C, const char* V) {
|
static Hyprlang::CParseResult handleReload(const char* C, const char* V) {
|
||||||
const std::string COMMAND = C;
|
const std::string COMMAND = C;
|
||||||
const std::string VALUE = V;
|
const std::string VALUE = V;
|
||||||
|
|
||||||
auto WALLPAPER = g_pConfigManager->trimPath(VALUE.substr(VALUE.find_first_of(',') + 1));
|
auto WALLPAPER = g_pConfigManager->trimPath(VALUE.substr(VALUE.find_first_of(',') + 1));
|
||||||
|
|
||||||
if (WALLPAPER.find("contain:") == 0) {
|
if (WALLPAPER.find("contain:") == 0) {
|
||||||
WALLPAPER = WALLPAPER.substr(8);
|
WALLPAPER = WALLPAPER.substr(8);
|
||||||
|
@ -189,8 +191,7 @@ void CConfigManager::parse() {
|
||||||
const auto ERROR = config->parse();
|
const auto ERROR = config->parse();
|
||||||
|
|
||||||
if (ERROR.error)
|
if (ERROR.error)
|
||||||
std::cout << "Error in config: \n"
|
std::cout << "Error in config: \n" << ERROR.getError() << "\n";
|
||||||
<< ERROR.getError() << "\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CConfigManager::getMainConfigPath() {
|
std::string CConfigManager::getMainConfigPath() {
|
||||||
|
@ -211,6 +212,6 @@ std::string CConfigManager::trimPath(std::string path) {
|
||||||
|
|
||||||
// trims whitespaces, tabs and new line feeds
|
// trims whitespaces, tabs and new line feeds
|
||||||
size_t pathStartIndex = path.find_first_not_of(" \t\r\n");
|
size_t pathStartIndex = path.find_first_not_of(" \t\r\n");
|
||||||
size_t pathEndIndex = path.find_last_not_of(" \t\r\n");
|
size_t pathEndIndex = path.find_last_not_of(" \t\r\n");
|
||||||
return path.substr(pathStartIndex, pathEndIndex - pathStartIndex + 1);
|
return path.substr(pathStartIndex, pathEndIndex - pathStartIndex + 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,18 +5,18 @@
|
||||||
class CIPCSocket;
|
class CIPCSocket;
|
||||||
|
|
||||||
class CConfigManager {
|
class CConfigManager {
|
||||||
public:
|
public:
|
||||||
// gets all the data from the config
|
// gets all the data from the config
|
||||||
CConfigManager();
|
CConfigManager();
|
||||||
void parse();
|
void parse();
|
||||||
|
|
||||||
std::deque<std::string> m_dRequestedPreloads;
|
std::deque<std::string> m_dRequestedPreloads;
|
||||||
std::string getMainConfigPath();
|
std::string getMainConfigPath();
|
||||||
std::string trimPath(std::string path);
|
std::string trimPath(std::string path);
|
||||||
|
|
||||||
std::unique_ptr<Hyprlang::CConfig> config;
|
std::unique_ptr<Hyprlang::CConfig> config;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class CIPCSocket;
|
friend class CIPCSocket;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,28 +9,17 @@ void Debug::log(LogLevel level, const char* fmt, ...) {
|
||||||
std::string levelstr = "";
|
std::string levelstr = "";
|
||||||
|
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case LOG:
|
case LOG: levelstr = "[LOG] "; break;
|
||||||
levelstr = "[LOG] ";
|
case WARN: levelstr = "[WARN] "; break;
|
||||||
break;
|
case ERR: levelstr = "[ERR] "; break;
|
||||||
case WARN:
|
case CRIT: levelstr = "[CRITICAL] "; break;
|
||||||
levelstr = "[WARN] ";
|
case INFO: levelstr = "[INFO] "; break;
|
||||||
break;
|
default: break;
|
||||||
case ERR:
|
|
||||||
levelstr = "[ERR] ";
|
|
||||||
break;
|
|
||||||
case CRIT:
|
|
||||||
levelstr = "[CRITICAL] ";
|
|
||||||
break;
|
|
||||||
case INFO:
|
|
||||||
levelstr = "[INFO] ";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char buf[LOGMESSAGESIZE] = "";
|
char buf[LOGMESSAGESIZE] = "";
|
||||||
char* outputStr;
|
char* outputStr;
|
||||||
int logLen;
|
int logLen;
|
||||||
|
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
enum LogLevel {
|
enum LogLevel {
|
||||||
NONE = -1,
|
NONE = -1,
|
||||||
LOG = 0,
|
LOG = 0,
|
||||||
WARN,
|
WARN,
|
||||||
ERR,
|
ERR,
|
||||||
CRIT,
|
CRIT,
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include "includes.hpp"
|
#include "includes.hpp"
|
||||||
#include "debug/Log.hpp"
|
#include "debug/Log.hpp"
|
||||||
#include "helpers/Vector2D.hpp"
|
|
||||||
|
|
||||||
// git stuff
|
// git stuff
|
||||||
#ifndef GIT_COMMIT_HASH
|
#ifndef GIT_COMMIT_HASH
|
||||||
|
@ -17,3 +16,11 @@
|
||||||
#ifndef GIT_DIRTY
|
#ifndef GIT_DIRTY
|
||||||
#define GIT_DIRTY "?"
|
#define GIT_DIRTY "?"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <hyprutils/math/Vector2D.hpp>
|
||||||
|
using namespace Hyprutils::Math;
|
||||||
|
|
||||||
|
#include <hyprutils/memory/WeakPtr.hpp>
|
||||||
|
using namespace Hyprutils::Memory;
|
||||||
|
#define SP Hyprutils::Memory::CSharedPointer
|
||||||
|
#define WP Hyprutils::Memory::CWeakPointer
|
||||||
|
|
|
@ -1,164 +0,0 @@
|
||||||
#include "Events.hpp"
|
|
||||||
#include "../Hyprpaper.hpp"
|
|
||||||
|
|
||||||
void Events::geometry(void* data, wl_output* output, int32_t x, int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, const char* make, const char* model, int32_t transform) {
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::mode(void* data, wl_output* output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) {
|
|
||||||
const auto PMONITOR = (SMonitor*)data;
|
|
||||||
|
|
||||||
PMONITOR->size = Vector2D(width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::done(void* data, wl_output* wl_output) {
|
|
||||||
const auto PMONITOR = (SMonitor*)data;
|
|
||||||
|
|
||||||
PMONITOR->readyForLS = true;
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lg(g_pHyprpaper->m_mtTickMutex);
|
|
||||||
if (g_pConfigManager) // don't tick if this is the first roundtrip
|
|
||||||
g_pHyprpaper->tick(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::scale(void* data, wl_output* wl_output, int32_t scale) {
|
|
||||||
const auto PMONITOR = (SMonitor*)data;
|
|
||||||
|
|
||||||
PMONITOR->scale = scale;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::name(void* data, wl_output* wl_output, const char* name) {
|
|
||||||
const auto PMONITOR = (SMonitor*)data;
|
|
||||||
|
|
||||||
PMONITOR->name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::description(void* data, wl_output* wl_output, const char* description) {
|
|
||||||
const auto PMONITOR = (SMonitor*)data;
|
|
||||||
// remove comma character from description. This allow monitor specific rules to work on monitor with comma on their description
|
|
||||||
std::string m_description = description;
|
|
||||||
std::erase(m_description, ',');
|
|
||||||
|
|
||||||
PMONITOR->description = m_description;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::handleCapabilities(void* data, wl_seat* wl_seat, uint32_t capabilities) {
|
|
||||||
if (capabilities & WL_SEAT_CAPABILITY_POINTER) {
|
|
||||||
wl_pointer_add_listener(wl_seat_get_pointer(wl_seat), &pointerListener, wl_seat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::handlePointerLeave(void* data, struct wl_pointer* wl_pointer, uint32_t serial, struct wl_surface* surface) {
|
|
||||||
// ignored
|
|
||||||
wl_surface_commit(surface);
|
|
||||||
|
|
||||||
g_pHyprpaper->m_pLastMonitor = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::handlePointerAxis(void* data, wl_pointer* wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) {
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::handlePointerMotion(void* data, struct wl_pointer* wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) {
|
|
||||||
// ignored
|
|
||||||
if (g_pHyprpaper->m_pLastMonitor) {
|
|
||||||
wl_surface_commit(g_pHyprpaper->m_pLastMonitor->pCurrentLayerSurface->pSurface);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::handlePointerButton(void* data, struct wl_pointer* wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t button_state) {
|
|
||||||
// ignored
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::handlePointerEnter(void* data, struct wl_pointer* wl_pointer, uint32_t serial, struct wl_surface* surface, wl_fixed_t surface_x, wl_fixed_t surface_y) {
|
|
||||||
for (auto& mon : g_pHyprpaper->m_vMonitors) {
|
|
||||||
if (mon->pCurrentLayerSurface->pSurface == surface) {
|
|
||||||
g_pHyprpaper->m_pLastMonitor = mon.get();
|
|
||||||
|
|
||||||
wl_surface_set_buffer_scale(mon->pCurrentLayerSurface->pCursorSurface, mon->scale);
|
|
||||||
wl_surface_attach(mon->pCurrentLayerSurface->pCursorSurface, wl_cursor_image_get_buffer(mon->pCurrentLayerSurface->pCursorImg), 0, 0);
|
|
||||||
wl_pointer_set_cursor(wl_pointer, serial, mon->pCurrentLayerSurface->pCursorSurface, mon->pCurrentLayerSurface->pCursorImg->hotspot_x / mon->scale, mon->pCurrentLayerSurface->pCursorImg->hotspot_y / mon->scale);
|
|
||||||
wl_surface_commit(mon->pCurrentLayerSurface->pCursorSurface);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::ls_configure(void* data, zwlr_layer_surface_v1* surface, uint32_t serial, uint32_t width, uint32_t height) {
|
|
||||||
const auto PLAYERSURFACE = (CLayerSurface*)data;
|
|
||||||
|
|
||||||
PLAYERSURFACE->m_pMonitor->size = Vector2D(width, height);
|
|
||||||
PLAYERSURFACE->m_pMonitor->wantsReload = true;
|
|
||||||
PLAYERSURFACE->m_pMonitor->configureSerial = serial;
|
|
||||||
PLAYERSURFACE->m_pMonitor->wantsACK = true;
|
|
||||||
PLAYERSURFACE->m_pMonitor->initialized = true;
|
|
||||||
|
|
||||||
Debug::log(LOG, "configure for %s", PLAYERSURFACE->m_pMonitor->name.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::handleLSClosed(void* data, zwlr_layer_surface_v1* zwlr_layer_surface_v1) {
|
|
||||||
const auto PLAYERSURFACE = (CLayerSurface*)data;
|
|
||||||
|
|
||||||
for (auto& m : g_pHyprpaper->m_vMonitors) {
|
|
||||||
std::erase_if(m->layerSurfaces, [&](const auto& other) { return other.get() == PLAYERSURFACE; });
|
|
||||||
if (m->pCurrentLayerSurface == PLAYERSURFACE) {
|
|
||||||
if (m->layerSurfaces.empty()) {
|
|
||||||
m->pCurrentLayerSurface = nullptr;
|
|
||||||
} else {
|
|
||||||
m->pCurrentLayerSurface = m->layerSurfaces.begin()->get();
|
|
||||||
g_pHyprpaper->recheckMonitor(m.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::handleGlobal(void* data, struct wl_registry* registry, uint32_t name, const char* interface, uint32_t version) {
|
|
||||||
if (strcmp(interface, wl_compositor_interface.name) == 0) {
|
|
||||||
g_pHyprpaper->m_sCompositor = (wl_compositor*)wl_registry_bind(registry, name, &wl_compositor_interface, 4);
|
|
||||||
} else if (strcmp(interface, wl_shm_interface.name) == 0) {
|
|
||||||
g_pHyprpaper->m_sSHM = (wl_shm*)wl_registry_bind(registry, name, &wl_shm_interface, 1);
|
|
||||||
} else if (strcmp(interface, wl_output_interface.name) == 0) {
|
|
||||||
g_pHyprpaper->m_mtTickMutex.lock();
|
|
||||||
|
|
||||||
const auto PMONITOR = g_pHyprpaper->m_vMonitors.emplace_back(std::make_unique<SMonitor>()).get();
|
|
||||||
PMONITOR->wayland_name = name;
|
|
||||||
PMONITOR->name = "";
|
|
||||||
PMONITOR->output = (wl_output*)wl_registry_bind(registry, name, &wl_output_interface, 4);
|
|
||||||
wl_output_add_listener(PMONITOR->output, &Events::outputListener, PMONITOR);
|
|
||||||
|
|
||||||
g_pHyprpaper->m_mtTickMutex.unlock();
|
|
||||||
} else if (strcmp(interface, wl_seat_interface.name) == 0) {
|
|
||||||
g_pHyprpaper->createSeat((wl_seat*)wl_registry_bind(registry, name, &wl_seat_interface, 1));
|
|
||||||
} else if (strcmp(interface, zwlr_layer_shell_v1_interface.name) == 0) {
|
|
||||||
g_pHyprpaper->m_sLayerShell = (zwlr_layer_shell_v1*)wl_registry_bind(registry, name, &zwlr_layer_shell_v1_interface, 1);
|
|
||||||
} else if (strcmp(interface, wp_fractional_scale_manager_v1_interface.name) == 0 && !g_pHyprpaper->m_bNoFractionalScale) {
|
|
||||||
g_pHyprpaper->m_sFractionalScale = (wp_fractional_scale_manager_v1*)wl_registry_bind(registry, name, &wp_fractional_scale_manager_v1_interface, 1);
|
|
||||||
} else if (strcmp(interface, wp_viewporter_interface.name) == 0) {
|
|
||||||
g_pHyprpaper->m_sViewporter = (wp_viewporter*)wl_registry_bind(registry, name, &wp_viewporter_interface, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::handleGlobalRemove(void* data, struct wl_registry* registry, uint32_t name) {
|
|
||||||
for (auto& m : g_pHyprpaper->m_vMonitors) {
|
|
||||||
if (m->wayland_name == name) {
|
|
||||||
Debug::log(LOG, "Destroying output %s", m->name.c_str());
|
|
||||||
g_pHyprpaper->clearWallpaperFromMonitor(m->name);
|
|
||||||
std::erase_if(g_pHyprpaper->m_vMonitors, [&](const auto& other) { return other->wayland_name == name; });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Events::handlePreferredScale(void* data, wp_fractional_scale_v1* fractionalScaleInfo, uint32_t scale) {
|
|
||||||
const double SCALE = scale / 120.0;
|
|
||||||
|
|
||||||
CLayerSurface* const pLS = (CLayerSurface*)data;
|
|
||||||
|
|
||||||
Debug::log(LOG, "handlePreferredScale: %.2lf for %lx", SCALE, pLS);
|
|
||||||
|
|
||||||
if (pLS->fScale != SCALE) {
|
|
||||||
pLS->fScale = SCALE;
|
|
||||||
std::lock_guard<std::mutex> lg(g_pHyprpaper->m_mtTickMutex);
|
|
||||||
pLS->m_pMonitor->wantsReload = true;
|
|
||||||
g_pHyprpaper->tick(true);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,51 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "../defines.hpp"
|
|
||||||
|
|
||||||
namespace Events {
|
|
||||||
void geometry(void *data, wl_output *output, int32_t x, int32_t y, int32_t width_mm, int32_t height_mm, int32_t subpixel, const char *make, const char *model, int32_t transform);
|
|
||||||
|
|
||||||
void mode(void *data, wl_output *output, uint32_t flags, int32_t width, int32_t height, int32_t refresh);
|
|
||||||
|
|
||||||
void done(void *data, wl_output *wl_output);
|
|
||||||
|
|
||||||
void scale(void *data, wl_output *wl_output, int32_t scale);
|
|
||||||
|
|
||||||
void name(void *data, wl_output *wl_output, const char *name);
|
|
||||||
|
|
||||||
void description(void *data, wl_output *wl_output, const char *description);
|
|
||||||
|
|
||||||
void ls_configure(void *data, zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t width, uint32_t height);
|
|
||||||
|
|
||||||
void handleLSClosed(void *data, zwlr_layer_surface_v1 *zwlr_layer_surface_v1);
|
|
||||||
|
|
||||||
void handleGlobal(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version);
|
|
||||||
|
|
||||||
void handleGlobalRemove(void *data, struct wl_registry *registry, uint32_t name);
|
|
||||||
|
|
||||||
void handleCapabilities(void *data, wl_seat *wl_seat, uint32_t capabilities);
|
|
||||||
|
|
||||||
void handlePointerMotion(void *data, struct wl_pointer *wl_pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y);
|
|
||||||
|
|
||||||
void handlePointerButton(void *data, struct wl_pointer *wl_pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t button_state);
|
|
||||||
|
|
||||||
void handlePointerAxis(void *data, wl_pointer *wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value);
|
|
||||||
|
|
||||||
void handlePointerEnter(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface, wl_fixed_t surface_x, wl_fixed_t surface_y);
|
|
||||||
|
|
||||||
void handlePointerLeave(void *data, struct wl_pointer *wl_pointer, uint32_t serial, struct wl_surface *surface);
|
|
||||||
|
|
||||||
void handlePreferredScale(void *data, wp_fractional_scale_v1 *wp_fractional_scale_v1, uint32_t scale);
|
|
||||||
|
|
||||||
inline const wl_output_listener outputListener = {.geometry = geometry, .mode = mode, .done = done, .scale = scale, .name = name, .description = description};
|
|
||||||
|
|
||||||
inline const zwlr_layer_surface_v1_listener layersurfaceListener = { .configure = ls_configure, .closed = handleLSClosed };
|
|
||||||
|
|
||||||
inline const struct wl_registry_listener registryListener = { .global = handleGlobal, .global_remove = handleGlobalRemove };
|
|
||||||
|
|
||||||
inline const wl_pointer_listener pointerListener = { .enter = handlePointerEnter, .leave = handlePointerLeave, .motion = handlePointerMotion, .button = handlePointerButton, .axis = handlePointerAxis };
|
|
||||||
|
|
||||||
inline const wl_seat_listener seatListener = { .capabilities = handleCapabilities };
|
|
||||||
|
|
||||||
inline const wp_fractional_scale_v1_listener scaleListener = { .preferred_scale = handlePreferredScale };
|
|
||||||
}
|
|
|
@ -3,25 +3,26 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
class BmpHeader {
|
class BmpHeader {
|
||||||
public:
|
public:
|
||||||
unsigned char format[2];
|
unsigned char format[2];
|
||||||
uint32_t sizeOfFile;
|
uint32_t sizeOfFile;
|
||||||
uint16_t reserved1;
|
uint16_t reserved1;
|
||||||
uint16_t reserved2;
|
uint16_t reserved2;
|
||||||
uint32_t dataOffset;
|
uint32_t dataOffset;
|
||||||
uint32_t sizeOfBitmapHeader;
|
uint32_t sizeOfBitmapHeader;
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
uint16_t numberOfColors;
|
uint16_t numberOfColors;
|
||||||
uint16_t numberOfBitPerPixel;
|
uint16_t numberOfBitPerPixel;
|
||||||
uint32_t compressionMethod;
|
uint32_t compressionMethod;
|
||||||
uint32_t imageSize;
|
uint32_t imageSize;
|
||||||
uint32_t horizontalResolutionPPM;
|
uint32_t horizontalResolutionPPM;
|
||||||
uint32_t verticalResolutionPPM;
|
uint32_t verticalResolutionPPM;
|
||||||
uint32_t numberOfCollors;
|
uint32_t numberOfCollors;
|
||||||
uint32_t numberOfImportantCollors;
|
uint32_t numberOfImportantCollors;
|
||||||
|
|
||||||
BmpHeader(std::ifstream& file) {
|
BmpHeader(std::ifstream& file) {
|
||||||
file.seekg(0, std::ios::end);
|
file.seekg(0, std::ios::end);
|
||||||
|
@ -59,7 +60,7 @@ public:
|
||||||
if (!imageSize)
|
if (!imageSize)
|
||||||
imageSize = sizeOfFile - dataOffset;
|
imageSize = sizeOfFile - dataOffset;
|
||||||
|
|
||||||
if (imageSize != (width * height * numberOfBitPerPixel/8)) {
|
if (imageSize != (width * height * numberOfBitPerPixel / 8)) {
|
||||||
Debug::log(ERR, "Unable to parse bitmap header: wrong image size");
|
Debug::log(ERR, "Unable to parse bitmap header: wrong image size");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -69,8 +70,8 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
void reflectImage(unsigned char* image, uint32_t numberOfRows, int stride) {
|
void reflectImage(unsigned char* image, uint32_t numberOfRows, int stride) {
|
||||||
int rowStart = 0;
|
int rowStart = 0;
|
||||||
int rowEnd = numberOfRows - 1;
|
int rowEnd = numberOfRows - 1;
|
||||||
std::vector<unsigned char> temp;
|
std::vector<unsigned char> temp;
|
||||||
temp.resize(stride);
|
temp.resize(stride);
|
||||||
while (rowStart < rowEnd) {
|
while (rowStart < rowEnd) {
|
||||||
|
@ -83,8 +84,8 @@ void reflectImage(unsigned char* image, uint32_t numberOfRows, int stride) {
|
||||||
};
|
};
|
||||||
|
|
||||||
void convertRgbToArgb(std::ifstream& imageStream, unsigned char* outputImage, uint32_t newImageSize) {
|
void convertRgbToArgb(std::ifstream& imageStream, unsigned char* outputImage, uint32_t newImageSize) {
|
||||||
uint8_t forthBitCounter = 0;
|
uint8_t forthBitCounter = 0;
|
||||||
unsigned long imgCursor = 0;
|
unsigned long imgCursor = 0;
|
||||||
while (imgCursor < newImageSize) {
|
while (imgCursor < newImageSize) {
|
||||||
imageStream.read(reinterpret_cast<char*>(&outputImage[imgCursor]), 1);
|
imageStream.read(reinterpret_cast<char*>(&outputImage[imgCursor]), 1);
|
||||||
imgCursor++;
|
imgCursor++;
|
||||||
|
@ -104,12 +105,12 @@ cairo_surface_t* BMP::createSurfaceFromBMP(const std::string& path) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ifstream bitmapImageStream(path);
|
std::ifstream bitmapImageStream(path);
|
||||||
BmpHeader bitmapHeader(bitmapImageStream);
|
BmpHeader bitmapHeader(bitmapImageStream);
|
||||||
|
|
||||||
cairo_format_t format = CAIRO_FORMAT_ARGB32;
|
cairo_format_t format = CAIRO_FORMAT_ARGB32;
|
||||||
int stride = cairo_format_stride_for_width (format, bitmapHeader.width);
|
int stride = cairo_format_stride_for_width(format, bitmapHeader.width);
|
||||||
unsigned char* imageData = (unsigned char*) malloc(bitmapHeader.height * stride);
|
unsigned char* imageData = (unsigned char*)malloc(bitmapHeader.height * stride);
|
||||||
|
|
||||||
if (bitmapHeader.numberOfBitPerPixel == 24)
|
if (bitmapHeader.numberOfBitPerPixel == 24)
|
||||||
convertRgbToArgb(bitmapImageStream, imageData, bitmapHeader.height * stride);
|
convertRgbToArgb(bitmapImageStream, imageData, bitmapHeader.height * stride);
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
cairo_surface_t* JPEG::createSurfaceFromJPEG(const std::string& path) {
|
cairo_surface_t* JPEG::createSurfaceFromJPEG(const std::string& path) {
|
||||||
|
|
||||||
|
@ -16,11 +17,11 @@ cairo_surface_t* JPEG::createSurfaceFromJPEG(const std::string& path) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* imageRawData;
|
void* imageRawData;
|
||||||
|
|
||||||
struct stat fileInfo = {};
|
struct stat fileInfo = {};
|
||||||
|
|
||||||
const auto FD = open(path.c_str(), O_RDONLY);
|
const auto FD = open(path.c_str(), O_RDONLY);
|
||||||
|
|
||||||
fstat(FD, &fileInfo);
|
fstat(FD, &fileInfo);
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@ cairo_surface_t* JPEG::createSurfaceFromJPEG(const std::string& path) {
|
||||||
// now the JPEG is in the memory
|
// now the JPEG is in the memory
|
||||||
|
|
||||||
jpeg_decompress_struct decompressStruct = {};
|
jpeg_decompress_struct decompressStruct = {};
|
||||||
jpeg_error_mgr errorManager = {};
|
jpeg_error_mgr errorManager = {};
|
||||||
|
|
||||||
decompressStruct.err = jpeg_std_error(&errorManager);
|
decompressStruct.err = jpeg_std_error(&errorManager);
|
||||||
jpeg_create_decompress(&decompressStruct);
|
jpeg_create_decompress(&decompressStruct);
|
||||||
|
@ -56,13 +57,13 @@ cairo_surface_t* JPEG::createSurfaceFromJPEG(const std::string& path) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto CAIRODATA = cairo_image_surface_get_data(cairoSurface);
|
const auto CAIRODATA = cairo_image_surface_get_data(cairoSurface);
|
||||||
const auto CAIROSTRIDE = cairo_image_surface_get_stride(cairoSurface);
|
const auto CAIROSTRIDE = cairo_image_surface_get_stride(cairoSurface);
|
||||||
JSAMPROW rowRead;
|
JSAMPROW rowRead;
|
||||||
|
|
||||||
while (decompressStruct.output_scanline < decompressStruct.output_height) {
|
while (decompressStruct.output_scanline < decompressStruct.output_height) {
|
||||||
const auto PROW = CAIRODATA + (decompressStruct.output_scanline * CAIROSTRIDE);
|
const auto PROW = CAIRODATA + (decompressStruct.output_scanline * CAIROSTRIDE);
|
||||||
rowRead = PROW;
|
rowRead = PROW;
|
||||||
jpeg_read_scanlines(&decompressStruct, &rowRead, 1);
|
jpeg_read_scanlines(&decompressStruct, &rowRead, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "Vector2D.hpp"
|
#include "../defines.hpp"
|
||||||
|
|
||||||
bool vectorDeltaLessThan(const Vector2D& a, const Vector2D& b, const float& delta);
|
bool vectorDeltaLessThan(const Vector2D& a, const Vector2D& b, const float& delta);
|
||||||
bool vectorDeltaLessThan(const Vector2D& a, const Vector2D& b, const Vector2D& delta);
|
bool vectorDeltaLessThan(const Vector2D& a, const Vector2D& b, const Vector2D& delta);
|
||||||
std::string execAndGet(const char*);
|
std::string execAndGet(const char*);
|
24
src/helpers/Monitor.cpp
Normal file
24
src/helpers/Monitor.cpp
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#include "Monitor.hpp"
|
||||||
|
#include "../Hyprpaper.hpp"
|
||||||
|
|
||||||
|
void SMonitor::registerListeners() {
|
||||||
|
output->setMode([this](CCWlOutput* r, uint32_t flags, int32_t width, int32_t height, int32_t refresh) { size = Vector2D(width, height); });
|
||||||
|
|
||||||
|
output->setDone([this](CCWlOutput* r) {
|
||||||
|
readyForLS = true;
|
||||||
|
std::lock_guard<std::mutex> lg(g_pHyprpaper->m_mtTickMutex);
|
||||||
|
if (g_pConfigManager) // don't tick if this is the first roundtrip
|
||||||
|
g_pHyprpaper->tick(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
output->setScale([this](CCWlOutput* r, int32_t scale_) { scale = scale_; });
|
||||||
|
|
||||||
|
output->setName([this](CCWlOutput* r, const char* name_) { name = name_; });
|
||||||
|
|
||||||
|
output->setDescription([this](CCWlOutput* r, const char* desc_) {
|
||||||
|
std::string desc = desc_;
|
||||||
|
std::erase(desc, ',');
|
||||||
|
|
||||||
|
description = desc;
|
||||||
|
});
|
||||||
|
}
|
|
@ -3,27 +3,30 @@
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
#include "../render/LayerSurface.hpp"
|
#include "../render/LayerSurface.hpp"
|
||||||
#include "PoolBuffer.hpp"
|
#include "PoolBuffer.hpp"
|
||||||
|
#include "protocols/wayland.hpp"
|
||||||
|
|
||||||
struct SMonitor {
|
struct SMonitor {
|
||||||
std::string name = "";
|
std::string name = "";
|
||||||
std::string description = "";
|
std::string description = "";
|
||||||
wl_output* output = nullptr;
|
SP<CCWlOutput> output;
|
||||||
uint32_t wayland_name = 0;
|
uint32_t wayland_name = 0;
|
||||||
Vector2D size;
|
Vector2D size;
|
||||||
int scale;
|
int scale;
|
||||||
|
|
||||||
bool readyForLS = false;
|
bool readyForLS = false;
|
||||||
bool hasATarget = true;
|
bool hasATarget = true;
|
||||||
|
|
||||||
bool wildcard = true;
|
bool wildcard = true;
|
||||||
|
|
||||||
uint32_t configureSerial = 0;
|
uint32_t configureSerial = 0;
|
||||||
SPoolBuffer buffer;
|
SPoolBuffer buffer;
|
||||||
|
|
||||||
bool wantsReload = false;
|
bool wantsReload = false;
|
||||||
bool wantsACK = false;
|
bool wantsACK = false;
|
||||||
bool initialized = false;
|
bool initialized = false;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<CLayerSurface>> layerSurfaces;
|
std::vector<std::unique_ptr<CLayerSurface>> layerSurfaces;
|
||||||
CLayerSurface* pCurrentLayerSurface = nullptr;
|
CLayerSurface* pCurrentLayerSurface = nullptr;
|
||||||
|
|
||||||
|
void registerListeners();
|
||||||
};
|
};
|
|
@ -1,17 +1,18 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
|
#include "protocols/wayland.hpp"
|
||||||
|
|
||||||
class CWallpaperTarget;
|
class CWallpaperTarget;
|
||||||
|
|
||||||
struct SPoolBuffer {
|
struct SPoolBuffer {
|
||||||
wl_buffer* buffer = nullptr;
|
SP<CCWlBuffer> buffer = nullptr;
|
||||||
cairo_surface_t* surface = nullptr;
|
cairo_surface_t* surface = nullptr;
|
||||||
cairo_t* cairo = nullptr;
|
cairo_t* cairo = nullptr;
|
||||||
void* data = nullptr;
|
void* data = nullptr;
|
||||||
size_t size = 0;
|
size_t size = 0;
|
||||||
std::string name = "";
|
std::string name = "";
|
||||||
|
|
||||||
std::string target = "";
|
std::string target = "";
|
||||||
Vector2D pixelSize;
|
Vector2D pixelSize;
|
||||||
};
|
};
|
|
@ -1,23 +0,0 @@
|
||||||
#include "Vector2D.hpp"
|
|
||||||
|
|
||||||
Vector2D::Vector2D(double xx, double yy) {
|
|
||||||
x = xx;
|
|
||||||
y = yy;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2D::Vector2D() { x = 0; y = 0; }
|
|
||||||
Vector2D::~Vector2D() = default;
|
|
||||||
|
|
||||||
double Vector2D::normalize() {
|
|
||||||
// get max abs
|
|
||||||
const auto max = abs(x) > abs(y) ? abs(x) : abs(y);
|
|
||||||
|
|
||||||
x /= max;
|
|
||||||
y /= max;
|
|
||||||
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2D Vector2D::floor() const {
|
|
||||||
return {static_cast<int>(x), static_cast<int>(y)};
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
class Vector2D {
|
|
||||||
public:
|
|
||||||
Vector2D(double, double);
|
|
||||||
Vector2D();
|
|
||||||
~Vector2D();
|
|
||||||
|
|
||||||
double x = 0;
|
|
||||||
double y = 0;
|
|
||||||
|
|
||||||
// returns the scale
|
|
||||||
double normalize();
|
|
||||||
|
|
||||||
Vector2D operator+(const Vector2D a) const {
|
|
||||||
return Vector2D(this->x + a.x, this->y + a.y);
|
|
||||||
}
|
|
||||||
Vector2D operator-(const Vector2D a) const {
|
|
||||||
return Vector2D(this->x - a.x, this->y - a.y);
|
|
||||||
}
|
|
||||||
Vector2D operator*(const float a) const {
|
|
||||||
return Vector2D(this->x * a, this->y * a);
|
|
||||||
}
|
|
||||||
Vector2D operator/(const float a) const {
|
|
||||||
return Vector2D(this->x / a, this->y / a);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator==(const Vector2D& a) const {
|
|
||||||
return a.x == x && a.y == y;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool operator!=(const Vector2D& a) const {
|
|
||||||
return a.x != x || a.y != y;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2D floor() const;
|
|
||||||
};
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
#include <webp/decode.h>
|
#include <webp/decode.h>
|
||||||
|
|
||||||
cairo_surface_t* WEBP::createSurfaceFromWEBP(const std::string& path) {
|
cairo_surface_t* WEBP::createSurfaceFromWEBP(const std::string& path) {
|
||||||
|
@ -13,11 +14,11 @@ cairo_surface_t* WEBP::createSurfaceFromWEBP(const std::string& path) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* imageRawData;
|
void* imageRawData;
|
||||||
|
|
||||||
struct stat fileInfo = {};
|
struct stat fileInfo = {};
|
||||||
|
|
||||||
const auto FD = open(path.c_str(), O_RDONLY);
|
const auto FD = open(path.c_str(), O_RDONLY);
|
||||||
|
|
||||||
fstat(FD, &fileInfo);
|
fstat(FD, &fileInfo);
|
||||||
|
|
||||||
|
@ -42,32 +43,31 @@ cairo_surface_t* WEBP::createSurfaceFromWEBP(const std::string& path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto HEIGHT = config.input.height;
|
const auto HEIGHT = config.input.height;
|
||||||
const auto WIDTH = config.input.width;
|
const auto WIDTH = config.input.width;
|
||||||
|
|
||||||
auto cairoSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT);
|
auto cairoSurface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, WIDTH, HEIGHT);
|
||||||
if (cairo_surface_status(cairoSurface) != CAIRO_STATUS_SUCCESS) {
|
if (cairo_surface_status(cairoSurface) != CAIRO_STATUS_SUCCESS) {
|
||||||
Debug::log(CRIT, "createSurfaceFromWEBP: Cairo Failed (?)");
|
Debug::log(CRIT, "createSurfaceFromWEBP: Cairo Failed (?)");
|
||||||
cairo_surface_destroy(cairoSurface);
|
cairo_surface_destroy(cairoSurface);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
config.output.colorspace = MODE_bgrA;
|
config.output.colorspace = MODE_bgrA;
|
||||||
#else
|
#else
|
||||||
config.output.colorspace = MODE_Argb;
|
config.output.colorspace = MODE_Argb;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const auto CAIRODATA = cairo_image_surface_get_data(cairoSurface);
|
const auto CAIRODATA = cairo_image_surface_get_data(cairoSurface);
|
||||||
const auto CAIROSTRIDE = cairo_image_surface_get_stride(cairoSurface);
|
const auto CAIROSTRIDE = cairo_image_surface_get_stride(cairoSurface);
|
||||||
|
|
||||||
config.options.no_fancy_upsampling = 1;
|
config.options.no_fancy_upsampling = 1;
|
||||||
config.output.u.RGBA.rgba = CAIRODATA;
|
config.output.u.RGBA.rgba = CAIRODATA;
|
||||||
config.output.u.RGBA.stride = CAIROSTRIDE;
|
config.output.u.RGBA.stride = CAIROSTRIDE;
|
||||||
config.output.u.RGBA.size = CAIROSTRIDE * HEIGHT;
|
config.output.u.RGBA.size = CAIROSTRIDE * HEIGHT;
|
||||||
config.output.is_external_memory = 1;
|
config.output.is_external_memory = 1;
|
||||||
config.output.width = WIDTH;
|
config.output.width = WIDTH;
|
||||||
config.output.height = HEIGHT;
|
config.output.height = HEIGHT;
|
||||||
|
|
||||||
if (WebPDecode((const unsigned char*)imageRawData, fileInfo.st_size, &config) != VP8_STATUS_OK) {
|
if (WebPDecode((const unsigned char*)imageRawData, fileInfo.st_size, &config) != VP8_STATUS_OK) {
|
||||||
Debug::log(CRIT, "createSurfaceFromWEBP: WebP Decode Failed (?)");
|
Debug::log(CRIT, "createSurfaceFromWEBP: WebP Decode Failed (?)");
|
||||||
|
@ -80,5 +80,4 @@ cairo_surface_t* WEBP::createSurfaceFromWEBP(const std::string& path) {
|
||||||
WebPFreeDecBuffer(&config.output);
|
WebPFreeDecBuffer(&config.output);
|
||||||
|
|
||||||
return cairoSurface;
|
return cairoSurface;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,23 +10,6 @@
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
#define class _class
|
|
||||||
#define namespace _namespace
|
|
||||||
#define static
|
|
||||||
|
|
||||||
extern "C" {
|
|
||||||
#include "wlr-layer-shell-unstable-v1-protocol.h"
|
|
||||||
#include "xdg-shell-protocol.h"
|
|
||||||
#include "fractional-scale-v1-protocol.h"
|
|
||||||
#include "viewporter-protocol.h"
|
|
||||||
#include <wayland-client.h>
|
|
||||||
#include <wayland-cursor.h>
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef class
|
|
||||||
#undef namespace
|
|
||||||
#undef static
|
|
||||||
|
|
||||||
#include <GLES3/gl32.h>
|
#include <GLES3/gl32.h>
|
||||||
#include <GLES3/gl3ext.h>
|
#include <GLES3/gl3ext.h>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
@ -39,8 +22,3 @@ extern "C" {
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <wayland-client.h>
|
#include <wayland-client.h>
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <filesystem>
|
|
||||||
#include <thread>
|
|
||||||
#include <unordered_map>
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <sys/un.h>
|
#include <sys/un.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
void CIPCSocket::initialize() {
|
void CIPCSocket::initialize() {
|
||||||
std::thread([&]() {
|
std::thread([&]() {
|
||||||
|
@ -22,15 +23,15 @@ void CIPCSocket::initialize() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX};
|
sockaddr_un SERVERADDRESS = {.sun_family = AF_UNIX};
|
||||||
|
|
||||||
const auto HISenv = getenv("HYPRLAND_INSTANCE_SIGNATURE");
|
const auto HISenv = getenv("HYPRLAND_INSTANCE_SIGNATURE");
|
||||||
const auto RUNTIMEdir = getenv("XDG_RUNTIME_DIR");
|
const auto RUNTIMEdir = getenv("XDG_RUNTIME_DIR");
|
||||||
const std::string USERID = std::to_string(getpwuid(getuid())->pw_uid);
|
const std::string USERID = std::to_string(getpwuid(getuid())->pw_uid);
|
||||||
|
|
||||||
const auto USERDIR = RUNTIMEdir ? RUNTIMEdir + std::string{"/hypr/"} : "/run/user/" + USERID + "/hypr/";
|
const auto USERDIR = RUNTIMEdir ? RUNTIMEdir + std::string{"/hypr/"} : "/run/user/" + USERID + "/hypr/";
|
||||||
|
|
||||||
std::string socketPath = HISenv ? USERDIR + std::string(HISenv) + "/.hyprpaper.sock" : USERDIR + ".hyprpaper.sock";
|
std::string socketPath = HISenv ? USERDIR + std::string(HISenv) + "/.hyprpaper.sock" : USERDIR + ".hyprpaper.sock";
|
||||||
|
|
||||||
if (!HISenv)
|
if (!HISenv)
|
||||||
mkdir(USERDIR.c_str(), S_IRWXU);
|
mkdir(USERDIR.c_str(), S_IRWXU);
|
||||||
|
@ -45,9 +46,9 @@ void CIPCSocket::initialize() {
|
||||||
listen(SOCKET, 10);
|
listen(SOCKET, 10);
|
||||||
|
|
||||||
sockaddr_in clientAddress = {};
|
sockaddr_in clientAddress = {};
|
||||||
socklen_t clientSize = sizeof(clientAddress);
|
socklen_t clientSize = sizeof(clientAddress);
|
||||||
|
|
||||||
char readBuffer[1024] = {0};
|
char readBuffer[1024] = {0};
|
||||||
|
|
||||||
Debug::log(LOG, "hyprpaper socket started at %s (fd: %i)", socketPath.c_str(), SOCKET);
|
Debug::log(LOG, "hyprpaper socket started at %s (fd: %i)", socketPath.c_str(), SOCKET);
|
||||||
while (1) {
|
while (1) {
|
||||||
|
@ -60,13 +61,13 @@ void CIPCSocket::initialize() {
|
||||||
Debug::log(LOG, "Accepted incoming socket connection request on fd %i", ACCEPTEDCONNECTION);
|
Debug::log(LOG, "Accepted incoming socket connection request on fd %i", ACCEPTEDCONNECTION);
|
||||||
std::lock_guard<std::mutex> lg(g_pHyprpaper->m_mtTickMutex);
|
std::lock_guard<std::mutex> lg(g_pHyprpaper->m_mtTickMutex);
|
||||||
|
|
||||||
auto messageSize = read(ACCEPTEDCONNECTION, readBuffer, 1024);
|
auto messageSize = read(ACCEPTEDCONNECTION, readBuffer, 1024);
|
||||||
readBuffer[messageSize == 1024 ? 1023 : messageSize] = '\0';
|
readBuffer[messageSize == 1024 ? 1023 : messageSize] = '\0';
|
||||||
if (messageSize == 0)
|
if (messageSize == 0)
|
||||||
break;
|
break;
|
||||||
std::string request(readBuffer);
|
std::string request(readBuffer);
|
||||||
|
|
||||||
m_szRequest = request;
|
m_szRequest = request;
|
||||||
m_bRequestReady = true;
|
m_bRequestReady = true;
|
||||||
|
|
||||||
g_pHyprpaper->tick(true);
|
g_pHyprpaper->tick(true);
|
||||||
|
@ -75,7 +76,7 @@ void CIPCSocket::initialize() {
|
||||||
}
|
}
|
||||||
write(ACCEPTEDCONNECTION, m_szReply.c_str(), m_szReply.length());
|
write(ACCEPTEDCONNECTION, m_szReply.c_str(), m_szReply.length());
|
||||||
m_bReplyReady = false;
|
m_bReplyReady = false;
|
||||||
m_szReply = "";
|
m_szReply = "";
|
||||||
|
|
||||||
} while (1);
|
} while (1);
|
||||||
Debug::log(LOG, "Closing Accepted Connection");
|
Debug::log(LOG, "Closing Accepted Connection");
|
||||||
|
@ -102,8 +103,8 @@ bool CIPCSocket::mainThreadParseRequest() {
|
||||||
Debug::log(LOG, "Received a request: %s", copy.c_str());
|
Debug::log(LOG, "Received a request: %s", copy.c_str());
|
||||||
|
|
||||||
// set default reply
|
// set default reply
|
||||||
m_szReply = "ok";
|
m_szReply = "ok";
|
||||||
m_bReplyReady = true;
|
m_bReplyReady = true;
|
||||||
m_bRequestReady = false;
|
m_bRequestReady = false;
|
||||||
|
|
||||||
// config commands
|
// config commands
|
||||||
|
@ -129,7 +130,7 @@ bool CIPCSocket::mainThreadParseRequest() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_szReply = "";
|
m_szReply = "";
|
||||||
long unsigned int i = 0;
|
long unsigned int i = 0;
|
||||||
for (auto& [name, target] : g_pHyprpaper->m_mWallpaperTargets) {
|
for (auto& [name, target] : g_pHyprpaper->m_mWallpaperTargets) {
|
||||||
m_szReply += name;
|
m_szReply += name;
|
||||||
|
@ -151,7 +152,7 @@ bool CIPCSocket::mainThreadParseRequest() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_szReply = "";
|
m_szReply = "";
|
||||||
long unsigned int i = 0;
|
long unsigned int i = 0;
|
||||||
for (auto& [mon, path1] : g_pHyprpaper->m_mMonitorActiveWallpapers) {
|
for (auto& [mon, path1] : g_pHyprpaper->m_mMonitorActiveWallpapers) {
|
||||||
m_szReply += mon + " = " + path1;
|
m_szReply += mon + " = " + path1;
|
||||||
|
|
|
@ -4,20 +4,18 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
class CIPCSocket {
|
class CIPCSocket {
|
||||||
public:
|
public:
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|
||||||
bool mainThreadParseRequest();
|
bool mainThreadParseRequest();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
std::mutex m_mtRequestMutex;
|
||||||
std::mutex m_mtRequestMutex;
|
|
||||||
std::string m_szRequest = "";
|
std::string m_szRequest = "";
|
||||||
std::string m_szReply = "";
|
std::string m_szReply = "";
|
||||||
|
|
||||||
bool m_bRequestReady = false;
|
bool m_bRequestReady = false;
|
||||||
bool m_bReplyReady = false;
|
bool m_bReplyReady = false;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::unique_ptr<CIPCSocket> g_pIPCSocket;
|
inline std::unique_ptr<CIPCSocket> g_pIPCSocket;
|
14
src/main.cpp
14
src/main.cpp
|
@ -7,7 +7,7 @@ int main(int argc, char** argv, char** envp) {
|
||||||
|
|
||||||
// parse some args
|
// parse some args
|
||||||
std::string configPath;
|
std::string configPath;
|
||||||
bool noFractional = false;
|
bool noFractional = false;
|
||||||
for (int i = 1; i < argc; ++i) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
if ((!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")) && argc >= i + 2) {
|
if ((!strcmp(argv[i], "-c") || !strcmp(argv[i], "--config")) && argc >= i + 2) {
|
||||||
configPath = std::string(argv[++i]);
|
configPath = std::string(argv[++i]);
|
||||||
|
@ -16,18 +16,18 @@ int main(int argc, char** argv, char** envp) {
|
||||||
noFractional = true;
|
noFractional = true;
|
||||||
Debug::log(LOG, "Disabling fractional scaling support!");
|
Debug::log(LOG, "Disabling fractional scaling support!");
|
||||||
} else {
|
} else {
|
||||||
std::cout << "Hyprpaper usage: hyprpaper [arg [...]].\n\nArguments:\n" <<
|
std::cout << "Hyprpaper usage: hyprpaper [arg [...]].\n\nArguments:\n"
|
||||||
"--help -h | Show this help message\n" <<
|
<< "--help -h | Show this help message\n"
|
||||||
"--config -c | Specify config file to use\n" <<
|
<< "--config -c | Specify config file to use\n"
|
||||||
"--no-fractional -n | Disable fractional scaling support\n";
|
<< "--no-fractional -n | Disable fractional scaling support\n";
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// starts
|
// starts
|
||||||
g_pHyprpaper = std::make_unique<CHyprpaper>();
|
g_pHyprpaper = std::make_unique<CHyprpaper>();
|
||||||
g_pHyprpaper->m_szExplicitConfigPath = configPath;
|
g_pHyprpaper->m_szExplicitConfigPath = configPath;
|
||||||
g_pHyprpaper->m_bNoFractionalScale = noFractional;
|
g_pHyprpaper->m_bNoFractionalScale = noFractional;
|
||||||
g_pHyprpaper->init();
|
g_pHyprpaper->init();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -5,62 +5,92 @@
|
||||||
CLayerSurface::CLayerSurface(SMonitor* pMonitor) {
|
CLayerSurface::CLayerSurface(SMonitor* pMonitor) {
|
||||||
m_pMonitor = pMonitor;
|
m_pMonitor = pMonitor;
|
||||||
|
|
||||||
pSurface = wl_compositor_create_surface(g_pHyprpaper->m_sCompositor);
|
pSurface = makeShared<CCWlSurface>(g_pHyprpaper->m_pCompositor->sendCreateSurface());
|
||||||
pCursorSurface = wl_compositor_create_surface(g_pHyprpaper->m_sCompositor);
|
|
||||||
|
|
||||||
if (!pSurface) {
|
if (!pSurface) {
|
||||||
Debug::log(CRIT, "The compositor did not allow hyprpaper a surface!");
|
Debug::log(CRIT, "The compositor did not allow hyprpaper a surface!");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto PINPUTREGION = wl_compositor_create_region(g_pHyprpaper->m_sCompositor);
|
const auto PINPUTREGION = makeShared<CCWlRegion>(g_pHyprpaper->m_pCompositor->sendCreateRegion());
|
||||||
|
|
||||||
if (!PINPUTREGION) {
|
if (!PINPUTREGION) {
|
||||||
Debug::log(CRIT, "The compositor did not allow hyprpaper a region!");
|
Debug::log(CRIT, "The compositor did not allow hyprpaper a region!");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
wl_surface_set_input_region(pSurface, PINPUTREGION);
|
pSurface->sendSetInputRegion(PINPUTREGION.get());
|
||||||
|
|
||||||
pLayerSurface = zwlr_layer_shell_v1_get_layer_surface(g_pHyprpaper->m_sLayerShell, pSurface, pMonitor->output, ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND, "hyprpaper");
|
pLayerSurface = makeShared<CCZwlrLayerSurfaceV1>(
|
||||||
|
g_pHyprpaper->m_pLayerShell->sendGetLayerSurface(pSurface->resource(), pMonitor->output->resource(), ZWLR_LAYER_SHELL_V1_LAYER_BACKGROUND, "hyprpaper"));
|
||||||
|
|
||||||
if (!pLayerSurface) {
|
if (!pLayerSurface) {
|
||||||
Debug::log(CRIT, "The compositor did not allow hyprpaper a layersurface!");
|
Debug::log(CRIT, "The compositor did not allow hyprpaper a layersurface!");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
zwlr_layer_surface_v1_set_size(pLayerSurface, 0, 0);
|
pLayerSurface->sendSetSize(0, 0);
|
||||||
zwlr_layer_surface_v1_set_anchor(pLayerSurface, ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT);
|
pLayerSurface->sendSetAnchor((zwlrLayerSurfaceV1Anchor)(ZWLR_LAYER_SURFACE_V1_ANCHOR_TOP | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT | ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM |
|
||||||
zwlr_layer_surface_v1_set_exclusive_zone(pLayerSurface, -1);
|
ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT));
|
||||||
zwlr_layer_surface_v1_add_listener(pLayerSurface, &Events::layersurfaceListener, this);
|
pLayerSurface->sendSetExclusiveZone(-1);
|
||||||
wl_surface_commit(pSurface);
|
|
||||||
|
|
||||||
wl_region_destroy(PINPUTREGION);
|
pLayerSurface->setConfigure([this](CCZwlrLayerSurfaceV1* r, uint32_t serial, uint32_t x, uint32_t y) {
|
||||||
|
m_pMonitor->size = Vector2D((double)x, (double)y);
|
||||||
|
m_pMonitor->wantsReload = true;
|
||||||
|
m_pMonitor->configureSerial = serial;
|
||||||
|
m_pMonitor->wantsACK = true;
|
||||||
|
m_pMonitor->initialized = true;
|
||||||
|
|
||||||
|
Debug::log(LOG, "configure for %s", m_pMonitor->name.c_str());
|
||||||
|
});
|
||||||
|
|
||||||
|
pLayerSurface->setClosed([this](CCZwlrLayerSurfaceV1* r) {
|
||||||
|
for (auto& m : g_pHyprpaper->m_vMonitors) {
|
||||||
|
std::erase_if(m->layerSurfaces, [&](const auto& other) { return other.get() == this; });
|
||||||
|
if (m->pCurrentLayerSurface == this) {
|
||||||
|
if (m->layerSurfaces.empty()) {
|
||||||
|
m->pCurrentLayerSurface = nullptr;
|
||||||
|
} else {
|
||||||
|
m->pCurrentLayerSurface = m->layerSurfaces.begin()->get();
|
||||||
|
g_pHyprpaper->recheckMonitor(m.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pSurface->sendCommit();
|
||||||
|
|
||||||
// fractional scale, if supported by the compositor
|
// fractional scale, if supported by the compositor
|
||||||
if (g_pHyprpaper->m_sFractionalScale) {
|
if (g_pHyprpaper->m_pFractionalScale && g_pHyprpaper->m_pViewporter) {
|
||||||
pFractionalScaleInfo = wp_fractional_scale_manager_v1_get_fractional_scale(g_pHyprpaper->m_sFractionalScale, pSurface);
|
pFractionalScaleInfo = makeShared<CCWpFractionalScaleV1>(g_pHyprpaper->m_pFractionalScale->sendGetFractionalScale(pSurface->resource()));
|
||||||
wp_fractional_scale_v1_add_listener(pFractionalScaleInfo, &Events::scaleListener, this);
|
pFractionalScaleInfo->setPreferredScale([this](CCWpFractionalScaleV1* r, uint32_t sc120) {
|
||||||
pViewport = wp_viewporter_get_viewport(g_pHyprpaper->m_sViewporter, pSurface);
|
const double SCALE = sc120 / 120.0;
|
||||||
wl_surface_commit(pSurface);
|
|
||||||
}
|
Debug::log(LOG, "handlePreferredScale: %.2lf for %lx", SCALE, this);
|
||||||
|
|
||||||
|
if (fScale != SCALE) {
|
||||||
|
fScale = SCALE;
|
||||||
|
std::lock_guard<std::mutex> lg(g_pHyprpaper->m_mtTickMutex);
|
||||||
|
m_pMonitor->wantsReload = true;
|
||||||
|
g_pHyprpaper->tick(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pViewport = makeShared<CCWpViewport>(g_pHyprpaper->m_pViewporter->sendGetViewport(pSurface->resource()));
|
||||||
|
|
||||||
|
pSurface->sendCommit();
|
||||||
|
} else
|
||||||
|
Debug::log(ERR, "No fractional-scale-v1 / wp-viewporter support from the compositor! fractional scaling will not work.");
|
||||||
|
|
||||||
wl_display_flush(g_pHyprpaper->m_sDisplay);
|
wl_display_flush(g_pHyprpaper->m_sDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
CLayerSurface::~CLayerSurface() {
|
CLayerSurface::~CLayerSurface() {
|
||||||
|
// hyprwayland-scanner will send the destructors automatically. Neat.
|
||||||
if (pCursorTheme)
|
pLayerSurface.reset();
|
||||||
wl_cursor_theme_destroy(pCursorTheme);
|
pFractionalScaleInfo.reset();
|
||||||
|
pViewport.reset();
|
||||||
if (g_pHyprpaper->m_sFractionalScale && pFractionalScaleInfo) {
|
pSurface.reset();
|
||||||
wp_fractional_scale_v1_destroy(pFractionalScaleInfo);
|
|
||||||
|
|
||||||
wp_viewport_destroy(pViewport);
|
|
||||||
}
|
|
||||||
|
|
||||||
zwlr_layer_surface_v1_destroy(pLayerSurface);
|
|
||||||
wl_surface_destroy(pSurface);
|
|
||||||
|
|
||||||
wl_display_flush(g_pHyprpaper->m_sDisplay);
|
wl_display_flush(g_pHyprpaper->m_sDisplay);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +1,23 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../defines.hpp"
|
#include "../defines.hpp"
|
||||||
|
#include "protocols/fractional-scale-v1.hpp"
|
||||||
|
#include "protocols/viewporter.hpp"
|
||||||
|
#include "protocols/wayland.hpp"
|
||||||
|
#include "protocols/wlr-layer-shell-unstable-v1.hpp"
|
||||||
|
|
||||||
struct SMonitor;
|
struct SMonitor;
|
||||||
|
|
||||||
class CLayerSurface {
|
class CLayerSurface {
|
||||||
public:
|
public:
|
||||||
explicit CLayerSurface(SMonitor*);
|
explicit CLayerSurface(SMonitor*);
|
||||||
~CLayerSurface();
|
~CLayerSurface();
|
||||||
|
|
||||||
SMonitor* m_pMonitor = nullptr;
|
SMonitor* m_pMonitor = nullptr;
|
||||||
|
|
||||||
zwlr_layer_surface_v1* pLayerSurface = nullptr;
|
SP<CCZwlrLayerSurfaceV1> pLayerSurface = nullptr;
|
||||||
wl_surface* pSurface = nullptr;
|
SP<CCWlSurface> pSurface = nullptr;
|
||||||
|
SP<CCWpFractionalScaleV1> pFractionalScaleInfo = nullptr;
|
||||||
wl_cursor_theme* pCursorTheme = nullptr;
|
SP<CCWpViewport> pViewport = nullptr;
|
||||||
wl_cursor_image* pCursorImg = nullptr;
|
double fScale = 1.0;
|
||||||
wl_surface* pCursorSurface = nullptr;
|
|
||||||
|
|
||||||
wp_fractional_scale_v1* pFractionalScaleInfo = nullptr;
|
|
||||||
wp_viewport* pViewport = nullptr;
|
|
||||||
double fScale = 1.0;
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "WallpaperTarget.hpp"
|
#include "WallpaperTarget.hpp"
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#include <magic.h>
|
#include <magic.h>
|
||||||
|
|
||||||
CWallpaperTarget::~CWallpaperTarget() {
|
CWallpaperTarget::~CWallpaperTarget() {
|
||||||
|
@ -9,36 +10,36 @@ CWallpaperTarget::~CWallpaperTarget() {
|
||||||
void CWallpaperTarget::create(const std::string& path) {
|
void CWallpaperTarget::create(const std::string& path) {
|
||||||
m_szPath = path;
|
m_szPath = path;
|
||||||
|
|
||||||
const auto BEGINLOAD = std::chrono::system_clock::now();
|
const auto BEGINLOAD = std::chrono::system_clock::now();
|
||||||
|
|
||||||
cairo_surface_t* CAIROSURFACE = nullptr;
|
cairo_surface_t* CAIROSURFACE = nullptr;
|
||||||
const auto len = path.length();
|
const auto len = path.length();
|
||||||
if (path.find(".png") == len - 4 || path.find(".PNG") == len - 4) {
|
if (path.find(".png") == len - 4 || path.find(".PNG") == len - 4) {
|
||||||
CAIROSURFACE = cairo_image_surface_create_from_png(path.c_str());
|
CAIROSURFACE = cairo_image_surface_create_from_png(path.c_str());
|
||||||
} else if (path.find(".jpg") == len - 4 || path.find(".JPG") == len - 4 || path.find(".jpeg") == len - 5 || path.find(".JPEG") == len - 5) {
|
} else if (path.find(".jpg") == len - 4 || path.find(".JPG") == len - 4 || path.find(".jpeg") == len - 5 || path.find(".JPEG") == len - 5) {
|
||||||
CAIROSURFACE = JPEG::createSurfaceFromJPEG(path);
|
CAIROSURFACE = JPEG::createSurfaceFromJPEG(path);
|
||||||
m_bHasAlpha = false;
|
m_bHasAlpha = false;
|
||||||
} else if (path.find(".bmp") == len - 4 || path.find(".BMP") == len - 4) {
|
} else if (path.find(".bmp") == len - 4 || path.find(".BMP") == len - 4) {
|
||||||
CAIROSURFACE = BMP::createSurfaceFromBMP(path);
|
CAIROSURFACE = BMP::createSurfaceFromBMP(path);
|
||||||
m_bHasAlpha = false;
|
m_bHasAlpha = false;
|
||||||
} else if (path.find(".webp") == len - 5 || path.find(".WEBP") == len - 5) {
|
} else if (path.find(".webp") == len - 5 || path.find(".WEBP") == len - 5) {
|
||||||
CAIROSURFACE = WEBP::createSurfaceFromWEBP(path);
|
CAIROSURFACE = WEBP::createSurfaceFromWEBP(path);
|
||||||
} else {
|
} else {
|
||||||
// magic is slow, so only use it when no recognized extension is found
|
// magic is slow, so only use it when no recognized extension is found
|
||||||
auto handle = magic_open(MAGIC_NONE|MAGIC_COMPRESS);
|
auto handle = magic_open(MAGIC_NONE | MAGIC_COMPRESS);
|
||||||
magic_load(handle, nullptr);
|
magic_load(handle, nullptr);
|
||||||
|
|
||||||
const auto type_str = std::string(magic_file(handle, path.c_str()));
|
const auto type_str = std::string(magic_file(handle, path.c_str()));
|
||||||
const auto first_word = type_str.substr(0, type_str.find(" "));
|
const auto first_word = type_str.substr(0, type_str.find(" "));
|
||||||
|
|
||||||
if (first_word == "PNG") {
|
if (first_word == "PNG") {
|
||||||
CAIROSURFACE = cairo_image_surface_create_from_png(path.c_str());
|
CAIROSURFACE = cairo_image_surface_create_from_png(path.c_str());
|
||||||
} else if (first_word == "JPEG") {
|
} else if (first_word == "JPEG") {
|
||||||
CAIROSURFACE = JPEG::createSurfaceFromJPEG(path);
|
CAIROSURFACE = JPEG::createSurfaceFromJPEG(path);
|
||||||
m_bHasAlpha = false;
|
m_bHasAlpha = false;
|
||||||
} else if (first_word == "BMP") {
|
} else if (first_word == "BMP") {
|
||||||
CAIROSURFACE = BMP::createSurfaceFromBMP(path);
|
CAIROSURFACE = BMP::createSurfaceFromBMP(path);
|
||||||
m_bHasAlpha = false;
|
m_bHasAlpha = false;
|
||||||
} else {
|
} else {
|
||||||
Debug::log(CRIT, "unrecognized image %s", path.c_str());
|
Debug::log(CRIT, "unrecognized image %s", path.c_str());
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -50,7 +51,7 @@ void CWallpaperTarget::create(const std::string& path) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_vSize = { cairo_image_surface_get_width(CAIROSURFACE), cairo_image_surface_get_height(CAIROSURFACE) };
|
m_vSize = {cairo_image_surface_get_width(CAIROSURFACE), cairo_image_surface_get_height(CAIROSURFACE)};
|
||||||
|
|
||||||
const auto MS = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now() - BEGINLOAD).count() / 1000.f;
|
const auto MS = std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now() - BEGINLOAD).count() / 1000.f;
|
||||||
|
|
||||||
|
|
|
@ -6,17 +6,16 @@
|
||||||
#include "../helpers/Webp.hpp"
|
#include "../helpers/Webp.hpp"
|
||||||
|
|
||||||
class CWallpaperTarget {
|
class CWallpaperTarget {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
~CWallpaperTarget();
|
~CWallpaperTarget();
|
||||||
|
|
||||||
void create(const std::string& path);
|
void create(const std::string& path);
|
||||||
|
|
||||||
std::string m_szPath;
|
std::string m_szPath;
|
||||||
|
|
||||||
Vector2D m_vSize;
|
Vector2D m_vSize;
|
||||||
|
|
||||||
bool m_bHasAlpha = true;
|
bool m_bHasAlpha = true;
|
||||||
|
|
||||||
cairo_surface_t* m_pCairoSurface;
|
cairo_surface_t* m_pCairoSurface;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue