Tiling2: Restrict allowed resizes of windows.

This commit is contained in:
Tom Hacohen 2014-01-16 17:18:29 +00:00
parent ae8acb24b2
commit b5434d1de5
3 changed files with 159 additions and 0 deletions

View File

@ -732,6 +732,108 @@ static void _move_or_resize(E_Client *ec)
_reapply_tree();
}
static void
_resize_begin_hook(void *data EINA_UNUSED, E_Client *ec)
{
Client_Extra *extra;
if (!ec) {
return;
}
if (!is_tilable(ec)) {
return;
}
if (!desk_should_tile_check(ec->desk))
return;
extra = eina_hash_find(_G.client_extras, &ec);
if (!extra) {
ERR("No extra for %p", ec);
return;
}
if (is_ignored_window(extra))
return;
Window_Tree *item = tiling_window_tree_client_find(_G.tinfo->tree, ec);
if (!item)
{
ERR("Couldn't find tree item for resized client %p!", ec);
return;
}
int edges = tiling_window_tree_edges_get(item);
if (edges & TILING_WINDOW_TREE_EDGE_LEFT)
{
switch (ec->resize_mode)
{
case E_POINTER_RESIZE_L:
ec->resize_mode = E_POINTER_RESIZE_NONE;
break;
case E_POINTER_RESIZE_TL:
ec->resize_mode = E_POINTER_RESIZE_T;
break;
case E_POINTER_RESIZE_BL:
ec->resize_mode = E_POINTER_RESIZE_B;
break;
default:
break;
}
}
if (edges & TILING_WINDOW_TREE_EDGE_RIGHT)
{
switch (ec->resize_mode)
{
case E_POINTER_RESIZE_R:
ec->resize_mode = E_POINTER_RESIZE_NONE;
break;
case E_POINTER_RESIZE_TR:
ec->resize_mode = E_POINTER_RESIZE_T;
break;
case E_POINTER_RESIZE_BR:
ec->resize_mode = E_POINTER_RESIZE_B;
break;
default:
break;
}
}
if (edges & TILING_WINDOW_TREE_EDGE_TOP)
{
switch (ec->resize_mode)
{
case E_POINTER_RESIZE_T:
ec->resize_mode = E_POINTER_RESIZE_NONE;
break;
case E_POINTER_RESIZE_TL:
ec->resize_mode = E_POINTER_RESIZE_L;
break;
case E_POINTER_RESIZE_TR:
ec->resize_mode = E_POINTER_RESIZE_R;
break;
default:
break;
}
}
if (edges & TILING_WINDOW_TREE_EDGE_BOTTOM)
{
switch (ec->resize_mode)
{
case E_POINTER_RESIZE_B:
ec->resize_mode = E_POINTER_RESIZE_NONE;
break;
case E_POINTER_RESIZE_BL:
ec->resize_mode = E_POINTER_RESIZE_L;
break;
case E_POINTER_RESIZE_BR:
ec->resize_mode = E_POINTER_RESIZE_R;
break;
default:
break;
}
}
}
static Eina_Bool
_resize_hook(void *data __UNUSED__, int type __UNUSED__, E_Event_Client *event)
{
@ -1014,6 +1116,7 @@ e_modapi_init(E_Module *m)
(Ecore_Event_Handler_Cb) _f, \
NULL);
e_client_hook_add(E_CLIENT_HOOK_RESIZE_BEGIN, _resize_begin_hook, NULL);
HANDLER(_G.handler_client_resize, CLIENT_RESIZE, _resize_hook);
HANDLER(_G.handler_client_move, CLIENT_MOVE, _move_hook);
HANDLER(_G.handler_client_add, CLIENT_ADD, _add_hook);

View File

@ -396,6 +396,55 @@ tiling_window_tree_node_resize(Window_Tree *node, int w_dir, double w_diff, int
return ret;
}
int
_tiling_window_tree_edges_get_helper(Window_Tree *node, Tiling_Split_Type split_type, Eina_Bool gave_up_this,
Eina_Bool gave_up_parent)
{
int ret = TILING_WINDOW_TREE_EDGE_LEFT | TILING_WINDOW_TREE_EDGE_RIGHT |
TILING_WINDOW_TREE_EDGE_TOP | TILING_WINDOW_TREE_EDGE_BOTTOM;
if (!node->parent)
{
return ret;
}
else if (gave_up_this && gave_up_parent)
{
return 0;
}
else if (gave_up_this)
{
/* Mixed the gave_up vals on purpose, we do it on every call. */
return _tiling_window_tree_edges_get_helper(node->parent, !split_type ,gave_up_parent,
gave_up_this);
}
if (EINA_INLIST_GET(node)->prev)
{
gave_up_this = EINA_TRUE;
ret ^= (split_type == TILING_SPLIT_HORIZONTAL) ?
TILING_WINDOW_TREE_EDGE_LEFT : TILING_WINDOW_TREE_EDGE_TOP;
}
if (EINA_INLIST_GET(node)->next)
{
gave_up_this = EINA_TRUE;
ret ^= (split_type == TILING_SPLIT_HORIZONTAL) ?
TILING_WINDOW_TREE_EDGE_RIGHT : TILING_WINDOW_TREE_EDGE_BOTTOM;
}
/* Mixed the gave_up vals on purpose, we do it on every call. */
return ret & _tiling_window_tree_edges_get_helper(node->parent, !split_type ,gave_up_parent,
gave_up_this);
}
int
tiling_window_tree_edges_get(Window_Tree *node)
{
Tiling_Split_Type split_type = _tiling_window_tree_split_type_get(node);
return _tiling_window_tree_edges_get_helper(node, !split_type, EINA_FALSE,
EINA_FALSE);
}
void
tiling_window_tree_dump(Window_Tree *root, int level)
{

View File

@ -21,6 +21,13 @@ struct _Window_Tree
double weight;
};
#define TILING_WINDOW_TREE_EDGE_LEFT (1 << 0)
#define TILING_WINDOW_TREE_EDGE_RIGHT (1 << 1)
#define TILING_WINDOW_TREE_EDGE_TOP (1 << 2)
#define TILING_WINDOW_TREE_EDGE_BOTTOM (1 << 3)
int tiling_window_tree_edges_get(Window_Tree *node);
void tiling_window_tree_free(Window_Tree *root);
void tiling_window_tree_walk(Window_Tree *root, void (*func)(void *));