Skip to content

Commit b7051ac

Browse files
committed
Add: Project files
0 parents  commit b7051ac

File tree

13 files changed

+598
-0
lines changed

13 files changed

+598
-0
lines changed

.github/workflows/release.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Release Build
2+
3+
on:
4+
push:
5+
tags:
6+
- 'v*'
7+
8+
permissions:
9+
contents: write
10+
11+
jobs:
12+
build:
13+
runs-on: windows-latest
14+
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v3
18+
19+
- name: Set up MSYS2
20+
uses: msys2/setup-msys2@v2
21+
with:
22+
msystem: MINGW64
23+
update: true
24+
install: >-
25+
mingw-w64-x86_64-gcc
26+
mingw-w64-x86_64-make
27+
mingw-w64-x86_64-binutils
28+
base-devel
29+
30+
- name: Build
31+
shell: msys2 {0}
32+
run: |
33+
export PATH="/c/msys64/mingw64/bin:$PATH"
34+
mkdir -p bin
35+
# Create resource file from manifest and icon
36+
echo '1 24 "src/app.manifest"' > src/app.rc
37+
echo '400 ICON "assets/app.ico"' >> src/app.rc
38+
windres src/app.rc -O coff -o src/app.res
39+
# Compile with manifest, icon, and optimizations
40+
gcc src/keepalive.c src/tray.c src/timer.c src/power.c src/app.res -o bin/KeepAlive.exe -mwindows -lcomctl32 -luser32 -lshell32 -Os -s
41+
42+
- name: Create Release
43+
id: create_release
44+
uses: softprops/action-gh-release@v1
45+
with:
46+
files: bin/KeepAlive.exe
47+
name: Release ${{ github.ref_name }}
48+
draft: false
49+
prerelease: false
50+
generate_release_notes: true
51+
env:
52+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.gitignore

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
2+
build/
3+
Debug/
4+
Release/
5+
x64/
6+
x86/
7+
[Oo]bj/
8+
[Bb]in/
9+
10+
.vs/
11+
*.user
12+
*.userosscache
13+
*.sln.docstates
14+
*.suo
15+
*.userprefs
16+
*.dbmdl
17+
*.dbproj.schemaview
18+
*.jfm
19+
*.pfx
20+
*.publishsettings
21+
orleans.codegen.cs
22+
23+
CMakeFiles/
24+
CMakeCache.txt
25+
cmake_install.cmake
26+
*.cmake
27+
!CMakeLists.txt
28+
29+
30+
*.rc
31+
!src/app.manifest
32+
33+
34+
*.slo
35+
*.lo
36+
*.o
37+
*.obj
38+
39+
40+
*.gch
41+
*.pch
42+
43+
44+
*.so
45+
*.dylib
46+
*.dll
47+
48+
49+
*.lai
50+
*.la
51+
*.a
52+
*.lib
53+
54+
55+
*.exe
56+
*.out
57+
*.app
58+
59+
60+
.vscode/
61+
.idea/
62+
*.swp
63+
*.swo
64+
*~
65+
66+
67+
Thumbs.db
68+
ehthumbs.db
69+
Desktop.ini
70+
$RECYCLE.BIN/
71+
72+
73+
!assets/
74+
!assets/app.ico

CMakeLists.txt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
cmake_minimum_required(VERSION 3.10)
2+
project(KeepAlive C)
3+
4+
5+
set(CMAKE_C_STANDARD 11)
6+
set(CMAKE_C_STANDARD_REQUIRED ON)
7+
8+
9+
set(RESOURCE_FILE src/app.rc)
10+
file(WRITE ${RESOURCE_FILE} "400 ICON \"${CMAKE_SOURCE_DIR}/assets/app.ico\"\n")
11+
file(APPEND ${RESOURCE_FILE} "1 24 \"${CMAKE_SOURCE_DIR}/src/app.manifest\"")
12+
13+
set(SOURCES
14+
src/keepalive.c
15+
src/tray.c
16+
src/timer.c
17+
src/power.c
18+
${RESOURCE_FILE}
19+
)
20+
21+
add_executable(KeepAlive WIN32 ${SOURCES})
22+
23+
set_target_properties(KeepAlive PROPERTIES
24+
LINK_FLAGS "/SUBSYSTEM:WINDOWS /ENTRY:WinMainCRTStartup /MANIFEST:NO"
25+
)
26+
27+
target_link_libraries(KeepAlive user32 comctl32 shell32)
28+
29+
30+
file(COPY ${CMAKE_SOURCE_DIR}/assets DESTINATION ${CMAKE_BINARY_DIR})

README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# KeepAlive
2+
3+
A Windows application that prevents the system from sleeping. It runs in the system tray and allows you to set a timer for how long you want to prevent sleep mode.
4+
5+
## Features
6+
7+
- System tray icon with context menu
8+
- Multiple duration options (30 minutes, 1 hour, 2 hours, 4 hours, 8 hours)
9+
- Shows remaining time in the tray icon tooltip
10+
- Prevents system sleep while active
11+
- Single instance check
12+
- Automatic sleep prevention when any application is in fullscreen mode
13+
14+
## Building
15+
16+
### Prerequisites
17+
18+
- CMake (version 3.10 or higher)
19+
- Visual Studio with C/C++ development tools
20+
- Windows SDK
21+
22+
### Build Steps
23+
24+
1. Create a build directory:
25+
```bash
26+
mkdir build
27+
cd build
28+
```
29+
30+
2. Configure the project:
31+
```bash
32+
cmake ..
33+
```
34+
35+
3. Build the project:
36+
```bash
37+
cmake --build .
38+
```
39+
40+
The executable will be created in the `build` directory.
41+
42+
## Usage
43+
44+
1. Run the application:
45+
```bash
46+
./KeepAlive
47+
```
48+
49+
2. The application will appear in the system tray. Right-click the icon to:
50+
- View current status
51+
- Start/Stop the timer
52+
- Select duration
53+
- Exit the application
54+
55+
3. The tray icon tooltip will show the remaining time when active.
56+
57+
## License
58+
59+
This project is licensed under the MIT License - see the LICENSE file for details.

assets/app.ico

4.19 KB
Binary file not shown.

src/app.manifest

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2+
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
3+
<assemblyIdentity
4+
version="1.0.0.0"
5+
processorArchitecture="*"
6+
name="KeepAlive"
7+
type="win32"
8+
/>
9+
<description>KeepAlive - System Sleep Prevention Tool</description>
10+
<dependency>
11+
<dependentAssembly>
12+
<assemblyIdentity
13+
type="win32"
14+
name="Microsoft.Windows.Common-Controls"
15+
version="6.0.0.0"
16+
processorArchitecture="*"
17+
publicKeyToken="6595b64144ccf1df"
18+
language="*"
19+
/>
20+
</dependentAssembly>
21+
</dependency>
22+
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
23+
<security>
24+
<requestedPrivileges>
25+
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
26+
</requestedPrivileges>
27+
</security>
28+
</trustInfo>
29+
</assembly>

src/keepalive.c

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#include <windows.h>
2+
#include <commctrl.h>
3+
#include "tray.h"
4+
#include "timer.h"
5+
#include "power.h"
6+
7+
#define WM_TRAYICON (WM_USER + 1)
8+
#define APP_MUTEX_NAME "KeepAliveSingleInstance"
9+
#define FULLSCREEN_CHECK_TIMER 2
10+
#define FULLSCREEN_CHECK_INTERVAL 1000
11+
12+
HINSTANCE hInst;
13+
HWND hwnd;
14+
TrayContext trayCtx;
15+
TimerContext timerCtx;
16+
HANDLE hMutex;
17+
18+
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
19+
20+
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
21+
hInst = hInstance;
22+
23+
hMutex = CreateMutex(NULL, TRUE, APP_MUTEX_NAME);
24+
if (GetLastError() == ERROR_ALREADY_EXISTS) {
25+
MessageBox(NULL, "KeepAlive is already running!", "Warning", MB_ICONWARNING);
26+
return 1;
27+
}
28+
29+
WNDCLASSEX wc = {0};
30+
wc.cbSize = sizeof(WNDCLASSEX);
31+
wc.lpfnWndProc = WindowProc;
32+
wc.hInstance = hInstance;
33+
wc.lpszClassName = "KeepAliveClass";
34+
RegisterClassEx(&wc);
35+
36+
hwnd = CreateWindowEx(0, "KeepAliveClass", "KeepAlive",
37+
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
38+
0, 0, NULL, NULL, hInstance, NULL);
39+
40+
trayCtx.hwnd = hwnd;
41+
init_tray(&trayCtx, hInstance);
42+
43+
SetTimer(hwnd, FULLSCREEN_CHECK_TIMER, FULLSCREEN_CHECK_INTERVAL, NULL);
44+
45+
MSG msg;
46+
while (GetMessage(&msg, NULL, 0, 0)) {
47+
TranslateMessage(&msg);
48+
DispatchMessage(&msg);
49+
}
50+
51+
cleanup_tray(&trayCtx);
52+
ReleaseMutex(hMutex);
53+
CloseHandle(hMutex);
54+
return 0;
55+
}
56+
57+
LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
58+
switch (uMsg) {
59+
case WM_TRAYICON:
60+
if (lParam == WM_RBUTTONUP) {
61+
show_tray_menu(&trayCtx);
62+
}
63+
break;
64+
65+
case WM_COMMAND:
66+
switch (LOWORD(wParam)) {
67+
case ID_START:
68+
start_timer(&timerCtx, hwnd, 30);
69+
update_menu_state(&trayCtx, TRUE);
70+
break;
71+
case ID_30MIN:
72+
start_timer(&timerCtx, hwnd, 30);
73+
update_menu_state(&trayCtx, TRUE);
74+
break;
75+
case ID_1HOUR:
76+
start_timer(&timerCtx, hwnd, 60);
77+
update_menu_state(&trayCtx, TRUE);
78+
break;
79+
case ID_2HOURS:
80+
start_timer(&timerCtx, hwnd, 120);
81+
update_menu_state(&trayCtx, TRUE);
82+
break;
83+
case ID_4HOURS:
84+
start_timer(&timerCtx, hwnd, 240);
85+
update_menu_state(&trayCtx, TRUE);
86+
break;
87+
case ID_8HOURS:
88+
start_timer(&timerCtx, hwnd, 480);
89+
update_menu_state(&trayCtx, TRUE);
90+
break;
91+
case ID_STOP:
92+
stop_timer(&timerCtx, hwnd);
93+
update_menu_state(&trayCtx, FALSE);
94+
break;
95+
case ID_EXIT:
96+
PostQuitMessage(0);
97+
break;
98+
}
99+
update_tray_tip(&trayCtx, get_remaining_time_str(&timerCtx));
100+
update_status_text(&trayCtx, get_remaining_time_str(&timerCtx));
101+
break;
102+
103+
case WM_TIMER:
104+
if (wParam == FULLSCREEN_CHECK_TIMER) {
105+
check_fullscreen_state();
106+
} else {
107+
update_timer_status(&timerCtx);
108+
if (!timerCtx.isActive) {
109+
update_menu_state(&trayCtx, FALSE);
110+
}
111+
update_tray_tip(&trayCtx, get_remaining_time_str(&timerCtx));
112+
update_status_text(&trayCtx, get_remaining_time_str(&timerCtx));
113+
}
114+
break;
115+
116+
case WM_DESTROY:
117+
PostQuitMessage(0);
118+
break;
119+
}
120+
return DefWindowProc(hwnd, uMsg, wParam, lParam);
121+
}

0 commit comments

Comments
 (0)