Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mod left/right to rotate space focus mask #119

Merged
merged 1 commit into from
Aug 15, 2015
Merged
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
58 changes: 58 additions & 0 deletions plugins/core-functionality/core-functionality.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include <unistd.h>
#include <stdlib.h>
#include <limits.h>
#include <orbment/plugin.h>
#include <chck/math/math.h>
#include <chck/string/string.h>
Expand Down Expand Up @@ -33,6 +34,36 @@ get_next_view(wlc_handle view, size_t offset, enum direction dir)
return (memb > 0 ? views[(dir == PREV ? chck_clampsz(i - offset, 0, memb - 1) : i + offset) % memb] : 0);
}

static uint32_t
rotate_mask(uint32_t wlc_mask, size_t offset, enum direction dir)
{
// can't shift with this offset
assert(sizeof(wlc_mask) * CHAR_BIT >= offset);

// Not sure where to get this magic number, it's the amount of spaces we use.
const uint32_t amountofspaces = 10;

// Circular shift from https://en.wikipedia.org/wiki/Circular_shift
// Modified to shift only a subsection of the bits

// Bitmask for the spaces in range, toggled bits define the spaces to shift, untoggled bits are left alone
const uint32_t spacesmask = (uint32_t)((uint64_t)1 << amountofspaces ) - 1;
// Take the spaces in range and bitrotate them while ignoring spaces outside of the range
const uint32_t spacesv = wlc_mask & spacesmask;

uint32_t newmask;
if (PREV == dir)
newmask = (spacesv >> offset) | (spacesv << (amountofspaces - offset));
else
newmask = (spacesv << offset) | (spacesv >> (amountofspaces - offset));

// drop the duplicated bits that got shifted beyond our range
// preserve the tags that aren't spaces
newmask = (newmask & spacesmask) | (~spacesmask & wlc_mask);

return newmask;
}

static wlc_handle
get_next_output(wlc_handle output, size_t offset, enum direction dir)
{
Expand Down Expand Up @@ -179,6 +210,15 @@ move_to_space(wlc_handle view, uint32_t index)
focus_space(index);
}

static void
focus_next_or_previous_space(enum direction direction)
{
const wlc_handle output = wlc_get_focused_output();
wlc_output_set_mask(output, rotate_mask(wlc_output_get_mask(output), 1, direction));
focus_topmost(output);
relayout(output);
}

static wlc_handle
output_for_index(uint32_t index)
{
Expand Down Expand Up @@ -340,6 +380,22 @@ key_cb_focus_space(wlc_handle view, uint32_t time, intptr_t arg)
focus_space((uint32_t)arg);
}

static void
key_cb_focus_previous_space(wlc_handle view, uint32_t time, intptr_t arg)
{
(void)view, (void)time, (void)arg;

focus_next_or_previous_space(PREV);
}

static void
key_cb_focus_next_space(wlc_handle view, uint32_t time, intptr_t arg)
{
(void)view, (void)time, (void)arg;

focus_next_or_previous_space(NEXT);
}

static void
key_cb_move_to_output(wlc_handle view, uint32_t time, intptr_t arg)
{
Expand Down Expand Up @@ -425,6 +481,8 @@ static const struct {
{ "focus space 7", (const char*[]){ "<P-8>", "<P-KP_8>", NULL }, key_cb_focus_space, 7 },
{ "focus space 8", (const char*[]){ "<P-9>", "<P-KP_9>", NULL }, key_cb_focus_space, 8 },
{ "focus space 9", (const char*[]){ "<P-0>", "<P-KP_0>", NULL }, key_cb_focus_space, 9 },
{ "focus left space", (const char*[]){ "<P-Left>", NULL }, key_cb_focus_previous_space, 0 },
{ "focus right space", (const char*[]){ "<P-Right>", NULL }, key_cb_focus_next_space, 0 },
{ "move to space 0", (const char*[]){ "<P-F1>", NULL }, key_cb_move_to_space, 0 },
{ "move to space 1", (const char*[]){ "<P-F2>", NULL }, key_cb_move_to_space, 1 },
{ "move to space 2", (const char*[]){ "<P-F3>", NULL }, key_cb_move_to_space, 2 },
Expand Down