commits
tags
#include <ncurses.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "monitors.h"
#include "draw.h"
#define SCALE 40
#define SNAP_DIST SCALE /* pixlar — en knapptryckning */
static void snap(Monitor *mons, int count, int idx) {
Monitor *m = &mons[idx];
for (int i = 0; i < count; i++) {
if (i == idx) continue;
Monitor *o = &mons[i];
int mr = m->x + m->w, or_ = o->x + o->w;
int mb = m->y + m->h, ob = o->y + o->h;
/* horisontell snap: vänster mot höger och tvärtom */
if (abs(m->x - or_) < SNAP_DIST) m->x = or_;
else if (abs(mr - o->x) < SNAP_DIST) m->x = o->x - m->w;
/* vertikal snap: topp mot botten och tvärtom */
if (abs(m->y - ob) < SNAP_DIST) m->y = ob;
else if (abs(mb - o->y) < SNAP_DIST) m->y = o->y - m->h;
}
if (m->x < 0) m->x = 0;
if (m->y < 0) m->y = 0;
}
int main(void) {
Monitor mons[MAX_MONITORS];
int nmons = monitors_get(mons, MAX_MONITORS);
if (nmons == 0) {
fprintf(stderr, "xrantui: inga aktiva skärmar hittades\n");
return 1;
}
/* spara ursprungspositioner för ångra */
Monitor orig[MAX_MONITORS];
memcpy(orig, mons, sizeof(Monitor) * (size_t)nmons);
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
curs_set(0);
draw_init_colors();
int selected = 0;
const char *msg = NULL;
for (;;) {
draw_monitors(mons, nmons, selected, SCALE, msg);
refresh();
msg = NULL;
int ch = getch();
switch (ch) {
case 'q':
case 'Q':
goto done;
case '\t':
selected = (selected + 1) % nmons;
break;
case KEY_UP:
mons[selected].y -= SCALE;
if (mons[selected].y < 0) mons[selected].y = 0;
snap(mons, nmons, selected);
break;
case KEY_DOWN:
mons[selected].y += SCALE;
snap(mons, nmons, selected);
break;
case KEY_LEFT:
mons[selected].x -= SCALE;
if (mons[selected].x < 0) mons[selected].x = 0;
snap(mons, nmons, selected);
break;
case KEY_RIGHT:
mons[selected].x += SCALE;
snap(mons, nmons, selected);
break;
case 'p':
case 'P':
/* sätt vald skärm som primär, rensa övriga */
for (int i = 0; i < nmons; i++)
mons[i].primary = (i == selected) ? 1 : 0;
msg = "Primärskärm satt — tryck Enter för att applicera";
break;
case '+':
case '=':
if (mons[selected].nmodes > 0) {
monitors_cycle_mode(&mons[selected], -1); /* -1 = större (lista är störst->minst) */
snap(mons, nmons, selected);
msg = "Upplösning ändrad — tryck Enter för att applicera";
} else {
msg = "Inga kända upplösningar för denna skärm";
}
break;
case '-':
case '_':
if (mons[selected].nmodes > 0) {
monitors_cycle_mode(&mons[selected], 1); /* +1 = mindre */
snap(mons, nmons, selected);
msg = "Upplösning ändrad — tryck Enter för att applicera";
} else {
msg = "Inga kända upplösningar för denna skärm";
}
break;
case 'u':
case 'U':
memcpy(mons, orig, sizeof(Monitor) * (size_t)nmons);
msg = "Återställt till ursprungspositioner";
break;
case KEY_ENTER:
case '\n':
case '\r':
monitors_apply(mons, nmons);
msg = "Applicerat";
break;
case 's':
case 'S':
if (monitors_save(mons, nmons) == 0)
msg = "Sparat — .desktop + .xprofile + .xinitrc (om de finns)";
else
msg = "Fel: kunde inte spara";
break;
}
}
done:
endwin();
return 0;
}