This commit is contained in:
ivaquero
2026-04-21 11:42:58 +08:00
parent 1a20802dad
commit 2e460fcb76
17 changed files with 55 additions and 391 deletions
+2 -1
View File
@@ -88,5 +88,6 @@ Icon
.cmake .cmake
.qtc_clangd .qtc_clangd
.qmake.stash .qmake.stash
build
*.dmg *.dmg
build
test*
+2 -2
View File
@@ -14,7 +14,7 @@
"defines": [], "defines": [],
"compilerPath": "/usr/bin/clang++", "compilerPath": "/usr/bin/clang++",
"cStandard": "c17", "cStandard": "c17",
"cppStandard": "c++17", "cppStandard": "c++20",
"intelliSenseMode": "macos-clang-arm64", "intelliSenseMode": "macos-clang-arm64",
"configurationProvider": "kylinideteam.cmake-intellisence", "configurationProvider": "kylinideteam.cmake-intellisence",
"macFrameworkPath": [ "macFrameworkPath": [
@@ -36,7 +36,7 @@
], ],
"compilerPath": "${env:SCOOP}\\apps\\msys2-cn\\current\\ucrt64\\bin\\g++.exe", "compilerPath": "${env:SCOOP}\\apps\\msys2-cn\\current\\ucrt64\\bin\\g++.exe",
"cStandard": "c17", "cStandard": "c17",
"cppStandard": "c++17", "cppStandard": "c++20",
"intelliSenseMode": "windows-gcc-x64", "intelliSenseMode": "windows-gcc-x64",
"configurationProvider": "kylinideteam.cmake-intellisence" "configurationProvider": "kylinideteam.cmake-intellisence"
} }
+1 -1
View File
@@ -16,7 +16,7 @@ When on macOS / Linux, the clock on the menu bar is too small to be noticeable,
## ✨ Features ## ✨ Features
- Cross Platform - [ ] **Cross Platform**
- [x] MacOS - [x] MacOS
- [x] Windows - [x] Windows
- [ ] Linux - [ ] Linux
+1 -1
View File
@@ -1,7 +1,7 @@
#!/bin/bash #!/bin/bash
# Build script # Build script
echo "Starting QFlock build..." echo "Starting Clouck build..."
# Create build directory if it doesn't exist # Create build directory if it doesn't exist
mkdir -p build mkdir -p build
+33 -1
View File
@@ -8,6 +8,7 @@
#include <QInputDialog> #include <QInputDialog>
#include <QMessageBox> #include <QMessageBox>
#include <QApplication> #include <QApplication>
#include <QScreen>
ClockWidget::ClockWidget(QWidget *parent) ClockWidget::ClockWidget(QWidget *parent)
: QWidget(parent), m_dragging(false), m_resizing(false), m_resizeBorder(5) : QWidget(parent), m_dragging(false), m_resizing(false), m_resizeBorder(5)
@@ -265,6 +266,28 @@ bool ClockWidget::isInResizeArea(const QPoint &pos) const
return resizeArea.contains(pos); return resizeArea.contains(pos);
} }
void ClockWidget::positionAtBottomRight()
{
// Get primary screen geometry
QScreen *screen = QApplication::primaryScreen();
if (!screen)
{
// Fallback to default position if no screen available
move(100, 100);
return;
}
QRect screenGeometry = screen->availableGeometry();
QSize windowSize = m_configManager->windowSize();
// Calculate position: bottom-right corner with some margin
int margin = 20; // 20 pixels margin from screen edges
int x = screenGeometry.right() - windowSize.width() - margin;
int y = screenGeometry.bottom() - windowSize.height() - margin;
move(x, y);
}
void ClockWidget::loadSettings() void ClockWidget::loadSettings()
{ {
m_configManager = new ConfigManager(this); m_configManager = new ConfigManager(this);
@@ -283,7 +306,16 @@ void ClockWidget::loadSettings()
m_alwaysOnTop = m_configManager->alwaysOnTop(); m_alwaysOnTop = m_configManager->alwaysOnTop();
// Restore window position and size // Restore window position and size
move(m_configManager->windowPosition()); QPoint windowPos = m_configManager->windowPosition();
if (windowPos.x() == -1 && windowPos.y() == -1)
{
// First time: position at bottom-right corner
positionAtBottomRight();
}
else
{
move(windowPos);
}
resize(m_configManager->windowSize()); resize(m_configManager->windowSize());
// Update always on top checkbox in menu // Update always on top checkbox in menu
+1
View File
@@ -64,6 +64,7 @@ private:
// Helper methods // Helper methods
bool isInResizeArea(const QPoint &pos) const; bool isInResizeArea(const QPoint &pos) const;
void positionAtBottomRight();
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
void setupMacOSWindowProperties(); void setupMacOSWindowProperties();
+3 -3
View File
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<QFlockConfig> <ClouckConfig>
<FontColor>#ffffffff</FontColor> <FontColor>#ffffffff</FontColor>
<BackgroundColor>#96000000</BackgroundColor> <BackgroundColor>#96000000</BackgroundColor>
<FontSize>24</FontSize> <FontSize>24</FontSize>
<AlwaysOnTop>true</AlwaysOnTop> <AlwaysOnTop>true</AlwaysOnTop>
<WindowPosition>1132,708</WindowPosition> <WindowPosition>1236,784</WindowPosition>
<WindowSize>137,59</WindowSize> <WindowSize>137,59</WindowSize>
</QFlockConfig> </ClouckConfig>
+7 -3
View File
@@ -26,7 +26,7 @@ bool ConfigManager::loadSettings(const QString &filename)
QXmlStreamReader reader(&file); QXmlStreamReader reader(&file);
// Check if it's a valid XML file // Check if it's a valid XML file
if (!reader.readNextStartElement() || reader.name() != QString("QFlockConfig")) if (!reader.readNextStartElement() || reader.name() != QString("ClouckConfig"))
{ {
qDebug() << "Invalid config file format"; qDebug() << "Invalid config file format";
file.close(); file.close();
@@ -108,7 +108,7 @@ bool ConfigManager::saveSettings(const QString &filename)
writer.writeStartDocument(); writer.writeStartDocument();
// Root element // Root element
writer.writeStartElement("QFlockConfig"); writer.writeStartElement("ClouckConfig");
// Font color // Font color
writer.writeTextElement("FontColor", m_fontColor.name(QColor::HexArgb)); writer.writeTextElement("FontColor", m_fontColor.name(QColor::HexArgb));
@@ -159,6 +159,10 @@ void ConfigManager::setDefaultValues()
m_backgroundColor = QColor(0, 0, 0, 150); // Semi-transparent black m_backgroundColor = QColor(0, 0, 0, 150); // Semi-transparent black
m_fontSize = 24; m_fontSize = 24;
m_alwaysOnTop = true; m_alwaysOnTop = true;
m_windowPosition = QPoint(100, 100);
// Calculate initial position: bottom-right corner of primary screen
// Position will be set properly when widget is shown for the first time
m_windowPosition = QPoint(-1, -1); // Special value indicating "not set yet"
m_windowSize = QSize(200, 80); // Default clock size m_windowSize = QSize(200, 80); // Default clock size
} }
+3 -3
View File
@@ -5,9 +5,9 @@ int main(int argc, char *argv[])
{ {
QApplication app(argc, argv); QApplication app(argc, argv);
app.setApplicationName("QFlock"); app.setApplicationName("Clouck");
app.setOrganizationName("QFlock"); app.setOrganizationName("Clouck");
app.setApplicationDisplayName("QFlock"); app.setApplicationDisplayName("Clouck");
ClockWidget clock; ClockWidget clock;
clock.show(); clock.show();
-27
View File
@@ -1,27 +0,0 @@
#!/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
-39
View File
@@ -1,39 +0,0 @@
#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QSize>
#include <QPoint>
#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;
}
-128
View File
@@ -1,128 +0,0 @@
#!/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"
-15
View File
@@ -1,15 +0,0 @@
#!/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."
-80
View File
@@ -1,80 +0,0 @@
#!/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"
-57
View File
@@ -1,57 +0,0 @@
#!/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!"
-29
View File
@@ -1,29 +0,0 @@
# Build and Run Test
echo "Building QFlock with XML configuration..."
# Clean previous build
./clean.sh
# Build the project
./build.sh
# Check if build was successful
if [ $? -eq 0 ]; then
echo "Build successful! Testing XML configuration..."
# Show config file content
echo "Config file content:"
if [ -f "config.xml" ]; then
cat config.xml
else
echo "No config.xml found (will be created on first run)"
fi
echo ""
echo "You can now run the application:"
echo "./build/flock.app/Contents/MacOS/flock # macOS"
echo "./build/flock # Linux"
else
echo "Build failed!"
fi
+2 -1
View File
@@ -5,7 +5,6 @@
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
#include <Windows.h> #include <Windows.h>
#endif
class WindowHelperWindows class WindowHelperWindows
{ {
@@ -19,4 +18,6 @@ private:
static HWND getWindowHandle(QWidget *widget); static HWND getWindowHandle(QWidget *widget);
}; };
#endif // Q_OS_WIN
#endif // WINDOW_HELPER_WINDOWS_H #endif // WINDOW_HELPER_WINDOWS_H