Skip to content

Commit

Permalink
feat: fork implement window pinning.
Browse files Browse the repository at this point in the history
Title: implement window pinning
Links: henkman#21

```Describe-Text
this is useful when you're running a multi-monitor setup and want some windows to persist on all desktops (such as having a performance monitor on your 2nd monitor)

the hotkey for pinning is CTRL + SHIFT + ALT + P

I opted for a small fixed size array to save memory since you're not gonna pin many windows anyway

it's kind of a big patch (40+ lines) so I understand if you don't want to merge it to keep the lines of code count low

tecnically using 0 as the empty hwnd value is wrong, but it's highly unlikely that a window that isn't a system window is gonna have HWND = 0, so it should be fine and it saves having to initialize the array to INVALID_WINDOW_HANDLE in virgo_init
```
  • Loading branch information
wwxiaoqi committed Aug 18, 2023
1 parent 710531f commit 4e8d9d6
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ Hotkeys:
CTRL + 1..4 -> moves active window to desktop 1..4
ALT + CTRL + SHIFT + Q -> exits the program
ALT + CTRL + SHIFT + S -> starts/stops handling of other hotkeys
ALT + CTRL + SHIFT + T -> pin active window (makes it always visible)

the nerds can build it with

Expand Down
50 changes: 50 additions & 0 deletions virgo.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#endif

#define NUM_DESKTOPS 4
#define NUM_PINNED 8

typedef struct {
HWND *windows;
Expand All @@ -39,6 +40,7 @@ typedef struct {
unsigned handle_hotkeys;
Windows desktops[NUM_DESKTOPS];
Trayicon trayicon;
HWND pinned[NUM_PINNED];
} Virgo;

static void *stb__sbgrowf(void *arr, unsigned increment, unsigned itemsize)
Expand Down Expand Up @@ -182,6 +184,38 @@ static void register_hotkey(unsigned id, unsigned mod, unsigned vk)
}
}

static unsigned virgo_is_pinned(Virgo *v, HWND hwnd) {
unsigned i;
for (i = 0; i < NUM_PINNED; ++i) {
if (v->pinned[i] == hwnd) {
return 1;
}
}
return 0;
}

static void virgo_toggle_pin(Virgo *v, HWND hwnd) {
unsigned i;
unsigned empty = NUM_PINNED;
for (i = 0; i < NUM_PINNED; ++i) {
if (v->pinned[i] == hwnd) {
v->pinned[i] = 0;
windows_add(&v->desktops[v->current], hwnd);
return;
}
if (!v->pinned[i]) {
empty = i;
}
}
if (empty == NUM_PINNED) {
MessageBox(NULL, "reached pinned windows limit", "error",
MB_ICONEXCLAMATION);
return;
}
v->pinned[empty] = hwnd;
windows_del(&v->desktops[v->current], hwnd);
}

static BOOL enum_func(HWND hwnd, LPARAM lParam)
{
unsigned i, e;
Expand All @@ -199,6 +233,9 @@ static BOOL enum_func(HWND hwnd, LPARAM lParam)
}
}
}
if (virgo_is_pinned(v, hwnd)) {
return 1;
}
windows_add(&(v->desktops[v->current]), hwnd);
return 1;
}
Expand All @@ -217,6 +254,12 @@ static void virgo_update(Virgo *v)
}
}
}
for (i = 0; i < NUM_PINNED; i++) {
hwnd = v->pinned[i];
if (!GetWindowThreadProcessId(hwnd, NULL)) {
v->pinned[i] = 0;
}
}
desk = &v->desktops[v->current];
for (i = 0; i < desk->count; i++) {
hwnd = desk->windows[i];
Expand Down Expand Up @@ -256,6 +299,8 @@ static void virgo_init(Virgo *v)
'Q');
register_hotkey(i * 2 + 1, MOD_ALT | MOD_CONTROL | MOD_SHIFT | MOD_NOREPEAT,
'S');
register_hotkey(i * 2 + 2, MOD_ALT | MOD_CONTROL | MOD_SHIFT | MOD_NOREPEAT,
'T');
trayicon_init(&v->trayicon);
}

Expand All @@ -277,6 +322,9 @@ static void virgo_move_to_desk(Virgo *v, unsigned desk)
}
virgo_update(v);
hwnd = GetForegroundWindow();
if (virgo_is_pinned(v, hwnd)) {
return;
}
if (!hwnd || !is_valid_window(hwnd)) {
return;
}
Expand Down Expand Up @@ -312,6 +360,8 @@ void __main(void)
}
if (msg.wParam == NUM_DESKTOPS * 2 + 1) {
virgo_toggle_hotkeys(&v);
} else if (msg.wParam == NUM_DESKTOPS * 2 + 2) {
virgo_toggle_pin(&v, GetForegroundWindow());
} else if (msg.wParam % 2 == 0) {
virgo_go_to_desk(&v, msg.wParam / 2);
} else {
Expand Down

0 comments on commit 4e8d9d6

Please sign in to comment.