Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions AAS.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ def MakeArchive(srcDir):
for x in os.listdir(tempDir):
if x.endswith(".exe"):
EmbedAndDeleteManifest(os.path.join(tempDir, x))
print(shutil.get_archive_formats())
shutil.make_archive(tempDir, "zip", tempDir)
shutil.rmtree(tempDir)

Expand All @@ -83,6 +84,7 @@ def Format():
for name in files:
if name.endswith(".c") or name.endswith(".h"):
os.system(f"clang-format.exe { path }/{ name } -i")
print(f"clang-format.exe { path }/{ name } -i")

import sys
if __name__ == "__main__":
Expand Down
52 changes: 48 additions & 4 deletions Assets/AAS/AddToStartup.bat
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,9 @@ if not exist "%fullPath%" (
exit
)

schtasks /create /sc ONEVENT /ec Application /tn AltAppSwitcher /tr "'%fullPath%'" /RL HIGHEST /F

call :createTask HighestAvailable
if !errorlevel! neq 0 (
schtasks /create /sc ONEVENT /ec Application /tn AltAppSwitcher /tr "'%fullPath%'" /RL LIMITED /F
call :createTask LeastPrivilege
if !errorlevel! neq 0 (
msg * "Task creation failed. If a previous task was created with admin privileges, please re-run this utility as an admin."
exit
Expand All @@ -30,7 +29,52 @@ if !errorlevel! neq 0 (
)

if "%limited%" == "true" (
msg * "Startup task added with limited rights. Re-run this utility as admin for admin rights.
msg * "Startup task added with limited rights. Re-run this utility as admin for admin rights."
) else (
msg * "Startup task added. Re-run this utility when moving AltAppSwitcher.exe."
)
exit /b

:createTask
set "curUser=%USERDOMAIN%\%USERNAME%"
set "xmlFile=%TEMP%\AltAppSwitcher_task.xml"
(
echo ^<?xml version="1.0" encoding="UTF-16"?^>
echo ^<Task version="1.2" xmlns="http://schemas.microsoft.com/windows/2004/02/mit/task"^>
echo ^<Triggers^>
echo ^<LogonTrigger^>
echo ^<Enabled^>true^</Enabled^>
echo ^<UserId^>%curUser%^</UserId^>
echo ^</LogonTrigger^>
echo ^<SessionStateChangeTrigger^>
echo ^<Enabled^>true^</Enabled^>
echo ^<StateChange^>SessionUnlock^</StateChange^>
echo ^<UserId^>%curUser%^</UserId^>
echo ^</SessionStateChangeTrigger^>
echo ^</Triggers^>
echo ^<Principals^>
echo ^<Principal id="Author"^>
echo ^<LogonType^>InteractiveToken^</LogonType^>
echo ^<RunLevel^>%1^</RunLevel^>
echo ^</Principal^>
echo ^</Principals^>
echo ^<Settings^>
echo ^<MultipleInstancesPolicy^>IgnoreNew^</MultipleInstancesPolicy^>
echo ^<DisallowStartIfOnBatteries^>false^</DisallowStartIfOnBatteries^>
echo ^<StopIfGoingOnBatteries^>false^</StopIfGoingOnBatteries^>
echo ^<ExecutionTimeLimit^>PT0S^</ExecutionTimeLimit^>
echo ^<Priority^>7^</Priority^>
echo ^</Settings^>
echo ^<Actions^>
echo ^<Exec^>
echo ^<Command^>%fullPath%^</Command^>
echo ^</Exec^>
echo ^</Actions^>
echo ^</Task^>
) > "%xmlFile%"

schtasks /create /tn AltAppSwitcher /xml "%xmlFile%" /F

set "result=!errorlevel!"
del "%xmlFile%"
exit /b !result!
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ clang_tidy_disable_if_dbg = --checks=-*
endif
$(ALLOBJECTS): $(OBJDIR)/%.o: $(ROOTDIR)/%.c $(ALLH)
clang-format $< --dry-run --Werror
clang-tidy $< --warnings-as-errors=* --allow-no-checks $(clang_tidy_disable_if_dbg) -- $(CFLAGS)
clang-tidy $< --warnings-as-errors=* --allow-no-checks $(clang_tidy_disable_if_dbg) --header-filter=$(SOURCEDIR)/.* -- $(CFLAGS)
$(CC) $(CFLAGS) -MJ $@.json -c $< -o $@

# Build exe targets (link):
Expand Down
7 changes: 1 addition & 6 deletions Sources/.clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@ Checks:
cert-*,
concurrency-*,
portability-*,
readability-*,
-bugprone-easily-swappable-parameters,
-readability-identifier-length,
-readability-magic-numbers,
-readability-uppercase-literal-suffix,
-readability-braces-around-statements,
-readability-function-cognitive-complexity,
-portability-avoid-pragma-once,
-cert-dcl16-c
53 changes: 30 additions & 23 deletions Sources/AltAppSwitcher/App.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,8 @@ static DWORD MainThread;

static void RestoreKey(WORD keyCode)
{
// if (GetAsyncKeyState(VK_RCONTROL) & 0x8000)
// {
// printf("WHY\n");
// }
{
INPUT input = {};
INPUT input = { };
input.type = INPUT_KEYBOARD;
input.ki.wVk = VK_RCONTROL;
input.ki.dwFlags = 0;
Expand All @@ -59,15 +55,15 @@ static void RestoreKey(WORD keyCode)

{
// Needed ?
INPUT input = {};
INPUT input = { };
input.type = INPUT_KEYBOARD;
input.ki.wVk = KeyConfig->Invert;
input.ki.dwFlags = KEYEVENTF_KEYUP;
const UINT uSent = SendInput(1, &input, sizeof(INPUT));
ASSERT(uSent == 1);
}
{
INPUT input = {};
INPUT input = { };
input.type = INPUT_KEYBOARD;
input.ki.wVk = keyCode;
input.ki.dwFlags = KEYEVENTF_KEYUP;
Expand All @@ -78,7 +74,7 @@ static void RestoreKey(WORD keyCode)
usleep(1000);
if (GetAsyncKeyState(VK_RCONTROL) & 0x8000) {
// printf("need reset key 0\n");
INPUT input = {};
INPUT input = { };
input.type = INPUT_KEYBOARD;
input.ki.wVk = VK_RCONTROL;
input.ki.dwFlags = KEYEVENTF_KEYUP;
Expand All @@ -89,7 +85,7 @@ static void RestoreKey(WORD keyCode)
usleep(1000);
if (GetKeyState(VK_RCONTROL) & 0x8000) {
// printf("need reset key 1\n");
INPUT input = {};
INPUT input = { };
input.type = INPUT_KEYBOARD;
input.ki.wVk = VK_RCONTROL;
input.ki.dwFlags = KEYEVENTF_KEYUP;
Expand All @@ -115,19 +111,19 @@ static LRESULT KbProc(int nCode, WPARAM wParam, LPARAM lParam)
const bool prevAppKey = kbStrut.vkCode == KeyConfig->PrevApp;
const bool winHoldKey = kbStrut.vkCode == KeyConfig->WinHold;
const bool nextWinKey = kbStrut.vkCode == KeyConfig->WinSwitch;
const bool isWatchedKey = appHoldKey || nextAppKey || prevAppKey || winHoldKey || nextWinKey;
const bool isWatchedKey = appHoldKey || nextAppKey || prevAppKey || winHoldKey || nextWinKey; // NOLINT
if (!isWatchedKey)
return CallNextHookEx(NULL, nCode, wParam, lParam);

static enum Mode mode = ModeNone;

const bool rel = kbStrut.flags & LLKHF_UP;
const bool rel = (kbStrut.flags & LLKHF_UP) != 0;

// Update target app state
bool bypassMsg = false;
const enum Mode prevMode = mode;
{
const bool winHoldRelease = winHoldKey && rel;
const bool winHoldRelease = (winHoldKey && rel) != 0;
const bool appHoldRelease = appHoldKey && rel;
const bool nextApp = nextAppKey && !rel;
const bool nextWin = nextWinKey && !rel;
Expand Down Expand Up @@ -166,7 +162,7 @@ static DWORD KbHookCb(LPVOID param)
{
(void)param;
ASSERT(SetWindowsHookEx(WH_KEYBOARD_LL, KbProc, 0, 0));
MSG msg = {};
MSG msg = { };

while (GetMessage(&msg, NULL, 0, 0) > 0) { }

Expand All @@ -188,12 +184,22 @@ static HWND GetFirstChild(HWND win)
}
#endif

static void AssertSingleInstance()
{
HANDLE hMutex = CreateMutexA(NULL, TRUE, "Global\\AltAppSwitcher{4fb3d3f7-9f35-41ce-b4d2-83c18eac3f54}");
if (GetLastError() == ERROR_ALREADY_EXISTS) {
CloseHandle(hMutex);
ExitProcess(1);
}
}

int StartAltAppSwitcher(HINSTANCE instance)
{
SetLastError(0);
AssertSingleInstance();
ASSERT(SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS));

static struct AppData appData = {};
static struct AppData appData = { };
{
appData.Instance = instance;
// Hook needs globals
Expand Down Expand Up @@ -223,11 +229,11 @@ int StartAltAppSwitcher(HINSTANCE instance)
CloseHandle(tok);
}

char updater[MAX_PATH] = {};
char updater[MAX_PATH] = { };
UpdaterPath(updater);
if (appData.Config.CheckForUpdates && access(updater, F_OK) == 0) {
STARTUPINFO si = {};
PROCESS_INFORMATION pi = {};
STARTUPINFO si = { };
PROCESS_INFORMATION pi = { };
CreateProcess(NULL, updater, 0, 0, false, CREATE_NEW_PROCESS_GROUP, 0, 0,
&si, &pi);
}
Expand All @@ -237,9 +243,10 @@ int StartAltAppSwitcher(HINSTANCE instance)
AppModeInit(instance, &appData.Config);
WinModeInit(instance, &appData.Config);

HANDLE threadKbHook = CreateRemoteThread(GetCurrentProcess(), NULL, 0, KbHookCb, (void*)&appData, 0, NULL);
HANDLE threadKbHook = CreateThread(NULL, 0, KbHookCb, (void*)&appData, CREATE_SUSPENDED, NULL);
(void)threadKbHook;

SetThreadPriority(threadKbHook, THREAD_PRIORITY_TIME_CRITICAL);
ResumeThread(threadKbHook);
AllowSetForegroundWindow(GetCurrentProcessId());

HANDLE token;
Expand All @@ -258,7 +265,7 @@ int StartAltAppSwitcher(HINSTANCE instance)
ChangeWindowMessageFilter(MSG_RESTART_AAS, MSGFLT_ADD);
ChangeWindowMessageFilter(MSG_CLOSE_AAS, MSGFLT_ADD);

MSG msg = {};
MSG msg = { };
bool restartAAS = false;
bool closeAAS = false;
while (GetMessage(&msg, NULL, 0, 0) > 0) {
Expand Down Expand Up @@ -324,10 +331,10 @@ int StartAltAppSwitcher(HINSTANCE instance)
WinModeDeinit();

if (restartAAS) {
STARTUPINFO si = {};
PROCESS_INFORMATION pi = {};
STARTUPINFO si = { };
PROCESS_INFORMATION pi = { };

char currentExe[MAX_PATH] = {};
char currentExe[MAX_PATH] = { };
GetModuleFileName(NULL, currentExe, MAX_PATH);

CreateProcess(NULL, currentExe, 0, 0, false, CREATE_NEW_PROCESS_GROUP, 0, 0,
Expand Down
Loading