forked from quickshell/quickshell
		
	feat: basic QtShell and ShellComponent types
This commit is contained in:
		
						commit
						23837e5195
					
				
					 9 changed files with 483 additions and 0 deletions
				
			
		
							
								
								
									
										82
									
								
								.clang-format
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								.clang-format
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,82 @@
 | 
				
			||||||
 | 
					AlignArrayOfStructures: None
 | 
				
			||||||
 | 
					AlignAfterOpenBracket: BlockIndent
 | 
				
			||||||
 | 
					AllowShortBlocksOnASingleLine: Always
 | 
				
			||||||
 | 
					AllowShortCaseLabelsOnASingleLine: true
 | 
				
			||||||
 | 
					AllowShortEnumsOnASingleLine: true
 | 
				
			||||||
 | 
					AllowShortFunctionsOnASingleLine: All
 | 
				
			||||||
 | 
					AllowShortIfStatementsOnASingleLine: AllIfsAndElse
 | 
				
			||||||
 | 
					AllowShortLambdasOnASingleLine: All
 | 
				
			||||||
 | 
					AllowShortLoopsOnASingleLine: true
 | 
				
			||||||
 | 
					BinPackArguments: false
 | 
				
			||||||
 | 
					BinPackParameters: false
 | 
				
			||||||
 | 
					Cpp11BracedListStyle: true
 | 
				
			||||||
 | 
					LambdaBodyIndentation: Signature
 | 
				
			||||||
 | 
					UseCRLF: false
 | 
				
			||||||
 | 
					UseTab: ForIndentation
 | 
				
			||||||
 | 
					SpacesInSquareBrackets: false
 | 
				
			||||||
 | 
					SpacesInParentheses: false
 | 
				
			||||||
 | 
					SpacesInCStyleCastParentheses: false
 | 
				
			||||||
 | 
					SpacesInAngles: Never
 | 
				
			||||||
 | 
					SpaceInEmptyParentheses: false
 | 
				
			||||||
 | 
					SpaceInEmptyBlock: false
 | 
				
			||||||
 | 
					SpaceBeforeSquareBrackets: false
 | 
				
			||||||
 | 
					SpaceBeforeRangeBasedForLoopColon: false
 | 
				
			||||||
 | 
					SpaceAfterCStyleCast: true
 | 
				
			||||||
 | 
					SpaceAfterLogicalNot: false
 | 
				
			||||||
 | 
					SpaceAfterTemplateKeyword: true
 | 
				
			||||||
 | 
					SpaceBeforeCaseColon: false
 | 
				
			||||||
 | 
					SpaceBeforeCpp11BracedList: true
 | 
				
			||||||
 | 
					SpaceBeforeCtorInitializerColon: false
 | 
				
			||||||
 | 
					SpaceBeforeInheritanceColon: false
 | 
				
			||||||
 | 
					SpaceBeforeParens: ControlStatementsExceptControlMacros
 | 
				
			||||||
 | 
					SortIncludes: CaseSensitive
 | 
				
			||||||
 | 
					PointerAlignment: Left
 | 
				
			||||||
 | 
					PackConstructorInitializers: NextLine
 | 
				
			||||||
 | 
					LineEnding: LF
 | 
				
			||||||
 | 
					InsertBraces: false
 | 
				
			||||||
 | 
					BreakConstructorInitializers: AfterColon
 | 
				
			||||||
 | 
					BreakBeforeBraces: Custom
 | 
				
			||||||
 | 
					BreakInheritanceList: AfterColon
 | 
				
			||||||
 | 
					AllowAllParametersOfDeclarationOnNextLine: false
 | 
				
			||||||
 | 
					AllowAllArgumentsOnNextLine: false
 | 
				
			||||||
 | 
					AlwaysBreakTemplateDeclarations: Yes
 | 
				
			||||||
 | 
					BraceWrapping:
 | 
				
			||||||
 | 
					  AfterClass: false
 | 
				
			||||||
 | 
					  AfterFunction: false
 | 
				
			||||||
 | 
					  AfterCaseLabel: false
 | 
				
			||||||
 | 
					  AfterEnum: false
 | 
				
			||||||
 | 
					  AfterNamespace: false
 | 
				
			||||||
 | 
					  AfterStruct: false
 | 
				
			||||||
 | 
					  AfterUnion: false
 | 
				
			||||||
 | 
					  AfterExternBlock: false
 | 
				
			||||||
 | 
					  BeforeCatch: false
 | 
				
			||||||
 | 
					  BeforeElse: false
 | 
				
			||||||
 | 
					  BeforeLambdaBody: false
 | 
				
			||||||
 | 
					  BeforeWhile: false
 | 
				
			||||||
 | 
					  IndentBraces: false
 | 
				
			||||||
 | 
					  SplitEmptyFunction: true
 | 
				
			||||||
 | 
					  SplitEmptyRecord: false
 | 
				
			||||||
 | 
					  SplitEmptyNamespace: false
 | 
				
			||||||
 | 
					  AfterControlStatement: MultiLine
 | 
				
			||||||
 | 
					BreakBeforeBinaryOperators: NonAssignment
 | 
				
			||||||
 | 
					BreakBeforeTernaryOperators: true
 | 
				
			||||||
 | 
					AlignOperands: AlignAfterOperator
 | 
				
			||||||
 | 
					InsertTrailingCommas: Wrapped
 | 
				
			||||||
 | 
					MaxEmptyLinesToKeep: 1
 | 
				
			||||||
 | 
					ExperimentalAutoDetectBinPacking: false
 | 
				
			||||||
 | 
					ColumnLimit: 100
 | 
				
			||||||
 | 
					IndentWidth: 2
 | 
				
			||||||
 | 
					TabWidth: 2
 | 
				
			||||||
 | 
					AllowAllConstructorInitializersOnNextLine: false
 | 
				
			||||||
 | 
					ConstructorInitializerAllOnOneLineOrOnePerLine: true
 | 
				
			||||||
 | 
					NamespaceIndentation: None
 | 
				
			||||||
 | 
					IncludeBlocks: Regroup
 | 
				
			||||||
 | 
					IncludeCategories:
 | 
				
			||||||
 | 
					  - Regex: '^<(cassert|cctype|cerrno|cfenv|cfloat|cinttypes|climits|clocale|cmath|csetjmp|csignal|cstdarg|cstdbool|cstddef|cstdint|cstdio|cstdlib|cstring|ctime|cuchar|cwchar|cwctype|algorithm|any|array|atomic|bitset|chrono|codecvt|complex|condition_variable|deque|exception|filesystem|forward_list|fstream|functional|future|initializer_list|iomanip|ios|iosfwd|iostream|istream|iterator|latch|limits|list|locale|map|memory|mutex|new|numeric|optional|ostream|queue|random|ratio|regex|scoped_allocator|set|shared_mutex|sstream|stack|stdexcept|streambuf|string|string_view|strstream|syncstream|system_error|thread|tuple|type_traits|typeindex|typeinfo|unordered_map|unordered_set|utility|valarray|variant|vector|version|assert.h|ctype.h|errno.h|fenv.h|float.h|inttypes.h|limits.h|locale.h|math.h|setjmp.h|signal.h|stdarg.h|stddef.h|stdint.h|stdio.h|stdlib.h|string.h|time.h|uchar.h|wchar.h|wctype.h)>$'
 | 
				
			||||||
 | 
					    Priority: 0
 | 
				
			||||||
 | 
					  - Regex: '^<.*>$'
 | 
				
			||||||
 | 
					    Priority: 1
 | 
				
			||||||
 | 
					  - Regex: '^".*"$'
 | 
				
			||||||
 | 
					    Priority: 2
 | 
				
			||||||
 | 
					  - Regex: '.+'
 | 
				
			||||||
 | 
					    Priority: 3
 | 
				
			||||||
							
								
								
									
										54
									
								
								.clang-tidy
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								.clang-tidy
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,54 @@
 | 
				
			||||||
 | 
					WarningsAsErrors: '*'
 | 
				
			||||||
 | 
					HeaderFilterRegex: '.*\.hpp'
 | 
				
			||||||
 | 
					FormatStyle: file
 | 
				
			||||||
 | 
					Checks: >
 | 
				
			||||||
 | 
					  -*,
 | 
				
			||||||
 | 
					  bugprone-*,
 | 
				
			||||||
 | 
					  -bugprone-easily-swappable-parameters,
 | 
				
			||||||
 | 
					  concurrency-*,
 | 
				
			||||||
 | 
					  cppcoreguidelines-*,
 | 
				
			||||||
 | 
					  -cppcoreguidelines-owning-memory,
 | 
				
			||||||
 | 
					  -cppcoreguidelines-avoid-magic-numbers,
 | 
				
			||||||
 | 
					  -cppcoreguidelines-pro-bounds-constant-array-index,
 | 
				
			||||||
 | 
					  -cppcoreguidelines-avoid-const-or-ref-data-members,
 | 
				
			||||||
 | 
					  google-build-using-namespace.
 | 
				
			||||||
 | 
					  google-explicit-constructor,
 | 
				
			||||||
 | 
					  google-global-names-in-headers,
 | 
				
			||||||
 | 
					  google-readability-casting,
 | 
				
			||||||
 | 
					  google-runtime-int,
 | 
				
			||||||
 | 
					  google-runtime-operator,
 | 
				
			||||||
 | 
					  misc-*,
 | 
				
			||||||
 | 
					  -misc-no-recursion,
 | 
				
			||||||
 | 
					  -misc-non-private-member-variables-in-classes,
 | 
				
			||||||
 | 
					  modernize-*,
 | 
				
			||||||
 | 
					  -modernize-return-braced-init-list,
 | 
				
			||||||
 | 
					  -modernize-use-trailing-return-type,
 | 
				
			||||||
 | 
					  performance-*,
 | 
				
			||||||
 | 
					  portability-std-allocator-const,
 | 
				
			||||||
 | 
					  readability-*,
 | 
				
			||||||
 | 
					  -readability-function-cognitive-complexity,
 | 
				
			||||||
 | 
					  -readability-function-size,
 | 
				
			||||||
 | 
					  -readability-identifier-length,
 | 
				
			||||||
 | 
					  -readability-magic-numbers,
 | 
				
			||||||
 | 
					  -readability-uppercase-literal-suffix,
 | 
				
			||||||
 | 
					  -readability-braces-around-statements,
 | 
				
			||||||
 | 
					  -readability-redundant-access-specifiers,
 | 
				
			||||||
 | 
					  tidyfox-*,
 | 
				
			||||||
 | 
					CheckOptions:
 | 
				
			||||||
 | 
					  performance-for-range-copy.WarnOnAllAutoCopies: true
 | 
				
			||||||
 | 
					  performance-inefficient-string-concatenation.StrictMode: true
 | 
				
			||||||
 | 
					  readability-braces-around-statements.ShortStatementLines: 1
 | 
				
			||||||
 | 
					  readability-identifier-naming.ClassCase: CamelCase
 | 
				
			||||||
 | 
					  readability-identifier-naming.ConstantCase: UPPER_CASE
 | 
				
			||||||
 | 
					  readability-identifier-naming.EnumCase: CamelCase
 | 
				
			||||||
 | 
					  readability-identifier-naming.FunctionCase: camelBack
 | 
				
			||||||
 | 
					  readability-identifier-naming.MemberCase: camelBack
 | 
				
			||||||
 | 
					  readability-identifier-naming.NamespaceCase: lower_case
 | 
				
			||||||
 | 
					  readability-identifier-naming.LocalConstantCase: camelBack
 | 
				
			||||||
 | 
					  readability-identifier-naming.MethodCase: camelBack
 | 
				
			||||||
 | 
					  readability-identifier-naming.ParameterCase: camelBack
 | 
				
			||||||
 | 
					  readability-identifier-naming.VariableCase: camelBack
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  # does not appear to work
 | 
				
			||||||
 | 
					  readability-operators-representation.BinaryOperators: '&&;&=;&;|;~;!;!=;||;|=;^;^='
 | 
				
			||||||
 | 
					  readability-operators-representation.OverloadedOperators: '&&;&=;&;|;~;!;!=;||;|=;^;^='
 | 
				
			||||||
							
								
								
									
										10
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								.gitignore
									
										
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					# build files
 | 
				
			||||||
 | 
					/build/
 | 
				
			||||||
 | 
					compile_commands.json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# clangd
 | 
				
			||||||
 | 
					/.cache
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# direnv
 | 
				
			||||||
 | 
					/.envrc
 | 
				
			||||||
 | 
					/.direnv/
 | 
				
			||||||
							
								
								
									
										35
									
								
								CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								CMakeLists.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,35 @@
 | 
				
			||||||
 | 
					cmake_minimum_required(VERSION 3.20)
 | 
				
			||||||
 | 
					project(qtshell VERSION "0.0.1")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					set(QT_MIN_VERSION "6.6.0")
 | 
				
			||||||
 | 
					set(CMAKE_CXX_STANDARD 20)
 | 
				
			||||||
 | 
					set(CMAKE_CXX_STANDARD_REQUIRED ON)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_compile_options(-Wall -Wextra)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# nix workaround
 | 
				
			||||||
 | 
					if (CMAKE_EXPORT_COMPILE_COMMANDS)
 | 
				
			||||||
 | 
						set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (NOT CMAKE_BUILD_TYPE)
 | 
				
			||||||
 | 
						message(STATUS "CMAKE_BUILD_TYPE unset, defaulting to Debug.")
 | 
				
			||||||
 | 
						set(CMAKE_BUILD_TYPE Debug)
 | 
				
			||||||
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					find_package(Qt6 REQUIRED COMPONENTS Qml QuickControls2)
 | 
				
			||||||
 | 
					find_package(LayerShellQt REQUIRED)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qt_standard_project_setup(REQUIRES 6.6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qt_add_executable(qtshell
 | 
				
			||||||
 | 
						src/cpp/main.cpp
 | 
				
			||||||
 | 
						src/cpp/shell.cpp
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					qt_add_qml_module(qtshell URI QtShell)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# qml type registration requires this
 | 
				
			||||||
 | 
					target_include_directories(qtshell PRIVATE src/cpp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					target_link_libraries(qtshell PRIVATE Qt6::Qml Qt6::QuickControls2 LayerShellQtInterface)
 | 
				
			||||||
							
								
								
									
										33
									
								
								Justfile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								Justfile
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,33 @@
 | 
				
			||||||
 | 
					builddir := 'build'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					with_cpphpp := 'find src -type f \( -name "*.cpp" -o -name "*.hpp" \) -print0 | xargs -0'
 | 
				
			||||||
 | 
					with_cpp := 'find src -type f -name "*.cpp" -print0 | xargs -0'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fmt:
 | 
				
			||||||
 | 
					    {{with_cpphpp}} clang-format -i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					lint:
 | 
				
			||||||
 | 
					    {{with_cpp}} clang-tidy --load={{ env_var("TIDYFOX") }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					fixlint:
 | 
				
			||||||
 | 
					    {{with_cpp}} clang-tidy --load={{ env_var("TIDYFOX") }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					configure target='debug' *FLAGS='':
 | 
				
			||||||
 | 
						cmake -B {{builddir}} \
 | 
				
			||||||
 | 
							-DCMAKE_BUILD_TYPE={{ if target == "debug" { "Debug" } else { "Release" } }} \
 | 
				
			||||||
 | 
							-DCMAKE_EXPORT_COMPILE_COMMANDS=ON {{FLAGS}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ln -sf {{builddir}}/compile_commands.json compile_commands.json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_configure_if_clean:
 | 
				
			||||||
 | 
						@if ! [ -d {{builddir}} ]; then just configure; fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					build: _configure_if_clean
 | 
				
			||||||
 | 
						cmake --build {{builddir}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					clean:
 | 
				
			||||||
 | 
						rm -f compile_commands.json
 | 
				
			||||||
 | 
						rm -rf {{builddir}}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					run *ARGS='': build
 | 
				
			||||||
 | 
						{{builddir}}/qtshell {{ARGS}}
 | 
				
			||||||
							
								
								
									
										51
									
								
								shell.nix
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								shell.nix
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,51 @@
 | 
				
			||||||
 | 
					{ pkgs ? import <nixpkgs> {} }: let
 | 
				
			||||||
 | 
					  tidyfox = import (pkgs.fetchFromGitea {
 | 
				
			||||||
 | 
					    domain = "git.outfoxxed.me";
 | 
				
			||||||
 | 
					    owner = "outfoxxed";
 | 
				
			||||||
 | 
					    repo = "tidyfox";
 | 
				
			||||||
 | 
					    rev = "1f062cc198d1112d13e5128fa1f2ee3dbffe613b";
 | 
				
			||||||
 | 
					    sha256 = "kbt0Zc1qHE5fhqBkKz8iue+B+ZANjF1AR/RdgmX1r0I=";
 | 
				
			||||||
 | 
					  }) {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  qtlayershell = pkgs.callPackage (import (pkgs.fetchFromGitea {
 | 
				
			||||||
 | 
					    domain = "git.outfoxxed.me";
 | 
				
			||||||
 | 
					    owner = "outfoxxed";
 | 
				
			||||||
 | 
					    repo = "layer-shell-qt-nokde";
 | 
				
			||||||
 | 
					    rev = "a50d30687cc03ae4da177033faf5f038c3e1a8b2";
 | 
				
			||||||
 | 
					    sha256 = "5fNwoCce74SSqR5XB3fJ8GI+D5cbkcLRok42k8R3XSw=";
 | 
				
			||||||
 | 
					  })) {}; #pkgs.callPackage (import /home/admin/programming/outfoxxed/layer-shell-qt) {};
 | 
				
			||||||
 | 
					in pkgs.mkShell {
 | 
				
			||||||
 | 
					  nativeBuildInputs = with pkgs; [
 | 
				
			||||||
 | 
					    just
 | 
				
			||||||
 | 
					    clang-tools_17
 | 
				
			||||||
 | 
					    cmake
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qt6.wrapQtAppsHook
 | 
				
			||||||
 | 
					    makeWrapper
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  buildInputs = with pkgs; [
 | 
				
			||||||
 | 
					    qt6.qtbase
 | 
				
			||||||
 | 
					    qt6.qtdeclarative
 | 
				
			||||||
 | 
					    qt6.qtwayland
 | 
				
			||||||
 | 
					    qtlayershell
 | 
				
			||||||
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  TIDYFOX = "${tidyfox}/lib/libtidyfox.so";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  shellHook = ''
 | 
				
			||||||
 | 
					    export CMAKE_BUILD_PARALLEL_LEVEL=$(nproc)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Add Qt-related environment variables.
 | 
				
			||||||
 | 
					    # https://discourse.nixos.org/t/qt-development-environment-on-a-flake-system/23707/5
 | 
				
			||||||
 | 
					    setQtEnvironment=$(mktemp)
 | 
				
			||||||
 | 
					    random=$(openssl rand -base64 20 | sed "s/[^a-zA-Z0-9]//g")
 | 
				
			||||||
 | 
					    makeWrapper "$(type -p sh)" "$setQtEnvironment" "''${qtWrapperArgs[@]}" --argv0 "$random"
 | 
				
			||||||
 | 
					    sed "/$random/d" -i "$setQtEnvironment"
 | 
				
			||||||
 | 
					    source "$setQtEnvironment"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # qmlls does not account for the import path and bases its search off qtbase's path.
 | 
				
			||||||
 | 
					    # The actual imports come from qtdeclarative. This directs qmlls to the correct imports.
 | 
				
			||||||
 | 
					    export QMLLS_BUILD_DIRS=$(pwd)/build:$QML2_IMPORT_PATH
 | 
				
			||||||
 | 
					  '';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										63
									
								
								src/cpp/main.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/cpp/main.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,63 @@
 | 
				
			||||||
 | 
					#include <LayerShellQt/shell.h>
 | 
				
			||||||
 | 
					#include <qcommandlineoption.h>
 | 
				
			||||||
 | 
					#include <qcommandlineparser.h>
 | 
				
			||||||
 | 
					#include <qdir.h>
 | 
				
			||||||
 | 
					#include <qguiapplication.h>
 | 
				
			||||||
 | 
					#include <qlogging.h>
 | 
				
			||||||
 | 
					#include <qobject.h>
 | 
				
			||||||
 | 
					#include <qqmlapplicationengine.h>
 | 
				
			||||||
 | 
					#include <qstandardpaths.h>
 | 
				
			||||||
 | 
					#include <qstring.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "shell.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int main(int argc, char** argv) {
 | 
				
			||||||
 | 
						const auto app = QGuiApplication(argc, argv);
 | 
				
			||||||
 | 
						QGuiApplication::setApplicationName("qtshell");
 | 
				
			||||||
 | 
						QGuiApplication::setApplicationVersion("0.0.1");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QCommandLineParser parser;
 | 
				
			||||||
 | 
						parser.setApplicationDescription("Qt based desktop shell");
 | 
				
			||||||
 | 
						parser.addHelpOption();
 | 
				
			||||||
 | 
						parser.addVersionOption();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto configOption = QCommandLineOption({"c", "config"}, "Path to configuration file.", "path");
 | 
				
			||||||
 | 
						parser.addOption(configOption);
 | 
				
			||||||
 | 
						parser.process(app);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QString configPath;
 | 
				
			||||||
 | 
						if (parser.isSet(configOption)) {
 | 
				
			||||||
 | 
							configPath = parser.value(configOption);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							configPath = QStandardPaths::writableLocation(QStandardPaths::ConfigLocation);
 | 
				
			||||||
 | 
							configPath = QDir(QDir(configPath).filePath("qtshell")).filePath("config.qml");
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						qInfo() << "config file path:" << configPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!QFile(configPath).exists()) {
 | 
				
			||||||
 | 
							qCritical() << "config file does not exist";
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						CONFIG_PATH = configPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						LayerShellQt::Shell::useLayerShell();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto engine = QQmlApplicationEngine();
 | 
				
			||||||
 | 
						engine.load(configPath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (engine.rootObjects().isEmpty()) {
 | 
				
			||||||
 | 
							qCritical() << "failed to load config file";
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto* shellobj = qobject_cast<QtShell*>(engine.rootObjects().first());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (shellobj == nullptr) {
 | 
				
			||||||
 | 
							qCritical() << "root item was not a QtShell";
 | 
				
			||||||
 | 
							return -1;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return QGuiApplication::exec();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										96
									
								
								src/cpp/shell.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								src/cpp/shell.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,96 @@
 | 
				
			||||||
 | 
					#include "shell.hpp"
 | 
				
			||||||
 | 
					#include <utility>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <qfileinfo.h>
 | 
				
			||||||
 | 
					#include <qlogging.h>
 | 
				
			||||||
 | 
					#include <qobject.h>
 | 
				
			||||||
 | 
					#include <qobjectdefs.h>
 | 
				
			||||||
 | 
					#include <qqmlcomponent.h>
 | 
				
			||||||
 | 
					#include <qqmlcontext.h>
 | 
				
			||||||
 | 
					#include <qqmlengine.h>
 | 
				
			||||||
 | 
					#include <qqmllist.h>
 | 
				
			||||||
 | 
					#include <qtmetamacros.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QString CONFIG_PATH; // NOLINT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QtShell::QtShell(): QObject(nullptr), path(CONFIG_PATH), dir(QFileInfo(this->path).dir()) {
 | 
				
			||||||
 | 
						CONFIG_PATH = "";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void QtShell::componentComplete() {
 | 
				
			||||||
 | 
						if (this->path.isEmpty()) {
 | 
				
			||||||
 | 
							qWarning() << "Multiple QtShell objects were created. You should not do this.";
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (auto* component: this->mComponents) {
 | 
				
			||||||
 | 
							component->prepare(this->dir);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QQmlListProperty<ShellComponent> QtShell::components() {
 | 
				
			||||||
 | 
						return QQmlListProperty<ShellComponent>(
 | 
				
			||||||
 | 
						    this,
 | 
				
			||||||
 | 
						    nullptr,
 | 
				
			||||||
 | 
						    &QtShell::appendComponent,
 | 
				
			||||||
 | 
						    nullptr,
 | 
				
			||||||
 | 
						    nullptr,
 | 
				
			||||||
 | 
						    nullptr,
 | 
				
			||||||
 | 
						    nullptr,
 | 
				
			||||||
 | 
						    nullptr
 | 
				
			||||||
 | 
						);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void QtShell::appendComponent(QQmlListProperty<ShellComponent>* list, ShellComponent* component) {
 | 
				
			||||||
 | 
						auto* shell = qobject_cast<QtShell*>(list->object);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (shell != nullptr) shell->mComponents.append(component);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ShellComponent::setSource(QString source) {
 | 
				
			||||||
 | 
						if (this->mComponent != nullptr) {
 | 
				
			||||||
 | 
							qWarning() << "cannot define ShellComponent.source while defining a component";
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->mSource = std::move(source);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ShellComponent::setComponent(QQmlComponent* component) {
 | 
				
			||||||
 | 
						if (this->mSource != nullptr) {
 | 
				
			||||||
 | 
							qWarning() << "cannot define a component for ShellComponent while source is set";
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						this->mComponent = component;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ShellComponent::prepare(const QDir& basePath) {
 | 
				
			||||||
 | 
						if (this->mComponent == nullptr) {
 | 
				
			||||||
 | 
							if (this->mSource == nullptr) {
 | 
				
			||||||
 | 
								qWarning() << "neither source or a component was set for ShellComponent on prepare";
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto path = basePath.filePath(this->mSource);
 | 
				
			||||||
 | 
							qDebug() << "preparing ShellComponent from" << path;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto* context = QQmlEngine::contextForObject(this);
 | 
				
			||||||
 | 
							if (context == nullptr) {
 | 
				
			||||||
 | 
								qWarning() << "ShellComponent was created without an associated QQmlEngine, cannot prepare";
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							auto* engine = context->engine();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							this->mComponent = new QQmlComponent(engine, path, this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (this->mComponent == nullptr) {
 | 
				
			||||||
 | 
								qWarning() << "could not load ShellComponent source" << path;
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						qDebug() << "Sending ready for ShellComponent";
 | 
				
			||||||
 | 
						emit this->ready();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										59
									
								
								src/cpp/shell.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/cpp/shell.hpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,59 @@
 | 
				
			||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <qdir.h>
 | 
				
			||||||
 | 
					#include <qlogging.h>
 | 
				
			||||||
 | 
					#include <qobject.h>
 | 
				
			||||||
 | 
					#include <qqmlcomponent.h>
 | 
				
			||||||
 | 
					#include <qqmlengine.h>
 | 
				
			||||||
 | 
					#include <qqmlintegration.h>
 | 
				
			||||||
 | 
					#include <qqmllist.h>
 | 
				
			||||||
 | 
					#include <qqmlparserstatus.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern QString CONFIG_PATH; // NOLINT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ShellComponent;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class QtShell: public QObject, public QQmlParserStatus {
 | 
				
			||||||
 | 
						Q_OBJECT;
 | 
				
			||||||
 | 
						Q_INTERFACES(QQmlParserStatus);
 | 
				
			||||||
 | 
						Q_PROPERTY(QQmlListProperty<ShellComponent> components READ components FINAL);
 | 
				
			||||||
 | 
						Q_CLASSINFO("DefaultProperty", "components");
 | 
				
			||||||
 | 
						QML_ELEMENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						explicit QtShell();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void classBegin() override {};
 | 
				
			||||||
 | 
						void componentComplete() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QQmlListProperty<ShellComponent> components();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						static void appendComponent(QQmlListProperty<ShellComponent>* list, ShellComponent* component);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QList<ShellComponent*> mComponents;
 | 
				
			||||||
 | 
						QString path;
 | 
				
			||||||
 | 
						QDir dir;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ShellComponent: public QObject {
 | 
				
			||||||
 | 
						Q_OBJECT;
 | 
				
			||||||
 | 
						Q_PROPERTY(QString source WRITE setSource);
 | 
				
			||||||
 | 
						Q_PROPERTY(QQmlComponent* component MEMBER mComponent WRITE setComponent);
 | 
				
			||||||
 | 
						Q_CLASSINFO("DefaultProperty", "component");
 | 
				
			||||||
 | 
						QML_ELEMENT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						explicit ShellComponent(QObject* parent = nullptr): QObject(parent) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void setSource(QString source);
 | 
				
			||||||
 | 
						void setComponent(QQmlComponent* component);
 | 
				
			||||||
 | 
						void prepare(const QDir& basePath);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					signals:
 | 
				
			||||||
 | 
						void ready();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						QString mSource;
 | 
				
			||||||
 | 
						QQmlComponent* mComponent = nullptr;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue