From 0d813ff3698712bc2cad38c076421fcf38eeb63d Mon Sep 17 00:00:00 2001 From: seanpringle Date: Fri, 21 Sep 2012 15:53:00 +1000 Subject: [PATCH] rotate layout for rotated monitor --- config.h | 22 +++++++------- xoat.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 89 insertions(+), 20 deletions(-) diff --git a/config.h b/config.h index f4d32ec..87866b9 100644 --- a/config.h +++ b/config.h @@ -1,6 +1,6 @@ // xoat config. -#define BORDER 1 +#define BORDER 2 #define BORDER_BLUR "Dark Gray" #define BORDER_FOCUS "Orange" #define BORDER_URGENT "Red" @@ -22,8 +22,8 @@ // The layout can be flipped so SPOT1 is on the right. // If you do this, review the directional move/focus key bindings too. -//#define SPOT1_ALIGN SPOT1_RIGHT -#define SPOT1_ALIGN SPOT1_LEFT +//#define SPOT1_ALIGN SPOT1_LEFT +#define SPOT1_ALIGN SPOT1_RIGHT // Width of SPOT1 as percentage of screen width. #define SPOT1_WIDTH_PCT 67 @@ -61,16 +61,16 @@ binding keys[] = { // Focus the top-most window in a spot. - { .mod = Mod4Mask, .key = XK_Left, .act = action_focus, .num = SPOT1 }, - { .mod = Mod4Mask, .key = XK_Up, .act = action_focus, .num = SPOT2 }, - { .mod = Mod4Mask, .key = XK_Right, .act = action_focus, .num = SPOT2 }, - { .mod = Mod4Mask, .key = XK_Down, .act = action_focus, .num = SPOT3 }, + { .mod = Mod4Mask, .key = XK_Left, .act = action_focus_direction, .num = LEFT }, + { .mod = Mod4Mask, .key = XK_Up, .act = action_focus_direction, .num = UP }, + { .mod = Mod4Mask, .key = XK_Right, .act = action_focus_direction, .num = RIGHT }, + { .mod = Mod4Mask, .key = XK_Down, .act = action_focus_direction, .num = DOWN }, // Move the current window to another spot. - { .mod = ShiftMask|Mod4Mask, .key = XK_Left, .act = action_move, .num = SPOT1 }, - { .mod = ShiftMask|Mod4Mask, .key = XK_Up, .act = action_move, .num = SPOT2 }, - { .mod = ShiftMask|Mod4Mask, .key = XK_Right, .act = action_move, .num = SPOT2 }, - { .mod = ShiftMask|Mod4Mask, .key = XK_Down, .act = action_move, .num = SPOT3 }, + { .mod = ShiftMask|Mod4Mask, .key = XK_Left, .act = action_move_direction, .num = LEFT }, + { .mod = ShiftMask|Mod4Mask, .key = XK_Up, .act = action_move_direction, .num = UP }, + { .mod = ShiftMask|Mod4Mask, .key = XK_Right, .act = action_move_direction, .num = RIGHT }, + { .mod = ShiftMask|Mod4Mask, .key = XK_Down, .act = action_move_direction, .num = DOWN }, // Flip between the top two windows in the current spot. { .mod = Mod4Mask, .key = XK_Tab, .act = action_other }, diff --git a/xoat.c b/xoat.c index bfd73a3..3b16ac1 100644 --- a/xoat.c +++ b/xoat.c @@ -95,6 +95,7 @@ Atom atoms[ATOMS]; enum { MONITOR_CURRENT=-1 }; enum { SPOT1=1, SPOT2, SPOT3, SPOT_CURRENT, SPOT_SMART, SPOT1_LEFT, SPOT1_RIGHT }; enum { FOCUS_IGNORE=1, FOCUS_STEAL, }; +enum { LEFT=1, RIGHT, UP, DOWN }; typedef struct { short x, y, w, h; @@ -136,6 +137,8 @@ typedef struct { void action_move(void*, int, client*); void action_focus(void*, int, client*); +void action_move_direction(void*, int, client*); +void action_focus_direction(void*, int, client*); void action_close(void*, int, client*); void action_cycle(void*, int, client*); void action_other(void*, int, client*); @@ -580,6 +583,35 @@ Window spot_focus_top_window(int spot, int mon, Window except) return None; } +int spot_choose_by_direction(int spot, int mon, int dir) +{ + monitor *m = &monitors[mon]; + int rotate = m->w < m->h ? 1:0; + if (rotate) + { + if (dir == LEFT) return SPOT3; + if (dir == RIGHT) return SPOT2; + if (SPOT1_ALIGN == SPOT1_LEFT) + { + if (dir == UP) return SPOT1; + if (dir == DOWN) return SPOT2; + } + if (dir == UP) return SPOT2; + if (dir == DOWN) return SPOT1; + return spot; + } + if (dir == UP) return SPOT2; + if (dir == DOWN) return SPOT3; + if (SPOT1_ALIGN == SPOT1_LEFT) + { + if (dir == LEFT) return SPOT1; + if (dir == RIGHT) return SPOT2; + } + if (dir == LEFT) return SPOT2; + if (dir == RIGHT) return SPOT1; + return spot; +} + void client_spot_cycle(client *c) { if (!c) return; @@ -604,11 +636,23 @@ void action_move(void *data, int num, client *cli) client_place_spot(cli, num, cli->monitor, 1); } +void action_move_direction(void *data, int num, client *cli) +{ + if (!cli) return; + client_raise_family(cli); + client_place_spot(cli, spot_choose_by_direction(cli->spot, cli->monitor, num), cli->monitor, 1); +} + void action_focus(void *data, int num, client *cli) { spot_focus_top_window(num, current_mon, None); } +void action_focus_direction(void *data, int num, client *cli) +{ + spot_focus_top_window(spot_choose_by_direction(current_spot, current_mon, num), current_mon, None); +} + void action_close(void *data, int num, client *cli) { if (cli) client_close(cli); @@ -646,6 +690,7 @@ void action_move_monitor(void *data, int num, client *cli) client_raise_family(cli); cli->monitor = MAX(0, MIN(current_mon+num, nmonitors-1)); client_place_spot(cli, cli->spot, cli->monitor, 1); + current_mon = cli->monitor; } void action_focus_monitor(void *data, int num, client *cli) @@ -956,23 +1001,47 @@ int main(int argc, char *argv[]) for (i = 0; i < nmonitors; i++) { monitor *m = &monitors[i]; - int width_spot1 = (double)m->w / 100 * MIN(90, MAX(10, SPOT1_WIDTH_PCT)); - int height_spot2 = (double)m->h / 100 * MIN(90, MAX(10, SPOT2_HEIGHT_PCT)); + int x = m->x, y = m->y, w = m->w, h = m->h; + // monitor rotated? + if (m->w < m->h) + { + int height_spot1 = (double)h / 100 * MIN(90, MAX(10, SPOT1_WIDTH_PCT)); + int width_spot2 = (double)w / 100 * MIN(90, MAX(10, SPOT2_HEIGHT_PCT)); + for_spots(j) + { + m->spots[j].x = x; + m->spots[j].y = SPOT1_ALIGN == SPOT1_LEFT ? y: y + h - height_spot1; + m->spots[j].w = w; + m->spots[j].h = height_spot1; + if (j == SPOT1) continue; + + m->spots[j].y = SPOT1_ALIGN == SPOT1_LEFT ? y + height_spot1: y; + m->spots[j].h = h - height_spot1; + m->spots[j].w = w - width_spot2; + if (j == SPOT3) continue; + + m->spots[j].x = x + w - width_spot2; + m->spots[j].w = width_spot2; + } + continue; + } + int width_spot1 = (double)w / 100 * MIN(90, MAX(10, SPOT1_WIDTH_PCT)); + int height_spot2 = (double)h / 100 * MIN(90, MAX(10, SPOT2_HEIGHT_PCT)); for_spots(j) { - m->spots[j].x = SPOT1_ALIGN == SPOT1_LEFT ? m->x: m->x + m->w - width_spot1; - m->spots[j].y = m->y; + m->spots[j].x = SPOT1_ALIGN == SPOT1_LEFT ? x: x + w - width_spot1; + m->spots[j].y = y; m->spots[j].w = width_spot1; - m->spots[j].h = m->h; + m->spots[j].h = h; if (j == SPOT1) continue; - m->spots[j].x = SPOT1_ALIGN == SPOT1_LEFT ? m->x + width_spot1: m->x; - m->spots[j].w = m->w - width_spot1; + m->spots[j].x = SPOT1_ALIGN == SPOT1_LEFT ? x + width_spot1: x; + m->spots[j].w = w - width_spot1; m->spots[j].h = height_spot2; if (j == SPOT2) continue; - m->spots[j].y = m->y + height_spot2; - m->spots[j].h = m->h - height_spot2; + m->spots[j].y = y + height_spot2; + m->spots[j].h = h - height_spot2; } }