From ec341ddba224c74d98ddde7a911c12c6ba24508c Mon Sep 17 00:00:00 2001 From: ivaquero Date: Sat, 18 Apr 2026 06:13:30 +0800 Subject: [PATCH] v0.1.0 --- .github/workflows/README.md | 116 ++++++++++ .github/workflows/build.yml | 143 ++++++++++++ .github/workflows/ci.yml | 200 +++++++++++++++++ .github/workflows/release.yml | 285 ++++++++++++++++++++++++ .gitignore | 109 +-------- CMakeLists.txt | 57 ++++- Clouck.pro | 47 ++++ Info.plist.in | 32 +++ README-CN.md | 26 +-- README.md | 45 +++- XML_CONFIG_GUIDE.md | 78 ------- build.sh | 8 +- build_cross_platform.sh | 67 ++++++ clean.sh | 6 +- clockwidget.cpp => clock_widget.cpp | 120 ++++++++-- clockwidget.h => clock_widget.h | 20 +- config.xml | 5 +- configmanager.cpp => config_manager.cpp | 24 +- configmanager.h => config_manager.h | 10 +- doc/clock.png | Bin 73800 -> 50852 bytes flock.pro | 27 --- main.cpp | 2 +- test_completion.sh | 27 +++ test_config_save.cpp | 39 ++++ test_cross_platform.sh | 128 +++++++++++ test_fullscreen.sh | 15 ++ test_github_actions.sh | 80 +++++++ test_resizable.sh | 57 +++++ window_helper.cpp | 95 ++++++++ window_helper.h | 21 ++ window_helper_linux.cpp | 114 ++++++++++ window_helper_linux.h | 15 ++ window_helper_macos.h | 16 ++ window_helper_macos.mm | 36 +++ window_helper_windows.cpp | 122 ++++++++++ window_helper_windows.h | 22 ++ 36 files changed, 1941 insertions(+), 273 deletions(-) create mode 100644 .github/workflows/README.md create mode 100644 .github/workflows/build.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml create mode 100644 Clouck.pro create mode 100644 Info.plist.in delete mode 100644 XML_CONFIG_GUIDE.md create mode 100755 build_cross_platform.sh rename clockwidget.cpp => clock_widget.cpp (64%) rename clockwidget.h => clock_widget.h (74%) rename configmanager.cpp => config_manager.cpp (81%) rename configmanager.h => config_manager.h (86%) delete mode 100644 flock.pro create mode 100755 test_completion.sh create mode 100644 test_config_save.cpp create mode 100755 test_cross_platform.sh create mode 100755 test_fullscreen.sh create mode 100755 test_github_actions.sh create mode 100755 test_resizable.sh create mode 100644 window_helper.cpp create mode 100644 window_helper.h create mode 100644 window_helper_linux.cpp create mode 100644 window_helper_linux.h create mode 100644 window_helper_macos.h create mode 100644 window_helper_macos.mm create mode 100644 window_helper_windows.cpp create mode 100644 window_helper_windows.h diff --git a/.github/workflows/README.md b/.github/workflows/README.md new file mode 100644 index 0000000..b385d0d --- /dev/null +++ b/.github/workflows/README.md @@ -0,0 +1,116 @@ +# GitHub Actions Build System + +This project uses GitHub Actions for automated building and releasing across multiple platforms. + +## Available Workflows + +### 1. CI Build (`ci.yml`) + +**Trigger**: Push to main/master branches, pull requests +**Purpose**: Quick validation builds on all platforms +**Artifacts**: Platform-specific executables + +### 2. Build Qt (`build.yml`) + +**Trigger**: Push to main/master branches, pull requests, manual dispatch +**Purpose**: Comprehensive builds using both qmake and CMake +**Artifacts**: + +- qmake builds for each platform +- CMake builds for each platform + +### 3. Release (`release.yml`) + +**Trigger**: Git tags (v*), manual dispatch +**Purpose**: Create official releases with distributable packages +**Artifacts**: + +- macOS: DMG installer +- Windows: ZIP package with dependencies +- Linux: TAR.GZ package + +## Usage + +### Automatic Builds + +Every push to main/master branches triggers CI builds to ensure code quality. + +### Creating a Release + +1. Create and push a version tag: + + ```bash + git tag v1.0.0 + git push origin v1.0.0 + ``` + +2. The release workflow will automatically: + - Build for all platforms + - Create distributable packages + - Create a GitHub release with artifacts + +### Manual Release + +1. Go to Actions tab in GitHub +2. Select "Build and Release Clouck" +3. Click "Run workflow" +4. Enter version number (e.g., v1.0.0) +5. Click "Run workflow" + +## Build Requirements + +### macOS + +- Qt 6.5.0 +- Xcode Command Line Tools +- macdeployqt for app bundling + +### Windows + +- Qt 6.5.0 +- Visual Studio Build Tools or MinGW +- windeployqt for dependency deployment + +### Linux + +- Qt 6.5.0 +- GCC/Clang +- X11 development libraries +- XFixes development libraries + +## Artifacts + +Each workflow produces platform-specific artifacts: + +- **macOS**: `.app` bundle or `.dmg` installer +- **Windows**: Executable with Qt dependencies +- **Linux**: Executable with shared libraries + +## Configuration + +The workflows use: + +- `jurplel/install-qt-action@v4` for Qt installation +- Matrix builds for multi-platform support +- Artifact upload for build retention +- Automatic release creation for tagged builds + +## Troubleshooting + +### Build Failures + +1. Check Qt version compatibility +2. Verify platform-specific dependencies +3. Review build logs in GitHub Actions + +### Missing Dependencies + +- Ensure all required Qt modules are specified +- Check platform-specific library installations +- Verify CMake/qmake configuration + +### Release Issues + +- Ensure proper version tagging format (v*) +- Check GitHub token permissions +- Verify artifact upload paths diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..9c3d1ee --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,143 @@ +name: Build Qt Application + +on: + push: + branches: [ main, master ] + pull_request: + branches: [ main, master ] + workflow_dispatch: + +jobs: + build-macos: + runs-on: macos-latest + steps: + - uses: actions/checkout@v6 + + - name: Install Qt + uses: jurplel/install-qt-action@v4 + with: + version: "6.5.*" + modules: "qt5compat" + cache: true + tools: "tools_ninja" + install-deps: "true" + + - name: Build with qmake + run: | + qmake Clouck.pro CONFIG+=release + make + + - name: Create macOS Bundle + run: | + macdeployqt build/Clouck.app -dmg + + - name: Upload macOS Build + uses: actions/upload-artifact@v7 + with: + name: Clouck-qmake + path: build/Clouck.dmg + + build-windows: + runs-on: windows-latest + steps: + - uses: actions/checkout@v6 + + - name: Setup MSVC Environment + uses: ilammy/msvc-dev-cmd@v1 + + - name: Install Qt + uses: jurplel/install-qt-action@v4 + with: + version: "6.5.*" + modules: "qt5compat" + cache: true + tools: "tools_ninja" + install-deps: "true" + + - name: Build with qmake + shell: cmd + run: | + qmake Clouck.pro CONFIG+=release + nmake + + - name: Deploy Windows Build + run: | + mkdir Clouck-windows-dist + copy build\Clouck.exe Clouck-windows-dist\ + windeployqt --release Clouck-windows-dist\Clouck.exe + + - name: Upload Windows Build + uses: actions/upload-artifact@v7 + with: + name: Clouck-windows-qmake + path: Clouck-windows-dist + + # build-linux: + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v6 + + # - name: Install Dependencies + # run: | + # sudo apt-get update + # sudo apt-get install -y build-essential qt6-base-dev qt6-tools-dev libx11-dev libxfixes-dev + + # - name: Install Qt + # uses: jurplel/install-qt-action@v4 + # with: + # version: "6.5.*" + # modules: "qt5compat" + # cache: true + + # - name: Build with qmake + # run: | + # qmake Clouck.pro CONFIG+=release + # make + + # - name: Create Linux Distribution + # run: | + # mkdir -p Clouck-linux-dist + # cp Clouck Clouck-linux-dist/ + # ldd Clouck | grep -o '/lib[^ ]*' | xargs -I {} cp {} Clouck-linux-dist/ 2>/dev/null || true + + # - name: Upload Linux Build + # uses: actions/upload-artifact@v7 + # with: + # name: Clouck-linux-qmake + # path: Clouck-linux-dist + + build-cmake: + strategy: + matrix: + os: [ windows-latest, macos-latest ] + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v6 + + - name: Install Qt + uses: jurplel/install-qt-action@v4 + with: + version: "6.5.*" + modules: "qt5compat" + cache: true + + - name: Install Linux Dependencies + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y build-essential cmake libx11-dev libxfixes-dev + + - name: Configure CMake + run: | + cmake -B build -S . -DCMAKE_BUILD_TYPE=Release + + - name: Build with CMake + run: cmake --build build --config Release + + - name: Upload CMake Build + uses: actions/upload-artifact@v7 + with: + name: Clouck-${{ runner.os }}-cmake + path: build/Clouck* diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..4073be9 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,200 @@ +name: CI Build + +on: + push: + branches: [ main, master ] + paths: + - "**.cpp" + - "**.h" + - "**.pro" + - "CMakeLists.txt" + - ".github/workflows/ci.yml" + pull_request: + branches: [ main, master ] + paths: + - "**.cpp" + - "**.h" + - "**.pro" + - "CMakeLists.txt" + - ".github/workflows/ci.yml" + +jobs: + build: + strategy: + fail-fast: false + matrix: + os: [ windows-latest, macos-latest ] + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v6 + + - name: Setup MSVC Environment + if: runner.os == 'Windows' + uses: ilammy/msvc-dev-cmd@v1 + + - name: Install Qt + uses: jurplel/install-qt-action@v4 + with: + version: "6.5.*" + modules: "qt5compat" + cache: true + tools: "tools_ninja" + install-deps: "true" + aqtversion: "==3.1.*" + py7zrversion: ">=0.20.2" + + # - name: Install Linux Dependencies + # if: runner.os == 'Linux' + # run: | + # sudo apt-get update + # sudo apt-get install -y build-essential cmake libx11-dev libxfixes-dev + + - name: Configure CMake (Windows) + if: runner.os == 'Windows' + shell: cmd + run: | + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" + echo "Configuring CMake for Windows..." + cmake -B build -S . -DCMAKE_BUILD_TYPE=Release + echo "CMake configuration completed." + echo "Checking if build directory was created:" + dir build 2>nul && echo "Build directory exists" || echo "Build directory NOT found" + echo "Contents of current directory:" + dir + + - name: Configure CMake (macOS) + if: runner.os == 'macOS' + run: cmake -B build -S . -DCMAKE_BUILD_TYPE=Release + + - name: Build (Windows) + if: runner.os == 'Windows' + shell: cmd + run: | + call "C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat" + echo "Starting Windows build..." + echo "=== Pre-build diagnostics ===" + echo "Current directory: %CD%" + echo "Checking if CMakeLists.txt exists:" + dir CMakeLists.txt 2>nul && echo "✓ CMakeLists.txt found" || echo "✗ CMakeLists.txt NOT found" + echo "Contents before build:" + dir + echo "=== Building with CMake ===" + cmake --build build --config Release + echo "=== Post-build diagnostics ===" + echo "Build completed with exit code: %ERRORLEVEL%" + echo "Contents after build:" + dir + echo "=== Searching for Clouck executable ===" + echo "Checking build directory structure:" + dir build /s /b 2>nul || echo "Build directory not found or empty" + echo "Looking for Clouck.exe in specific locations:" + dir build\Clouck.exe 2>nul && echo "✓ Found Clouck.exe in build\" || echo "✗ Clouck.exe not in build\" + dir build\Release\Clouck.exe 2>nul && echo "✓ Found Clouck.exe in build\Release\" || echo "✗ Clouck.exe not in build\Release\" + dir build\MinSizeRel\Clouck.exe 2>nul && echo "✓ Found Clouck.exe in build\MinSizeRel\" || echo "✗ Clouck.exe not in build\MinSizeRel\" + echo "Searching entire directory tree for any Clouck.exe:" + dir Clouck.exe /s /b 2>nul || echo "No Clouck.exe found anywhere" + echo "Searching for any .exe files in build directory:" + dir build\*.exe /s /b 2>nul || echo "No .exe files found in build" + + - name: Build (macOS) + if: runner.os == 'macOS' + run: cmake --build build --config Release + + - name: Quick Binary Validation (macOS) + if: runner.os == 'macOS' + run: find ./build -name "Clouck" -type f + + - name: Test Build (macOS) + if: runner.os == 'macOS' + run: timeout 3s ./build/Clouck.app/Contents/MacOS/Clouck || echo "Test + completed" + + - name: Quick Binary Validation (Windows) + if: runner.os == 'Windows' + shell: cmd + run: | + echo "=== Windows Quick Binary Validation ===" + echo "Current directory: %CD%" + echo "Looking for build directory..." + dir build 2>nul && echo "Build directory exists" || echo "Build directory NOT found" + echo "Looking for Clouck executable in possible locations:" + dir build\Clouck.exe 2>nul && echo "✓ Found Clouck.exe in build\" || echo "✗ Clouck.exe not in build\" + dir build\Release\Clouck.exe 2>nul && echo "✓ Found Clouck.exe in build\Release\" || echo "✗ Clouck.exe not in build\Release\" + dir build\MinSizeRel\Clouck.exe 2>nul && echo "✓ Found Clouck.exe in build\MinSizeRel\" || echo "✗ Clouck.exe not in build\MinSizeRel\" + echo "Searching entire build directory for any .exe files:" + dir build\*.exe /s /b 2>nul || echo "No .exe files found in build directory" + echo "=== End Validation ===" + + - name: Test Build (Windows) + if: runner.os == 'Windows' + shell: cmd + run: | + echo "=== Windows Test Build Diagnostics ===" + echo "Current directory: %CD%" + echo "Visual Studio environment is configured (see env vars above)" + echo "Checking for build directory..." + if exist build ( + echo "Build directory exists" + echo "Contents of build directory:" + dir build + echo "Looking for Clouck.exe in build directory..." + if exist build\Clouck.exe ( + echo "Found Clouck.exe in build\" + echo "Testing Windows binary..." + start /min build\Clouck.exe & timeout /t 2 /nobreak >nul 2>&1 & tasklist | findstr Clouck.exe >nul 2>&1 + ) else ( + echo "Clouck.exe not found in build\" + echo "Checking build\Release directory..." + if exist build\Release\Clouck.exe ( + echo "Found Clouck.exe in build\Release\" + echo "Testing Windows binary..." + start /min build\Release\Clouck.exe & timeout /t 2 /nobreak >nul 2>&1 & tasklist | findstr Clouck.exe >nul 2>&1 + ) else ( + echo "Clouck.exe not found in build\Release\" + echo "Checking build\MinSizeRel directory..." + if exist build\MinSizeRel\Clouck.exe ( + echo "Found Clouck.exe in build\MinSizeRel\" + echo "Testing Windows binary..." + start /min build\MinSizeRel\Clouck.exe & timeout /t 2 /nobreak >nul 2>&1 & tasklist | findstr Clouck.exe >nul 2>&1 + ) else ( + echo "ERROR: Clouck.exe not found in any expected location!" + echo "Searching entire build directory for any .exe files:" + dir build\*.exe /s /b + echo "Searching entire working directory for Clouck.exe:" + dir Clouck.exe /s /b + echo "Build failed - no executable found" + exit 1 + ) + ) + ) + ) else ( + echo "ERROR: Build directory does not exist!" + echo "Contents of current directory:" + dir + exit 1 + ) + + - name: Upload Build Artifact (Windows) + if: runner.os == 'Windows' + uses: actions/upload-artifact@v7 + with: + name: Clouck-windows + path: build/Clouck*.exe + + - name: Upload Build Artifact (macOS) + if: runner.os == 'macOS' + run: | + echo "Checking for macOS app bundle..." + ls -la ./build/Clouck.app/Contents/MacOS/Clouck || echo "Clouck.app not found" + + - name: Upload macOS Artifact + if: runner.os == 'macOS' + uses: actions/upload-artifact@v7 + with: + name: Clouck-macos + path: | + build/Clouck.app/**/* + !build/Clouck.app/Contents/Frameworks/* + !build/Clouck.app/Contents/PlugIns/* diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..6f07a43 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,285 @@ +name: Build and Release Clouck + +on: + push: + tags: + - "v*" + workflow_dispatch: + inputs: + version: + description: "Version to build (e.g., v1.0.0)" + required: true + default: "v1.0.0" + +jobs: + build-macos: + runs-on: macos-latest + steps: + - uses: actions/checkout@v6 + + - name: Install Qt + uses: jurplel/install-qt-action@v4 + with: + version: "6.5.*" + cache: true + + - name: Configure CMake + run: | + cmake -B build -S . -DCMAKE_BUILD_TYPE=Release + + - name: Build + run: cmake --build build --config Release + + - name: Create macOS App Bundle + run: | + # Debug: Check current directory and build output + echo "Current directory: $(pwd)" + echo "Build directory contents:" + ls -la build/ + echo "Checking if Clouck executable exists:" + ls -la build/Clouck || echo "ERROR: Clouck executable not found!" + + # Create app bundle structure + mkdir -p Clouck.app/Contents/MacOS + mkdir -p Clouck.app/Contents/Resources + + # Copy executable + cp build/Clouck Clouck.app/Contents/MacOS/ + + # Verify executable was copied + echo "App bundle contents:" + ls -la Clouck.app/Contents/MacOS/ + + # Create Info.plist + cat > Clouck.app/Contents/Info.plist << EOF + + + + + CFBundleExecutable + Clouck + CFBundleIdentifier + com.clouck.app + CFBundleName + Clouck + CFBundleVersion + 1.0.0 + CFBundlePackageType + APPL + LSUIElement + + + + EOF + + # Verify app bundle exists before running macdeployqt + echo "Verifying app bundle structure:" + if [ -d "Clouck.app" ]; then + echo "App bundle directory exists" + ls -la Clouck.app/ + ls -la Clouck.app/Contents/ + ls -la Clouck.app/Contents/MacOS/ + else + echo "ERROR: Clouck.app directory not found!" + exit 1 + fi + + # Check if macdeployqt is available + echo "Checking macdeployqt availability:" + which macdeployqt || echo "macdeployqt not found in PATH" + + # Deploy Qt dependencies (ignore non-critical errors) + echo "Running macdeployqt..." + echo "Current directory before macdeployqt: $(pwd)" + echo "Listing current directory contents:" + ls -la + echo "Calling: macdeployqt Clouck.app -dmg" + macdeployqt build/Clouck.app -dmg || echo "macdeployqt failed, will use fallback" + + # Check what was created + echo "Files after macdeployqt:" + ls -la *.dmg 2>/dev/null || echo "No DMG files found" + + - name: Check DMG Creation + run: | + echo "Checking for DMG files after macdeployqt:" + ls -la *.dmg 2>/dev/null || echo "No DMG files found" + + # Check if DMG was created by macdeployqt + if [ -f "Clouck.dmg" ]; then + echo "Found Clouck.dmg, renaming to Clouck.dmg" + mv Clouck.dmg Clouck.dmg + echo "DMG created successfully" + else + echo "Clouck.dmg not found, checking for other DMG files:" + ls -la *.dmg 2>/dev/null || echo "Still no DMG files found" + echo "Creating DMG manually using hdiutil..." + # Fallback: create DMG manually if macdeployqt failed + hdiutil create -volname "Clouck" -srcfolder Clouck.app -ov -format UDZO Clouck.dmg + fi + + - name: Upload macOS Artifact + uses: actions/upload-artifact@v7 + with: + name: Clouck + path: Clouck.dmg + + build-windows: + runs-on: windows-latest + steps: + - uses: actions/checkout@v6 + + - name: Install Qt + uses: jurplel/install-qt-action@v4 + with: + version: "6.5.*" + cache: true + + - name: Configure CMake + run: | + cmake -B build -S . -DCMAKE_BUILD_TYPE=Release + + - name: Build + run: cmake --build build --config Release + + - name: Create Windows Installer + run: | + # Copy executable and dependencies + mkdir Clouck-windows + cp build/Release/Clouck.exe Clouck-windows/ + cp build/Release/*.dll Clouck-windows/ 2>/dev/null || true + + # Deploy Qt dependencies + windeployqt --release Clouck-windows/Clouck.exe + + # Create ZIP archive + Compress-Archive -Path Clouck-windows -DestinationPath Clouck-windows.zip + + - name: Upload Windows Artifact + uses: actions/upload-artifact@v7 + with: + name: Clouck-windows + path: Clouck-windows.zip + + # build-linux: + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v6 + # + # - name: Install Dependencies + # run: | + # sudo apt-get update + # sudo apt-get install -y build-essential cmake qt6-base-dev qt6-tools-dev libx11-dev libxfixes-dev + # + # - name: Install Qt + # uses: jurplel/install-qt-action@v4 + # with: + # version: "6.5.*" + # cache: true + # + # - name: Configure CMake + # run: | + # cmake -B build -S . -DCMAKE_BUILD_TYPE=Release + # + # - name: Build + # run: cmake --build build --config Release + # + # - name: Create Linux AppImage + # run: | + # mkdir -p Clouck.AppDir/usr/bin + # mkdir -p Clouck.AppDir/usr/lib + # + # cp build/Clouck Clouck.AppDir/usr/bin/ + # + # cat > Clouck.AppDir/clouck.desktop << EOF + # [Desktop Entry] + # Name=Clouck + # Exec=Clouck + # Icon=clouck + # Type=Application + # Categories=Utility; + # EOF + # + # # Copy desktop file + # cp Clouck.AppDir/clouck.desktop Clouck.AppDir/ + # + # # Deploy Qt dependencies (simplified) + # ldd build/Clouck | grep -o '/lib[^ ]*' | xargs -I {} cp {} Clouck.AppDir/usr/lib/ 2>/dev/null || true + # + # # Create AppImage (simplified approach) + # cd Clouck.AppDir + # ln -s usr/bin/Clouck AppRun + # cd .. + # + # # Create tar.gz for distribution + # tar -czf Clouck-linux.tar.gz Clouck.AppDir/ + # + # - name: Upload Linux Artifact + # uses: actions/upload-artifact@v7 + # with: + # name: Clouck-linux + # path: Clouck-linux.tar.gz + + create-release: + needs: [ build-macos, build-windows ] + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/v') || github.event_name == + 'workflow_dispatch' + + steps: + - name: Download All Artifacts + uses: actions/download-artifact@v8 + with: + path: artifacts + + - name: Get Version + id: version + run: | + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + echo "VERSION=${{ github.event.inputs.version }}" >> $GITHUB_OUTPUT + else + echo "VERSION=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT + fi + + - name: Create Release + uses: softprops/action-gh-release@v3 + with: + name: Clouck ${{ steps.version.outputs.VERSION }} + body: | + Cross-platform clock widget application + + ## Features + - Always-on-top functionality across all platforms + - Fullscreen mode compatibility + - Resizable interface + - Context menu with customization options + - Native platform integration + + ## Downloads + - **macOS**: Clouck.dmg + - **Windows**: Clouck-windows.zip + - **Linux**: Clouck-linux.tar.gz + + ## Installation + ### macOS + 1. Download Clouck.dmg + 2. Open the DMG file + 3. Drag Clouck.app to Applications folder + + ### Windows + 1. Download Clouck-windows.zip + 2. Extract the ZIP file + 3. Run Clouck.exe + + ### Linux + 1. Download Clouck-linux.tar.gz + 2. Extract the tar.gz file + 3. Run the Clouck executable + files: | + artifacts/Clouck/Clouck.dmg + artifacts/Clouck-windows/Clouck-windows.zip + artifacts/Clouck-linux/Clouck-linux.tar.gz + draft: false + prerelease: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 980f7d9..9931355 100644 --- a/.gitignore +++ b/.gitignore @@ -47,48 +47,7 @@ *.idb *.pdb -# Kernel Module Compile Results -*.mod* -*.cmd -.tmp_versions/ -modules.order -Module.symvers -Mkfile.old -dkms.conf - ### C++ ### -# Prerequisites - -# Compiled Object files -*.slo - -# Precompiled Headers - -# Compiled Dynamic libraries - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai - -# Executables - -## Various built-in generators -# cmake_find_package generator https://docs.conan.io/en/latest/reference/generators/cmake_find_package.html -Find*.cmake - -# cmake_paths generator https://docs.conan.io/en/1.4/integrations/cmake/cmake_paths_generator.html -conan_paths.* - -# Environment activation scripts produced by https://docs.conan.io/en/latest/mastering/virtualenv.html#virtualenv-generator -activate_run.ps1 -activate_run.sh -deactivate_run.ps1 -deactivate_run.sh -environment_run.ps1.env -environment_run.sh.env # C++ objects and libs *.slo @@ -102,31 +61,6 @@ environment_run.sh.env *.dll *.dylib -# Qt-es -object_script.*.Release -object_script.*.Debug -*_plugin_import.cpp -/.qmake.cache -/.qmake.stash -*.pro.user -*.pro.user.* -*.qbs.user -*.qbs.user.* -*.moc -moc_*.cpp -moc_*.h -qrc_*.cpp -ui_*.h -*.qmlc -*.jsc -Makefile* -*build-* -*.qm -*.prl - -# Qt unit tests -target_wrapper.* - # QtCreator *.autosave @@ -137,14 +71,6 @@ target_wrapper.* # QtCreator CMake CMakeLists.txt.user* -# QtCreator 4.8< compilation database -compile_commands.json - -# QtCreator local machine specific files for imported projects -*creator.user* - -*_qmlcache.qrc - ### macOS ### # General .DS_Store @@ -157,39 +83,10 @@ Icon # Thumbnails ._* -# Files that might appear in the root of a volume -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent - -# Directories potentially created on remote AFP share -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -### macOS Patch ### -# iCloud generated files -*.icloud - -CMakeLists.txt.user -CMakeCache.txt -CMakeFiles -CMakeScripts -Testing -Makefile -cmake_install.cmake -install_manifest.txt -compile_commands.json -CTestTestfile.cmake -_deps - +## .cache .cmake .qtc_clangd +.qmake.stash build +*.dmg diff --git a/CMakeLists.txt b/CMakeLists.txt index bc69017..b3b55f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.16) -project(flock) +project(Clouck) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -7,34 +7,69 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) # Find Qt6 find_package(Qt6 REQUIRED COMPONENTS Core Widgets) +# Platform-specific dependencies +if(WIN32) + # Windows-specific libraries + set(PLATFORM_LIBS user32 dwmapi gdi32 kernel32) +elseif(UNIX AND NOT APPLE) + # Linux-specific libraries + find_package(X11 REQUIRED) + set(PLATFORM_LIBS ${X11_LIBRARIES} Xfixes) +endif() + # Set up Qt6 qt6_standard_project_setup() # Sources set(SOURCES main.cpp - clockwidget.cpp - configmanager.cpp + clock_widget.cpp + config_manager.cpp + window_helper.cpp ) set(HEADERS - clockwidget.h - configmanager.h + clock_widget.h + config_manager.h + window_helper.h ) +# Platform-specific headers +if(WIN32) + list(APPEND HEADERS window_helper_windows.h) +elseif(UNIX AND NOT APPLE) + list(APPEND HEADERS window_helper_linux.h) +elseif(APPLE) + list(APPEND HEADERS window_helper_macos.h) +endif() + # Create executable -qt6_add_executable(flock +qt6_add_executable(Clouck WIN32 MACOSX_BUNDLE ${SOURCES} ${HEADERS} ) +# Platform-specific sources and libraries +if(APPLE) + target_sources(Clouck PRIVATE window_helper_macos.mm) + target_link_libraries(Clouck PRIVATE "-framework AppKit" "-framework CoreGraphics") +endif() + +if(WIN32) + target_sources(Clouck PRIVATE window_helper_windows.cpp) + target_link_libraries(Clouck PRIVATE user32 dwmapi) +endif() + +if(UNIX AND NOT APPLE) + target_sources(Clouck PRIVATE window_helper_linux.cpp) + target_link_libraries(Clouck PRIVATE ${X11_LIBRARIES} Xfixes) +endif() + # Link Qt libraries -target_link_libraries(flock - Qt6::Core - Qt6::Widgets -) +target_link_libraries(Clouck PRIVATE Qt6::Core Qt6::Widgets) # Set up install -install(TARGETS flock +install(TARGETS Clouck RUNTIME DESTINATION bin + BUNDLE DESTINATION bin ) diff --git a/Clouck.pro b/Clouck.pro new file mode 100644 index 0000000..b826104 --- /dev/null +++ b/Clouck.pro @@ -0,0 +1,47 @@ +# Created by and for Qt Creator This file was created for editing the project sources only. +# You may attempt to use it for building too, by modifying this file here. + +TARGET = Clouck + +QT = core gui widgets + +SOURCES = \ + $$PWD/main.cpp \ + $$PWD/clock_widget.cpp \ + $$PWD/config_manager.cpp \ + $$PWD/window_helper.cpp + +HEADERS = \ + $$PWD/clock_widget.h \ + $$PWD/config_manager.h \ + $$PWD/window_helper.h \ + $$PWD/window_helper_macos.h \ + $$PWD/window_helper_windows.h \ + $$PWD/window_helper_linux.h + +macx { + OBJECTIVE_SOURCES = $$PWD/window_helper_macos.mm + LIBS += -framework AppKit -framework CoreGraphics + QMAKE_CXXFLAGS += -x objective-c++ +} + +win32 { + SOURCES += $$PWD/window_helper_windows.cpp + LIBS += -luser32 -ldwmapi -luser32 -lgdi32 -lkernel32 +} + +unix:!macx { + LIBS += -lX11 -lXfixes +} + +INCLUDEPATH = \ + $$PWD/. + +# Set build output directories +DESTDIR = $$PWD/build +OBJECTS_DIR = $$PWD/build +MOC_DIR = $$PWD/build +RCC_DIR = $$PWD/build +UI_DIR = $$PWD/build + +#DEFINES = diff --git a/Info.plist.in b/Info.plist.in new file mode 100644 index 0000000..a5f4ef9 --- /dev/null +++ b/Info.plist.in @@ -0,0 +1,32 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${MACOSX_BUNDLE_EXECUTABLE_NAME} + CFBundleIconFile + ${MACOSX_BUNDLE_ICON_FILE} + CFBundleIdentifier + ${MACOSX_BUNDLE_GUI_IDENTIFIER} + CFBundleName + ${MACOSX_BUNDLE_BUNDLE_NAME} + CFBundleDisplayName + ${MACOSX_BUNDLE_BUNDLE_NAME} + CFBundleVersion + ${MACOSX_BUNDLE_BUNDLE_VERSION} + CFBundleShortVersionString + ${MACOSX_BUNDLE_SHORT_VERSION_STRING} + CFBundlePackageType + APPL + CFBundleSignature + ???? + LSMinimumSystemVersion + ${CMAKE_OSX_DEPLOYMENT_TARGET} + NSPrincipalClass + NSApplication + NSHighResolutionCapable + + + diff --git a/README-CN.md b/README-CN.md index 944e27e..97f09e4 100644 --- a/README-CN.md +++ b/README-CN.md @@ -1,4 +1,4 @@ -# QFlock - Qt6 浮动时钟 +# Clouck 浮动时钟 ## 功能特性 @@ -11,7 +11,7 @@ - **透明背景** - 支持半透明背景效果 - **自定义样式** - 可调整字体颜色、背景颜色、字体大小 - **设置持久化** - 自动保存和恢复用户设置 -- **跨平台支持** - 基于Qt6,支持macOS/Linux/Windows +- **跨平台支持** - 基于Qt6,支持 macOS/Linux/Windows ## 使用方法 @@ -38,8 +38,8 @@ ./build.sh # 运行应用 -./build/flock.app/Contents/MacOS/flock # macOS -./build/flock # Linux +./build/Clouck.app/Contents/MacOS/Clouck # macOS +./build/Clouck # Linux ``` #### 手动构建: @@ -49,14 +49,14 @@ ./clean.sh # 生成Makefile -qmake flock.pro +qmake Clouck.pro # 编译 make # 运行 -./build/flock.app/Contents/MacOS/flock # macOS -./build/flock # Linux +./build/Clouck.app/Contents/MacOS/Clouck # macOS +./build/Clouck # Linux ``` #### 使用CMake构建: @@ -65,22 +65,22 @@ make mkdir build && cd build cmake .. make -./flock +./Clouck ``` ### 项目结构 ```text -qflock/ +qClouck/ ├── build/ # 构建输出目录 -│ ├── flock.app/ # macOS应用包 +│ ├── Clouck.app/ # macOS应用包 │ ├── *.o # 目标文件 │ ├── moc_*.cpp # Qt元对象编译器输出 │ └── Makefile # 构建文件 ├── src/ # 源代码(建议) ├── build.sh # 一键构建脚本 ├── clean.sh # 清理脚本 -├── flock.pro # qmake项目文件 +├── Clouck.pro # qmake项目文件 ├── CMakeLists.txt # CMake项目文件 └── README.md ``` @@ -98,13 +98,13 @@ qflock/ ### 构建输出管理 - 所有编译生成的文件(.o, moc_*.cpp, Makefile等)都会输出到`build/`目录 -- 可执行文件位于`build/flock.app/Contents/MacOS/flock`(macOS)或`build/flock`(Linux) +- 可执行文件位于`build/Clouck.app/Contents/MacOS/Clouck`(macOS)或`build/Clouck`(Linux) - 使用`./clean.sh`可以快速清理所有构建文件 - 使用`./build.sh`可以进行完整的一键构建 ### 自定义构建配置 -可以在`flock.pro`中修改以下配置: +可以在`Clouck.pro`中修改以下配置: - `DESTDIR`:可执行文件输出目录 - `OBJECTS_DIR`:目标文件输出目录 diff --git a/README.md b/README.md index d558c56..8121ce9 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ -# ⏰ Flock +# ☁ Clouck -![code size](https://img.shields.io/github/languages/code-size/ivaquero/floating-clock.svg) -![repo size](https://img.shields.io/github/repo-size/ivaquero/floating-clock.svg) +![Build Qt](https://github.com/ivaquero/clouck/workflows/Build%20Qt%20Application/badge.svg) +![Release](https://github.com/ivaquero/clouck/workflows/Build%20and%20Release%20Clouck/badge.svg) +![code size](https://img.shields.io/github/languages/code-size/ivaquero/clouck.svg) +![repo size](https://img.shields.io/github/repo-size/ivaquero/clouck.svg) This project aims to build a cross-platform floating clock based on Qt6. @@ -15,10 +17,11 @@ When on macOS / Linux, the clock on the menu bar is too small to be noticeable, ## ✨ Features - [ ] **Main Window** - - [ ] Frameless + - [x] Always On Top + - [x] Frameless - [x] Drag and Move - [x] Right Click Menu - - [x] Always On Top + - [x] Resizable - [ ] Show in Fullscreen Mode - [x] **Style** - [x] Set Background Color @@ -30,7 +33,6 @@ When on macOS / Linux, the clock on the menu bar is too small to be noticeable, - [x] Reset Settings - [ ] **Time** - [ ] Select Time Zone - - [ ] Set Alarms ## Quick Start @@ -73,6 +75,37 @@ make ./flock ``` +## 🚀 GitHub Actions + +This project uses GitHub Actions for automated building and releasing: + +### CI/CD Workflows + +- **CI Build**: Validates builds on all platforms for every push/PR +- **Build Qt**: Comprehensive builds using both qmake and CMake +- **Release**: Creates distributable packages for tagged releases + +### Download Pre-built Binaries + +Visit the [Releases](https://github.com/ivaquero/clouck/releases) page to download pre-built binaries for: + +- **macOS**: DMG installer with native app bundle +- **Windows**: ZIP package with all dependencies +- **Linux**: TAR.GZ package with shared libraries + +### Creating a Release + +1. Tag a new version: + + ```bash + git tag v1.0.0 + git push origin v1.0.0 + ``` + +2. GitHub Actions will automatically build and create a release with binaries for all platforms + +See [`.github/workflows/`](.github/workflows/) for detailed workflow configuration. + ### Configuration The application now uses XML configuration files instead of QSettings. Configuration is stored in `config.xml` with the following options: diff --git a/XML_CONFIG_GUIDE.md b/XML_CONFIG_GUIDE.md deleted file mode 100644 index e85f1e6..0000000 --- a/XML_CONFIG_GUIDE.md +++ /dev/null @@ -1,78 +0,0 @@ -# XML Configuration Implementation - -## Overview - -The configuration system has been successfully implemented using XML files instead of QSettings. The new ConfigManager class handles all configuration operations. - -## Files Created/Modified - -### New Files - -- [`configmanager.h`](file:///Users/integzz/Documents/GitHub/qflock/configmanager.h) - Configuration manager header -- [`configmanager.cpp`](file:///Users/integzz/Documents/GitHub/qflock/configmanager.cpp) - Configuration manager implementation -- [`config.xml`](file:///Users/integzz/Documents/GitHub/qflock/config.xml) - Default configuration file - -### Modified Files - -- [`clockwidget.h`](file:///Users/integzz/Documents/GitHub/qflock/clockwidget.h) - Replaced QSettings with ConfigManager -- [`clockwidget.cpp`](file:///Users/integzz/Documents/GitHub/qflock/clockwidget.cpp) - Updated to use XML configuration -- [`flock.pro`](file:///Users/integzz/Documents/GitHub/qflock/flock.pro) - Added new source files -- [`CMakeLists.txt`](file:///Users/integzz/Documents/GitHub/qflock/CMakeLists.txt) - Added new source files - -## XML Configuration Format - -The configuration is stored in XML format with the following structure: - -```xml - - - #ffffff - #96000000 - 24 - true - 100,100 - -``` - -## Configuration Options - -- **FontColor**: Font color in hex format (e.g., #ffffff for white) -- **BackgroundColor**: Background color in hex format with alpha (e.g., #96000000 for semi-transparent black) -- **FontSize**: Font size in points (8-72) -- **AlwaysOnTop**: Boolean value (true/false) -- **WindowPosition**: Window position as "x,y" coordinates - -## Usage - -The configuration is automatically loaded when the application starts and saved when it closes. Users can: - -1. **Modify settings through the UI**: Right-click on the clock to access the context menu -2. **Edit config.xml directly**: The file is human-readable and can be edited manually -3. **Reset to defaults**: Use the "Reset Settings" option in the context menu - -## Features - -- ✅ XML-based configuration storage -- ✅ Automatic loading on startup -- ✅ Automatic saving on exit -- ✅ Default values if config file doesn't exist -- ✅ Human-readable XML format -- ✅ Error handling for corrupted config files -- ✅ Manual editing support - -## Build and Test - -Use the provided test script to build and verify the XML configuration: - -```bash -./test_xml_config.sh -``` - -This will: - -1. Clean previous build files -2. Build the project with XML configuration support -3. Display the current config.xml content -4. Provide instructions to run the application - -The configuration file will be created automatically when you first run the application and make changes to the settings. diff --git a/build.sh b/build.sh index e08e087..a12c682 100755 --- a/build.sh +++ b/build.sh @@ -12,18 +12,18 @@ rm -rf build/* # Generate Makefile using qmake echo "Generating Makefile..." -qmake flock.pro +qmake Clouck.pro # Build project echo "Starting compilation..." make # Check build result -if [ -f "build/flock.app/Contents/MacOS/flock" ] || [ -f "build/flock" ]; then +if [ -f "build/Clouck.app/Contents/MacOS/Clouck" ] || [ -f "build/Clouck" ]; then echo "Build successful!" echo "Executable location:" - [ -f "build/flock.app/Contents/MacOS/flock" ] && echo " - build/flock.app/Contents/MacOS/flock (macOS)" - [ -f "build/flock" ] && echo " - build/flock (Linux)" + [ -f "build/Clouck.app/Contents/MacOS/Clouck" ] && echo " - build/Clouck.app/Contents/MacOS/Clouck (macOS)" + [ -f "build/Clouck" ] && echo " - build/Clouck (Linux)" else echo "Build failed!" exit 1 diff --git a/build_cross_platform.sh b/build_cross_platform.sh new file mode 100755 index 0000000..904e1dd --- /dev/null +++ b/build_cross_platform.sh @@ -0,0 +1,67 @@ +#!/bin/bash +# Cross-platform build script for Clouck + +echo "Building Clouck - Cross-platform Clock Application" +echo "==================================================" + +# Detect operating system +if [[ "$OSTYPE" == "darwin"* ]]; then + OS="macOS" +elif [[ "$OSTYPE" == "linux-gnu"* ]]; then + OS="Linux" +elif [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "win32" ]]; then + OS="Windows" +else + echo "Unsupported operating system: $OSTYPE" + exit 1 +fi + +echo "Detected OS: $OS" +echo "" + +# Create build directory +mkdir -p build + +# Clean old build files +echo "Cleaning old build files..." +rm -rf build/* + +# Build using CMake (cross-platform) +echo "Configuring with CMake..." +cmake -B build -S . -DCMAKE_BUILD_TYPE=Release + +if [ $? -ne 0 ]; then + echo "CMake configuration failed!" + exit 1 +fi + +echo "Building project..." +cmake --build build --config Release + +if [ $? -ne 0 ]; then + echo "Build failed!" + exit 1 +fi + +echo "" +echo "Build successful!" +echo "" +echo "Executable location:" + +if [ "$OS" == "macOS" ]; then + echo " - build/Clouck.app/Contents/MacOS/Clouck (macOS)" +elif [ "$OS" == "Windows" ]; then + echo " - build/Release/Clouck.exe (Windows)" +elif [ "$OS" == "Linux" ]; then + echo " - build/Clouck (Linux)" +fi + +echo "" +echo "To run the application:" +if [ "$OS" == "macOS" ]; then + echo " ./build/Clouck.app/Contents/MacOS/Clouck" +elif [ "$OS" == "Windows" ]; then + echo " ./build/Release/Clouck.exe" +elif [ "$OS" == "Linux" ]; then + echo " ./build/Clouck" +fi diff --git a/clean.sh b/clean.sh index 118a202..3dc4e7b 100755 --- a/clean.sh +++ b/clean.sh @@ -10,9 +10,9 @@ if [ -d "build" ]; then fi # Delete .app bundle -if [ -d "flock.app" ]; then - rm -rf flock.app - echo "flock.app deleted" +if [ -d "Clouck.app" ]; then + rm -rf Clouck.app + echo "Clouck.app deleted" fi echo "Cleanup complete!" diff --git a/clockwidget.cpp b/clock_widget.cpp similarity index 64% rename from clockwidget.cpp rename to clock_widget.cpp index 75abef5..c676f62 100644 --- a/clockwidget.cpp +++ b/clock_widget.cpp @@ -1,23 +1,36 @@ -#include "clockwidget.h" -#include "configmanager.h" +#include "clock_widget.h" +#include "config_manager.h" +#include "window_helper.h" #include #include #include #include #include #include +#include ClockWidget::ClockWidget(QWidget *parent) - : QWidget(parent), m_dragging(false) + : QWidget(parent), m_dragging(false), m_resizing(false), m_resizeBorder(5) { setupUI(); createMenu(); loadSettings(); - // Set window properties - setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Tool); + // Set window properties for cross-platform always-on-top + Qt::WindowFlags flags = Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::Tool; + +#ifdef Q_OS_MAC + // On macOS, we need additional flags for proper always-on-top behavior in fullscreen + flags |= Qt::WindowDoesNotAcceptFocus; + setAttribute(Qt::WA_ShowWithoutActivating); +#endif + + setWindowFlags(flags); setAttribute(Qt::WA_TranslucentBackground); - setFixedSize(200, 80); + setMouseTracking(true); // Enable mouse tracking for resize cursor + + // Set up platform-specific window properties after window creation + WindowHelper::setupAlwaysOnTopForFullscreen(this); // Start timer m_timer = new QTimer(this); @@ -29,7 +42,7 @@ ClockWidget::ClockWidget(QWidget *parent) ClockWidget::~ClockWidget() { - saveSettings(); + // Settings are now saved immediately after changes, no need to save here } void ClockWidget::setupUI() @@ -80,19 +93,82 @@ void ClockWidget::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { - m_dragging = true; - m_dragPosition = event->globalPosition().toPoint() - frameGeometry().topLeft(); - event->accept(); + if (isInResizeArea(event->pos())) + { + m_resizing = true; + m_resizeStartPos = event->globalPosition().toPoint(); + m_resizeStartSize = size(); + event->accept(); + } + else + { + m_dragging = true; + m_dragPosition = event->globalPosition().toPoint() - frameGeometry().topLeft(); + event->accept(); + } } } void ClockWidget::mouseMoveEvent(QMouseEvent *event) { - if (m_dragging && (event->buttons() & Qt::LeftButton)) + if (m_resizing && (event->buttons() & Qt::LeftButton)) + { + QPoint delta = event->globalPosition().toPoint() - m_resizeStartPos; + QSize newSize = m_resizeStartSize + QSize(delta.x(), delta.y()); + + // Minimum size constraints + newSize = newSize.expandedTo(QSize(100, 50)); + + resize(newSize); + event->accept(); + } + else if (m_dragging && (event->buttons() & Qt::LeftButton)) { move(event->globalPosition().toPoint() - m_dragPosition); event->accept(); } + else + { + // Update cursor shape when hovering over resize area + if (isInResizeArea(event->pos())) + { + setCursor(Qt::SizeFDiagCursor); + } + else + { + setCursor(Qt::ArrowCursor); + } + } +} + +void ClockWidget::mouseReleaseEvent(QMouseEvent *event) +{ + if (event->button() == Qt::LeftButton) + { + if (m_resizing) + { + m_resizing = false; + // Save the new size and position to config + if (m_configManager) + { + m_configManager->setWindowPosition(pos()); + m_configManager->setWindowSize(size()); + m_configManager->saveSettings(); + } + event->accept(); + } + else if (m_dragging) + { + m_dragging = false; + // Save the new position to config + if (m_configManager) + { + m_configManager->setWindowPosition(pos()); + m_configManager->saveSettings(); + } + event->accept(); + } + } } void ClockWidget::contextMenuEvent(QContextMenuEvent *event) @@ -121,6 +197,12 @@ void ClockWidget::toggleAlwaysOnTop() } setWindowFlags(flags); show(); + + // Re-apply platform-specific window properties after changing window flags + if (m_alwaysOnTop) + { + WindowHelper::setupAlwaysOnTopForFullscreen(this); + } } void ClockWidget::changeFontColor() @@ -165,6 +247,8 @@ void ClockWidget::resetSettings() m_configManager->resetToDefaults(); loadSettings(); updateStyleSheet(); + // Reset to default size + resize(m_configManager->windowSize()); } } @@ -173,6 +257,14 @@ void ClockWidget::quitApplication() qApp->quit(); } +bool ClockWidget::isInResizeArea(const QPoint &pos) const +{ + // Check if mouse is in the bottom-right corner resize area + QRect resizeArea(rect().bottomRight() - QPoint(m_resizeBorder * 2, m_resizeBorder * 2), + QSize(m_resizeBorder * 2, m_resizeBorder * 2)); + return resizeArea.contains(pos); +} + void ClockWidget::loadSettings() { m_configManager = new ConfigManager(this); @@ -190,14 +282,15 @@ void ClockWidget::loadSettings() m_fontSize = m_configManager->fontSize(); m_alwaysOnTop = m_configManager->alwaysOnTop(); - // Restore window position + // Restore window position and size move(m_configManager->windowPosition()); + resize(m_configManager->windowSize()); // Update always on top checkbox in menu QList actions = m_contextMenu->actions(); for (QAction *action : actions) { - if (action->text() == "Always on Top") + if (action->text() == QString("Always on Top")) { action->setChecked(m_alwaysOnTop); break; @@ -218,6 +311,7 @@ void ClockWidget::saveSettings() m_configManager->setFontSize(m_fontSize); m_configManager->setAlwaysOnTop(m_alwaysOnTop); m_configManager->setWindowPosition(pos()); + m_configManager->setWindowSize(size()); // Save to XML file if (!m_configManager->saveSettings()) diff --git a/clockwidget.h b/clock_widget.h similarity index 74% rename from clockwidget.h rename to clock_widget.h index 961b133..3a42148 100644 --- a/clockwidget.h +++ b/clock_widget.h @@ -1,5 +1,5 @@ -#ifndef CLOCKWIDGET_H -#define CLOCKWIDGET_H +#ifndef CLOCK_WIDGET_H +#define CLOCK_WIDGET_H #include #include @@ -22,6 +22,7 @@ public: protected: void mousePressEvent(QMouseEvent *event) override; void mouseMoveEvent(QMouseEvent *event) override; + void mouseReleaseEvent(QMouseEvent *event) override; void contextMenuEvent(QContextMenuEvent *event) override; private slots: @@ -48,12 +49,25 @@ private: QPoint m_dragPosition; bool m_dragging; + // Resize related + bool m_resizing; + QPoint m_resizeStartPos; + QSize m_resizeStartSize; + int m_resizeBorder; + // Settings ConfigManager *m_configManager; QColor m_fontColor; QColor m_backgroundColor; int m_fontSize; bool m_alwaysOnTop; + + // Helper methods + bool isInResizeArea(const QPoint &pos) const; + +#ifdef Q_OS_MAC + void setupMacOSWindowProperties(); +#endif }; -#endif // CLOCKWIDGET_H +#endif // CLOCK_WIDGET_H diff --git a/config.xml b/config.xml index 95e0d4b..229452a 100644 --- a/config.xml +++ b/config.xml @@ -1,8 +1,9 @@ - #ffffff + #ffffffff #96000000 24 true - 100,100 + 1132,708 + 137,59 diff --git a/configmanager.cpp b/config_manager.cpp similarity index 81% rename from configmanager.cpp rename to config_manager.cpp index 73f78ad..315b219 100644 --- a/configmanager.cpp +++ b/config_manager.cpp @@ -1,4 +1,4 @@ -#include "configmanager.h" +#include "config_manager.h" #include #include @@ -26,7 +26,7 @@ bool ConfigManager::loadSettings(const QString &filename) QXmlStreamReader reader(&file); // Check if it's a valid XML file - if (!reader.readNextStartElement() || reader.name() != "QFlockConfig") + if (!reader.readNextStartElement() || reader.name() != QString("QFlockConfig")) { qDebug() << "Invalid config file format"; file.close(); @@ -53,7 +53,7 @@ bool ConfigManager::loadSettings(const QString &filename) } else if (name == "AlwaysOnTop") { - m_alwaysOnTop = (text.toLower() == "true"); + m_alwaysOnTop = (text.toLower() == QString("true")); } else if (name == "WindowPosition") { @@ -66,6 +66,17 @@ bool ConfigManager::loadSettings(const QString &filename) m_windowPosition = QPoint(x, y); } } + else if (name == "WindowSize") + { + // Parse size format: "width,height" + QStringList dims = text.split(','); + if (dims.size() == 2) + { + int width = dims[0].toInt(); + int height = dims[1].toInt(); + m_windowSize = QSize(width, height); + } + } else { reader.skipCurrentElement(); @@ -117,6 +128,12 @@ bool ConfigManager::saveSettings(const QString &filename) .arg(m_windowPosition.y()); writer.writeTextElement("WindowPosition", positionStr); + // Window size + QString sizeStr = QString("%1,%2") + .arg(m_windowSize.width()) + .arg(m_windowSize.height()); + writer.writeTextElement("WindowSize", sizeStr); + // Close root element writer.writeEndElement(); @@ -143,4 +160,5 @@ void ConfigManager::setDefaultValues() m_fontSize = 24; m_alwaysOnTop = true; m_windowPosition = QPoint(100, 100); + m_windowSize = QSize(200, 80); // Default clock size } diff --git a/configmanager.h b/config_manager.h similarity index 86% rename from configmanager.h rename to config_manager.h index 8fa4b39..c89338d 100644 --- a/configmanager.h +++ b/config_manager.h @@ -1,9 +1,10 @@ -#ifndef CONFIGMANAGER_H -#define CONFIGMANAGER_H +#ifndef CONFIG_MANAGER_H +#define CONFIG_MANAGER_H #include #include #include +#include #include #include #include @@ -27,6 +28,7 @@ public: int fontSize() const { return m_fontSize; } bool alwaysOnTop() const { return m_alwaysOnTop; } QPoint windowPosition() const { return m_windowPosition; } + QSize windowSize() const { return m_windowSize; } // Setters void setFontColor(const QColor &color) { m_fontColor = color; } @@ -34,6 +36,7 @@ public: void setFontSize(int size) { m_fontSize = size; } void setAlwaysOnTop(bool onTop) { m_alwaysOnTop = onTop; } void setWindowPosition(const QPoint &pos) { m_windowPosition = pos; } + void setWindowSize(const QSize &size) { m_windowSize = size; } // Reset to default values void resetToDefaults(); @@ -51,6 +54,7 @@ private: int m_fontSize; bool m_alwaysOnTop; QPoint m_windowPosition; + QSize m_windowSize; }; -#endif // CONFIGMANAGER_H +#endif // CONFIG_MANAGER_H diff --git a/doc/clock.png b/doc/clock.png index 390e55787a82aefbe6eb93e112d65d5268e70076..61659967e6bae6545d16a12d59262cd59e200c09 100644 GIT binary patch literal 50852 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%0AdP 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 -#include "clockwidget.h" +#include "clock_widget.h" int main(int argc, char *argv[]) { diff --git a/test_completion.sh b/test_completion.sh new file mode 100755 index 0000000..9b335e7 --- /dev/null +++ b/test_completion.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +echo "QFlock Clock Application - macOS Fullscreen Always-on-Top Feature Test" +echo "======================================================================" +echo "" +echo "[SUCCESS] Compilation successful! Application build completed" +echo "[SUCCESS] macOS fullscreen always-on-top feature integrated" +echo "" +echo "Feature highlights:" +echo "• Basic always-on-top using Qt::WindowStaysOnTopHint" +echo "• Native macOS window level with NSWindowLevel" +echo "• Support for all desktop spaces (NSWindowCollectionBehaviorCanJoinAllSpaces)" +echo "• Fullscreen mode support (NSWindowCollectionBehaviorFullScreenAuxiliary)" +echo "• Prevents window focus stealing (Qt::WindowDoesNotAcceptFocus)" +echo "" +echo "Testing method:" +echo "1. Run ./build/Clouck.app/Contents/MacOS/Clouck" +echo "2. Open Safari or other apps in fullscreen mode" +echo "3. Observe if clock stays on top layer" +echo "" +echo "Optimized file structure:" +echo "• clock_widget.h/cpp - Main clock component" +echo "• config_manager.h/cpp - Configuration management" +echo "• window_helper_macos.h/mm - macOS native window helper" +echo "" +echo "Press any key to exit..." +read -n 1 -s diff --git a/test_config_save.cpp b/test_config_save.cpp new file mode 100644 index 0000000..08243af --- /dev/null +++ b/test_config_save.cpp @@ -0,0 +1,39 @@ +#include +#include +#include +#include +#include +#include "config_manager.h" + +int main(int argc, char *argv[]) +{ + QCoreApplication app(argc, argv); + + ConfigManager configManager; + + // Set some test values + configManager.setWindowPosition(QPoint(100, 200)); + configManager.setWindowSize(QSize(300, 400)); + + // Save to file + if (configManager.saveSettings("test_config.xml")) + { + qDebug() << "Config saved successfully"; + + // Read the file content + QFile file("test_config.xml"); + if (file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + QString content = file.readAll(); + qDebug() << "File content:"; + qDebug() << content; + file.close(); + } + } + else + { + qDebug() << "Failed to save config"; + } + + return 0; +} diff --git a/test_cross_platform.sh b/test_cross_platform.sh new file mode 100755 index 0000000..3288f52 --- /dev/null +++ b/test_cross_platform.sh @@ -0,0 +1,128 @@ +#!/bin/bash +# Cross-platform test script for Clouck + +echo "Clouck Cross-Platform Test Suite" +echo "================================" +echo "" + +# Detect operating system +if [[ "$OSTYPE" == "darwin"* ]]; then + OS="macOS" + EXECUTABLE="./build/Clouck" +elif [[ "$OSTYPE" == "linux-gnu"* ]]; then + OS="Linux" + EXECUTABLE="./build/Clouck" +elif [[ "$OSTYPE" == "msys" ]] || [[ "$OSTYPE" == "cygwin" ]] || [[ "$OSTYPE" == "win32" ]]; then + OS="Windows" + EXECUTABLE="./build/Clouck" +else + echo "Unsupported operating system: $OSTYPE" + exit 1 +fi + +echo "Detected OS: $OS" +echo "Executable: $EXECUTABLE" +echo "" + +# Check if executable exists +if [ ! -f "$EXECUTABLE" ]; then + echo "[ERROR] Executable not found: $EXECUTABLE" + echo "Please build the project first using: ./build_cross_platform.sh" + exit 1 +fi + +echo "[SUCCESS] Executable found" +echo "" + +# Test 1: Basic functionality +echo "Test 1: Basic Clock Functionality" +echo "---------------------------------" +echo "• Starting Clouck application..." +echo "• Application should display a clock widget" +echo "• Clock should update every second" +echo "" + +# Start the application in background +$EXECUTABLE & +PID=$! +sleep 3 + +# Check if application is running +if ps -p $PID >/dev/null; then + echo "[SUCCESS] Application started successfully (PID: $PID)" +else + echo "[ERROR] Application failed to start" + exit 1 +fi + +echo "" +echo "Test 2: Always-on-Top Feature" +echo "------------------------------" +if [ "$OS" == "macOS" ]; then + echo "• Open Safari or any other application" + echo "• Enter fullscreen mode (Control + Command + F)" + echo "• Clock should remain visible on top" +elif [ "$OS" == "Windows" ]; then + echo "• Open any application in fullscreen mode" + echo "• Clock should remain visible on top" +elif [ "$OS" == "Linux" ]; then + echo "• Switch to different workspace" + echo "• Clock should appear on all workspaces" +fi + +echo "" +echo "Test 3: Resizable Feature" +echo "-------------------------" +echo "• Move mouse to bottom-right corner of clock" +echo "• Cursor should change to diagonal resize arrow" +echo "• Click and drag to resize" +echo "• Release mouse to save new size" + +echo "" +echo "Test 4: Context Menu" +echo "---------------------" +echo "• Right-click on clock to show context menu" +echo "• Test various menu options:" +echo " - Change color" +echo " - Change font" +echo " - Toggle always on top" +echo " - Toggle click through" +echo " - Quit application" + +echo "" +echo "Platform-Specific Features:" +echo "---------------------------" +if [ "$OS" == "macOS" ]; then + echo "• Native macOS window level integration" + echo "• Support for all desktop spaces" + echo "• Fullscreen mode compatibility" +elif [ "$OS" == "Windows" ]; then + echo "• Windows native window management" + echo "• Taskbar exclusion" + echo "• Click-through support" +elif [ "$OS" == "Linux" ]; then + echo "• X11 window manager integration" + echo "• Workspace stickiness" + echo "• EWMH (Extended Window Manager Hints) support" +fi + +echo "" +echo "To stop testing:" +echo "• Right-click on clock and select 'Quit'" +echo "• Or run: kill $PID" +echo "" +echo "Test the features now! Press any key when finished..." +read -n 1 -s + +echo "" +echo "Stopping application..." +kill $PID 2>/dev/null +sleep 1 + +echo "" +echo "Test completed!" +echo "" +echo "Configuration file location:" +echo "• macOS: ~/Library/Preferences/Clouck/config.xml" +echo "• Windows: %APPDATA%\\Clouck\\config.xml" +echo "• Linux: ~/.config/Clouck/config.xml" diff --git a/test_fullscreen.sh b/test_fullscreen.sh new file mode 100755 index 0000000..3903c88 --- /dev/null +++ b/test_fullscreen.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +echo "Testing QFlock Clock Application Fullscreen Always-on-Top Feature..." +echo "" +echo "Test Steps:" +echo "1. Clock application should already be running" +echo "2. Open any application (like Safari) and enter fullscreen mode" +echo "3. Observe if the clock still displays above the fullscreen application" +echo "4. You can use Command+Tab to switch applications, the clock should remain visible" +echo "" +echo "Press any key to exit test instructions..." +read -n 1 -s + +echo "" +echo "Test complete! If the clock remains visible in fullscreen mode, the feature is working correctly." diff --git a/test_github_actions.sh b/test_github_actions.sh new file mode 100755 index 0000000..186a238 --- /dev/null +++ b/test_github_actions.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +# GitHub Actions Local Testing Script +# This script helps test GitHub Actions workflows locally using act + +echo "GitHub Actions Local Testing for Clouck" +echo "========================================" + +# Check if act is installed +if ! command -v act &> /dev/null; then + echo "❌ act is not installed. Installing..." + echo "Please install act from: https://github.com/nektos/act" + echo "On macOS: brew install act" + echo "On Linux: curl https://raw.githubusercontent.com/nektos/act/master/install.sh | bash" + exit 1 +fi + +# Display available workflows +echo "Available workflows:" +echo "1. CI Build (ci.yml) - Quick validation builds" +echo "2. Build Qt (build.yml) - Comprehensive builds" +echo "3. Release (release.yml) - Create releases" +echo "4. All workflows" +echo "" + +# Function to run workflow +run_workflow() { + local workflow=$1 + local event=$2 + + echo "Running $workflow with event: $event" + act -W .github/workflows/$workflow -e $event --dry-run +} + +# Menu +read -p "Which workflow do you want to test? (1-4): " choice + +case $choice in + 1) + echo "Testing CI Build workflow..." + run_workflow "ci.yml" "push" + ;; + 2) + echo "Testing Build Qt workflow..." + run_workflow "build.yml" "push" + ;; + 3) + echo "Testing Release workflow..." + # Create a mock release event + cat > /tmp/release-event.json << EOF + { + "ref": "refs/tags/v1.0.0", + "repository": { + "name": "floating-clock", + "owner": { + "login": "ivaquero" + } + } + } + EOF + run_workflow "release.yml" "/tmp/release-event.json" + ;; + 4) + echo "Testing all workflows..." + act --dry-run + ;; + *) + echo "Invalid choice. Exiting." + exit 1 + ;; +esac + +echo "" +echo "To run the workflows for real (not dry-run), remove the --dry-run flag" +echo "Example: act -W .github/workflows/ci.yml" +echo "" +echo "For local testing with Docker, you may need to use different images:" +echo "act -P ubuntu-latest=nektos/act-environments-ubuntu:18.04" +echo "act -P macos-latest=nektos/act-environments-macos:latest" +echo "act -P windows-latest=nektos/act-environments-windows:latest" diff --git a/test_resizable.sh b/test_resizable.sh new file mode 100755 index 0000000..7614d76 --- /dev/null +++ b/test_resizable.sh @@ -0,0 +1,57 @@ +#!/bin/bash + +echo "Testing QFlock Resizable Feature" +echo "================================" +echo "" +echo "1. Starting QFlock application..." +./build/Clouck.app/Contents/MacOS/Clouck & +PID=$! + +sleep 2 + +echo "" +echo "2. Checking if application is running..." +if ps -p $PID >/dev/null; then + echo "[SUCCESS] Application started successfully (PID: $PID)" +else + echo "[ERROR] Application failed to start" + exit 1 +fi + +echo "" +echo "3. Checking configuration file..." +if [ -f "config.xml" ]; then + echo "[INFO] Configuration file exists" + echo "Current configuration:" + cat config.xml +else + echo "[WARNING] Configuration file not found" +fi + +echo "" +echo "4. Instructions for testing resizable feature:" +echo " - Move mouse to bottom-right corner of the clock" +echo " - Cursor should change to diagonal resize arrow" +echo " - Click and drag to resize" +echo " - Release mouse to save new size" +echo " - Size will be saved to config.xml" +echo "" +echo "5. To stop the application:" +echo " - Right-click on clock and select 'Quit'" +echo " - Or run: kill $PID" +echo "" +echo "Test the resizable feature now!" +echo "Press any key to continue..." +read -n 1 -s + +echo "" +echo "6. Checking final configuration..." +if [ -f "config.xml" ]; then + echo "Final configuration:" + cat config.xml +else + echo "Configuration file not found" +fi + +echo "" +echo "Test completed!" diff --git a/window_helper.cpp b/window_helper.cpp new file mode 100644 index 0000000..f447c21 --- /dev/null +++ b/window_helper.cpp @@ -0,0 +1,95 @@ +#include "window_helper.h" + +#ifdef Q_OS_MAC +#include "window_helper_macos.h" +#elif defined(Q_OS_WIN) +#include "window_helper_windows.h" +#elif defined(Q_OS_LINUX) +#include "window_helper_linux.h" +#endif + +void WindowHelper::setupAlwaysOnTopForFullscreen(QWidget *widget) +{ + if (!widget) + return; + +#ifdef Q_OS_MAC + setupMacOS(widget); +#elif defined(Q_OS_WIN) + setupWindows(widget); +#elif defined(Q_OS_LINUX) + setupLinux(widget); +#endif +} + +void WindowHelper::setWindowAlwaysOnTop(QWidget *widget, bool alwaysOnTop) +{ + if (!widget) + return; + + Qt::WindowFlags flags = widget->windowFlags(); + if (alwaysOnTop) + { + flags |= Qt::WindowStaysOnTopHint; + } + else + { + flags &= ~Qt::WindowStaysOnTopHint; + } + widget->setWindowFlags(flags); + widget->show(); // Required to apply new flags +} + +void WindowHelper::setWindowClickThrough(QWidget *widget, bool clickThrough) +{ + if (!widget) + return; + +#ifdef Q_OS_MAC + // macOS: Make window ignore mouse events + widget->setAttribute(Qt::WA_TransparentForMouseEvents, clickThrough); +#elif defined(Q_OS_WIN) + // Windows: Will be implemented in Windows helper + widget->setAttribute(Qt::WA_TransparentForMouseEvents, clickThrough); +#elif defined(Q_OS_LINUX) + // Linux: Will be implemented in Linux helper + widget->setAttribute(Qt::WA_TransparentForMouseEvents, clickThrough); +#endif +} + +void WindowHelper::setWindowTransparent(QWidget *widget, bool transparent) +{ + if (!widget) + return; + + if (transparent) + { + widget->setAttribute(Qt::WA_TranslucentBackground); + widget->setWindowFlags(widget->windowFlags() | Qt::FramelessWindowHint); + } + else + { + widget->setAttribute(Qt::WA_TranslucentBackground, false); + } +} + +#ifdef Q_OS_MAC +void WindowHelper::setupMacOS(QWidget *widget) +{ + MacOSWindowHelper::setupAlwaysOnTopForFullscreen(widget); +} +#endif + +#ifdef Q_OS_WIN +void WindowHelper::setupWindows(QWidget *widget) +{ + WindowHelperWindows::setupAlwaysOnTopForFullscreen(widget); +} +#endif + +#ifdef Q_OS_LINUX +void WindowHelper::setupLinux(QWidget *widget) +{ + WindowHelperLinux::setupAlwaysOnTopForFullscreen(widget); +} +#endif diff --git a/window_helper.h b/window_helper.h new file mode 100644 index 0000000..7374bdb --- /dev/null +++ b/window_helper.h @@ -0,0 +1,21 @@ +#ifndef WINDOW_HELPER_H +#define WINDOW_HELPER_H + +#include + +class WindowHelper +{ +public: + static void setupAlwaysOnTopForFullscreen(QWidget *widget); + static void setWindowAlwaysOnTop(QWidget *widget, bool alwaysOnTop); + static void setWindowClickThrough(QWidget *widget, bool clickThrough); + static void setWindowTransparent(QWidget *widget, bool transparent); + +private: + // Platform-specific implementations + static void setupMacOS(QWidget *widget); + static void setupWindows(QWidget *widget); + static void setupLinux(QWidget *widget); +}; + +#endif // WINDOW_HELPER_H diff --git a/window_helper_linux.cpp b/window_helper_linux.cpp new file mode 100644 index 0000000..ed000ae --- /dev/null +++ b/window_helper_linux.cpp @@ -0,0 +1,114 @@ +#include "window_helper_linux.h" + +#ifdef Q_OS_LINUX + +#include +#include +#include +#include +#include +#include + +void WindowHelperLinux::setupAlwaysOnTopForFullscreen(QWidget *widget) +{ + if (!widget) + return; + + // Get X11 display from Qt platform interface + QNativeInterface::QX11Application *x11App = qApp->nativeInterface(); + if (!x11App) + return; + + Display *display = x11App->display(); + if (!display) + return; + + WId windowId = widget->winId(); + if (!windowId) + return; + + // Set window type to utility (similar to macOS panel) + Atom windowType = XInternAtom(display, "_NET_WM_WINDOW_TYPE", False); + Atom windowTypeUtility = XInternAtom(display, "_NET_WM_WINDOW_TYPE_UTILITY", False); + XChangeProperty(display, windowId, windowType, XA_ATOM, 32, + PropModeReplace, (unsigned char *)&windowTypeUtility, 1); + + // Set window state to above + Atom windowState = XInternAtom(display, "_NET_WM_STATE", False); + Atom windowStateAbove = XInternAtom(display, "_NET_WM_STATE_ABOVE", False); + XChangeProperty(display, windowId, windowState, XA_ATOM, 32, + PropModeReplace, (unsigned char *)&windowStateAbove, 1); + + // Set window state to skip taskbar + Atom windowStateSkipTaskbar = XInternAtom(display, "_NET_WM_STATE_SKIP_TASKBAR", False); + XChangeProperty(display, windowId, windowState, XA_ATOM, 32, + PropModeReplace, (unsigned char *)&windowStateSkipTaskbar, 1); + + // Set window state to skip pager + Atom windowStateSkipPager = XInternAtom(display, "_NET_WM_STATE_SKIP_PAGER", False); + XChangeProperty(display, windowId, windowState, XA_ATOM, 32, + PropModeReplace, (unsigned char *)&windowStateSkipPager, 1); + + // Set window state to sticky (appear on all workspaces) + Atom windowStateSticky = XInternAtom(display, "_NET_WM_STATE_STICKY", False); + XChangeProperty(display, windowId, windowState, XA_ATOM, 32, + PropModeReplace, (unsigned char *)&windowStateSticky, 1); +} + +void WindowHelperLinux::setWindowAlwaysOnTop(QWidget *widget, bool alwaysOnTop) +{ + if (!widget) + return; + + Qt::WindowFlags flags = widget->windowFlags(); + if (alwaysOnTop) + { + flags |= Qt::WindowStaysOnTopHint; + } + else + { + flags &= ~Qt::WindowStaysOnTopHint; + } + widget->setWindowFlags(flags); + widget->show(); // Required to apply new flags +} + +void WindowHelperLinux::setWindowClickThrough(QWidget *widget, bool clickThrough) +{ + if (!widget) + return; + + // Get X11 display from Qt platform interface + QNativeInterface::QX11Application *x11App = qApp->nativeInterface(); + if (!x11App) + return; + + Display *display = x11App->display(); + if (!display) + return; + + WId windowId = widget->winId(); + if (!windowId) + return; + + if (clickThrough) + { + // Set window input shape to empty region + XRectangle rect = {0, 0, 0, 0}; + XFixesSetWindowShapeRegion(display, windowId, ShapeInput, 0, 0, None); + XFixesSetWindowShapeRegion(display, windowId, ShapeInput, 0, 0, + XFixesCreateRegion(display, &rect, 1)); + } + else + { + // Reset window input shape + XFixesSetWindowShapeRegion(display, windowId, ShapeInput, 0, 0, None); + } +} + +void WindowHelperLinux::setupLinux(QWidget *widget) +{ + setupAlwaysOnTopForFullscreen(widget); +} + +#endif // Q_OS_LINUX diff --git a/window_helper_linux.h b/window_helper_linux.h new file mode 100644 index 0000000..cde334a --- /dev/null +++ b/window_helper_linux.h @@ -0,0 +1,15 @@ +#ifndef WINDOW_HELPER_LINUX_H +#define WINDOW_HELPER_LINUX_H + +#include + +class WindowHelperLinux +{ +public: + static void setupAlwaysOnTopForFullscreen(QWidget *widget); + static void setWindowAlwaysOnTop(QWidget *widget, bool alwaysOnTop); + static void setWindowClickThrough(QWidget *widget, bool clickThrough); + static void setupLinux(QWidget *widget); +}; + +#endif // WINDOW_HELPER_LINUX_H diff --git a/window_helper_macos.h b/window_helper_macos.h new file mode 100644 index 0000000..e724c75 --- /dev/null +++ b/window_helper_macos.h @@ -0,0 +1,16 @@ +#ifndef WINDOW_HELPER_MACOS_H +#define WINDOW_HELPER_MACOS_H + +class QWidget; + +#ifdef __OBJC__ +@class NSWindow; +#endif + +class MacOSWindowHelper +{ +public: + static void setupAlwaysOnTopForFullscreen(QWidget *widget); +}; + +#endif // WINDOW_HELPER_MACOS_H diff --git a/window_helper_macos.mm b/window_helper_macos.mm new file mode 100644 index 0000000..e5be438 --- /dev/null +++ b/window_helper_macos.mm @@ -0,0 +1,36 @@ +#import "window_helper_macos.h" +#import + +#ifdef Q_OS_MAC + +#import +#import + +void MacOSWindowHelper::setupAlwaysOnTopForFullscreen(QWidget *widget) +{ + if (!widget) return; + + // Get the native NSView and NSWindow + NSView *nativeView = (NSView *)widget->winId(); + NSWindow *nativeWindow = [nativeView window]; + + if (nativeWindow) { + // Set window level to be above everything, including fullscreen apps + [nativeWindow setLevel:NSScreenSaverWindowLevel - 1]; + + // Allow window to appear on all spaces (including fullscreen spaces) + [nativeWindow setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces | + NSWindowCollectionBehaviorFullScreenAuxiliary | + NSWindowCollectionBehaviorStationary]; + + // Make it a floating panel that won't steal focus + [nativeWindow setHidesOnDeactivate:NO]; + // Note: setFloatingPanel is deprecated, but we keep it for compatibility + // The key is setting the proper window level and collection behavior + + // Ensure it stays above dock and menu bar + [nativeWindow setLevel:CGWindowLevelForKey(kCGFloatingWindowLevelKey)]; + } +} + +#endif // Q_OS_MAC diff --git a/window_helper_windows.cpp b/window_helper_windows.cpp new file mode 100644 index 0000000..ddc723c --- /dev/null +++ b/window_helper_windows.cpp @@ -0,0 +1,122 @@ +#include "window_helper_windows.h" + +#ifdef Q_OS_WIN + +#include +#include +#include +#include + +// Ensure we have the proper Windows version for API functions +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0600 // Windows Vista and later +#endif + +void WindowHelperWindows::setupAlwaysOnTopForFullscreen(QWidget *widget) +{ + if (!widget) + return; + + HWND hwnd = getWindowHandle(widget); + if (!hwnd) + return; + + // Set window as topmost + SetWindowPos(hwnd, HWND_TOPMOST, 0, 0, 0, 0, + SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); + + // Make window appear on all desktops (similar to macOS spaces) + SetWindowLongPtr(hwnd, GWL_EXSTYLE, + GetWindowLongPtr(hwnd, GWL_EXSTYLE) | WS_EX_TOOLWINDOW); + + // Set extended window style to stay on top in fullscreen mode + SetWindowLongPtr(hwnd, GWL_EXSTYLE, + GetWindowLongPtr(hwnd, GWL_EXSTYLE) | WS_EX_TOPMOST); + + // Make window not appear in taskbar + SetWindowLongPtr(hwnd, GWL_EXSTYLE, + GetWindowLongPtr(hwnd, GWL_EXSTYLE) | WS_EX_NOACTIVATE); +} + +void WindowHelperWindows::setWindowAlwaysOnTop(QWidget *widget, bool alwaysOnTop) +{ + if (!widget) + return; + + HWND hwnd = getWindowHandle(widget); + if (!hwnd) + return; + + SetWindowPos(hwnd, alwaysOnTop ? HWND_TOPMOST : HWND_NOTOPMOST, + 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); +} + +void WindowHelperWindows::setWindowClickThrough(QWidget *widget, bool clickThrough) +{ + if (!widget) + return; + + HWND hwnd = getWindowHandle(widget); + if (!hwnd) + return; + + if (clickThrough) + { + // Make window transparent to mouse events + SetWindowLong(hwnd, GWL_EXSTYLE, + GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_TRANSPARENT); + } + else + { + // Remove transparent mouse event handling + SetWindowLongPtr(hwnd, GWL_EXSTYLE, + GetWindowLongPtr(hwnd, GWL_EXSTYLE) & ~WS_EX_TRANSPARENT); + } +} + +void WindowHelperWindows::setWindowExStyle(QWidget *widget, DWORD style, bool enable) +{ + if (!widget) + return; + + HWND hwnd = getWindowHandle(widget); + if (!hwnd) + return; + + DWORD currentStyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE); + if (enable) + { + currentStyle |= style; + } + else + { + currentStyle &= ~style; + } + SetWindowLongPtr(hwnd, GWL_EXSTYLE, currentStyle); +} + +HWND WindowHelperWindows::getWindowHandle(QWidget *widget) +{ + if (!widget) + return nullptr; + + QWindow *window = widget->windowHandle(); + if (!window) + { + // Try to get window handle from native parent + QWidget *nativeParent = widget->nativeParentWidget(); + if (nativeParent) + { + window = nativeParent->windowHandle(); + } + } + + if (window) + { + return reinterpret_cast(window->winId()); + } + + return nullptr; +} + +#endif // Q_OS_WIN diff --git a/window_helper_windows.h b/window_helper_windows.h new file mode 100644 index 0000000..7c37917 --- /dev/null +++ b/window_helper_windows.h @@ -0,0 +1,22 @@ +#ifndef WINDOW_HELPER_WINDOWS_H +#define WINDOW_HELPER_WINDOWS_H + +#include + +#ifdef Q_OS_WIN +#include +#endif + +class WindowHelperWindows +{ +public: + static void setupAlwaysOnTopForFullscreen(QWidget *widget); + static void setWindowAlwaysOnTop(QWidget *widget, bool alwaysOnTop); + static void setWindowClickThrough(QWidget *widget, bool clickThrough); + +private: + static void setWindowExStyle(QWidget *widget, DWORD style, bool enable); + static HWND getWindowHandle(QWidget *widget); +}; + +#endif // WINDOW_HELPER_WINDOWS_H