Esempio n. 1
0
void focus_node(monitor_t *m, desktop_t *d, node_t *n, bool is_mapped)
{
    if (n == NULL)
        return;

    PRINTF("focus node %X\n", n->client->window);

    split_mode = MODE_AUTOMATIC;
    n->client->urgent = false;

    if (is_mapped) {
        if (mon != m) {
            for (desktop_t *cd = mon->desk_head; cd != NULL; cd = cd->next)
                window_draw_border(cd->focus, true, false);
            for (desktop_t *cd = m->desk_head; cd != NULL; cd = cd->next)
                if (cd != d)
                    window_draw_border(cd->focus, true, true);
            if (d->focus == n)
                window_draw_border(n, true, true);
        }
        if (d->focus != n) {
            window_draw_border(d->focus, false, true);
            window_draw_border(n, true, true);
        }
        xcb_set_input_focus(dpy, XCB_INPUT_FOCUS_POINTER_ROOT, n->client->window, XCB_CURRENT_TIME);
    }

    if (focus_follows_pointer) {
        xcb_window_t win = XCB_NONE;
        get_pointed_window(&win);
        if (win != n->client->window)
            enable_motion_recorder();
        else
            disable_motion_recorder();
    }

    if (!is_tiled(n->client)) {
        if (!adaptative_raise || !might_cover(d, n))
            window_raise(n->client->window);
    } else {
        window_pseudo_raise(d, n->client->window);
    }

    if (d->focus != n) {
        d->last_focus = d->focus;
        d->focus = n;
    }

    ewmh_update_active_window();
    put_status();
}
Esempio n. 2
0
void gui_update_playlist(void) {
    window_draw_border(playlist_window);
    window_draw_title(playlist_window);
    window_draw_scrollbar(playlist_window);
    window_draw_list(playlist_window);
    window_update(playlist_window);
}
Esempio n. 3
0
void draw_border(node_t *n, bool focused_node, bool focused_monitor)
{
	if (n == NULL) {
		return;
	}

	uint32_t border_color_pxl = get_border_color(focused_node, focused_monitor);
	for (node_t *f = first_extrema(n); f != NULL; f = next_leaf(f, n)) {
		if (f->client->border_width > 0) {
			window_draw_border(f->id, border_color_pxl);
		}
	}
}
Esempio n. 4
0
void gui_update_filelist(void) {
	if(!filelist_window){
		return;
	}
	window_draw_border(filelist_window);
	window_draw_title(filelist_window);
	window_draw_scrollbar(filelist_window);
	window_draw_list(filelist_window);
	window_update(filelist_window);

	//Update the info window as we are updated as well
	gui_update_info();
	gui_update();
}
Esempio n. 5
0
/*
 * Rearrange left and right child of a given pair, based on method and sized
 * already set in the (as usually) right window.
 */
void window_rearrange(winid_t pair)
{
   SDL_Rect left_area, right_area;
   window_calc_sizes(pair, &left_area, &right_area);

   // Let the window resize first, which size has been reduced, so that it can
   // copy from the old area before the now larger window will overwrite it.
   int or = pair->right->method & winmethod_DirMask;
   if(((or == winmethod_Above || or == winmethod_Below) &&
       left_area.h < pair->left->area.h) ||
      ((or == winmethod_Left || or == winmethod_Right) &&
       left_area.w < pair->left->area.w)) {
      window_resize(pair->left, &left_area);
      window_resize(pair->right, &right_area);
   } else {
      window_resize(pair->right, &right_area);
      window_resize(pair->left, &left_area);
   }

   window_draw_border(pair);
}
Esempio n. 6
0
void track_pointer(int root_x, int root_y)
{
    if (frozen_pointer->action == ACTION_NONE)
        return;

    int16_t delta_x, delta_y, x = 0, y = 0, w = 1, h = 1;
    uint16_t width, height;

    pointer_action_t pac = frozen_pointer->action;
    monitor_t *m = frozen_pointer->monitor;
    desktop_t *d = frozen_pointer->desktop;
    node_t *n = frozen_pointer->node;
    client_t *c = frozen_pointer->client;
    xcb_window_t win = frozen_pointer->window;
    xcb_rectangle_t rect = frozen_pointer->rectangle;
    node_t *vertical_fence = frozen_pointer->vertical_fence;
    node_t *horizontal_fence = frozen_pointer->horizontal_fence;

    delta_x = root_x - frozen_pointer->position.x;
    delta_y = root_y - frozen_pointer->position.y;

    switch (pac) {
        case ACTION_MOVE:
            if (frozen_pointer->is_tiled) {
                xcb_window_t pwin = XCB_NONE;
                query_pointer(&pwin, NULL);
                if (pwin == win)
                    return;
                coordinates_t loc;
                bool is_managed = (pwin == XCB_NONE ? false : locate_window(pwin, &loc));
                if (is_managed && is_tiled(loc.node->client) && loc.monitor == m) {
                    swap_nodes(m, d, n, m, d, loc.node);
                    arrange(m, d);
                } else {
                    if (is_managed && loc.monitor == m) {
                        return;
                    } else if (!is_managed) {
                        xcb_point_t pt = (xcb_point_t) {root_x, root_y};
                        monitor_t *pmon = monitor_from_point(pt);
                        if (pmon == NULL || pmon == m) {
                            return;
                        } else {
                            loc.monitor = pmon;
                            loc.desktop = pmon->desk;
                        }
                    }
                    bool focused = (n == mon->desk->focus);
                    transfer_node(m, d, n, loc.monitor, loc.desktop, loc.desktop->focus);
                    if (focused)
                        focus_node(loc.monitor, loc.desktop, n);
                    frozen_pointer->monitor = loc.monitor;
                    frozen_pointer->desktop = loc.desktop;
                }
            } else {
                x = rect.x + delta_x;
                y = rect.y + delta_y;
                window_move(win, x, y);
                c->floating_rectangle.x = x;
                c->floating_rectangle.y = y;
                xcb_point_t pt = (xcb_point_t) {root_x, root_y};
                monitor_t *pmon = monitor_from_point(pt);
                if (pmon == NULL || pmon == m)
                    return;
                bool focused = (n == mon->desk->focus);
                transfer_node(m, d, n, pmon, pmon->desk, pmon->desk->focus);
                if (focused)
                    focus_node(pmon, pmon->desk, n);
                frozen_pointer->monitor = pmon;
                frozen_pointer->desktop = pmon->desk;
            }
            break;
        case ACTION_RESIZE_SIDE:
        case ACTION_RESIZE_CORNER:
            if (frozen_pointer->is_tiled) {
                if (vertical_fence != NULL) {
                    double sr = frozen_pointer->vertical_ratio + (double) delta_x / vertical_fence->rectangle.width;
                    sr = MAX(0, sr);
                    sr = MIN(1, sr);
                    vertical_fence->split_ratio = sr;
                }
                if (horizontal_fence != NULL) {
                    double sr = frozen_pointer->horizontal_ratio + (double) delta_y / horizontal_fence->rectangle.height;
                    sr = MAX(0, sr);
                    sr = MIN(1, sr);
                    horizontal_fence->split_ratio = sr;
                }
                arrange(mon, mon->desk);
            } else {
                if (pac == ACTION_RESIZE_SIDE) {
                    switch (frozen_pointer->side) {
                        case SIDE_TOP:
                            x = rect.x;
                            y = rect.y + delta_y;
                            w = rect.width;
                            h = rect.height - delta_y;
                            break;
                        case SIDE_RIGHT:
                            x = rect.x;
                            y = rect.y;
                            w = rect.width + delta_x;
                            h = rect.height;
                            break;
                        case SIDE_BOTTOM:
                            x = rect.x;
                            y = rect.y;
                            w = rect.width;
                            h = rect.height + delta_y;
                            break;
                        case SIDE_LEFT:
                            x = rect.x + delta_x;
                            y = rect.y;
                            w = rect.width - delta_x;
                            h = rect.height;
                            break;
                    }
                    width = MAX(1, w);
                    height = MAX(1, h);
                    window_move_resize(win, x, y, width, height);
                    c->floating_rectangle = (xcb_rectangle_t) {x, y, width, height};
                    window_draw_border(n, d->focus == n, mon == m);
                } else if (pac == ACTION_RESIZE_CORNER) {
                    switch (frozen_pointer->corner) {
                        case CORNER_TOP_LEFT:
                            x = rect.x + delta_x;
                            y = rect.y + delta_y;
                            w = rect.width - delta_x;
                            h = rect.height - delta_y;
                            break;
                        case CORNER_TOP_RIGHT:
                            x = rect.x;
                            y = rect.y + delta_y;
                            w = rect.width + delta_x;
                            h = rect.height - delta_y;
                            break;
                        case CORNER_BOTTOM_LEFT:
                            x = rect.x + delta_x;
                            y = rect.y;
                            w = rect.width - delta_x;
                            h = rect.height + delta_y;
                            break;
                        case CORNER_BOTTOM_RIGHT:
                            x = rect.x;
                            y = rect.y;
                            w = rect.width + delta_x;
                            h = rect.height + delta_y;
                            break;
                    }
                    width = MAX(1, w);
                    height = MAX(1, h);
                    window_move_resize(win, x, y, width, height);
                    c->floating_rectangle = (xcb_rectangle_t) {x, y, width, height};
                    window_draw_border(n, d->focus == n, mon == m);
                }
            }
            break;
        case ACTION_FOCUS:
        case ACTION_NONE:
            break;
    }
}
Esempio n. 7
0
void apply_layout(monitor_t *m, desktop_t *d, node_t *n, xcb_rectangle_t rect, xcb_rectangle_t root_rect)
{
    if (n == NULL)
        return;

    n->rectangle = rect;

    if (is_leaf(n)) {
        if (n->client->fullscreen)
            return;

        if (is_floating(n->client) && n->client->border_width != border_width) {
            int ds = 2 * (border_width - n->client->border_width);
            n->client->floating_rectangle.width += ds;
            n->client->floating_rectangle.height += ds;
        }

        if (borderless_monocle && is_tiled(n->client) && d->layout == LAYOUT_MONOCLE)
            n->client->border_width = 0;
        else
            n->client->border_width = border_width;

        xcb_rectangle_t r;
        if (is_tiled(n->client)) {
            if (d->layout == LAYOUT_TILED)
                r = rect;
            else if (d->layout == LAYOUT_MONOCLE)
                r = root_rect;
            int wg = (gapless_monocle && d->layout == LAYOUT_MONOCLE ? 0 : window_gap);
            int bleed = wg + 2 * n->client->border_width;
            r.width = (bleed < r.width ? r.width - bleed : 1);
            r.height = (bleed < r.height ? r.height - bleed : 1);
            n->client->tiled_rectangle = r;
        } else {
            r = n->client->floating_rectangle;
        }

        window_move_resize(n->client->window, r.x, r.y, r.width, r.height);
        window_border_width(n->client->window, n->client->border_width);
        window_draw_border(n, n == d->focus, m == mon);

    } else {
        xcb_rectangle_t first_rect;
        xcb_rectangle_t second_rect;

        if (n->first_child->vacant || n->second_child->vacant) {
            first_rect = second_rect = rect;
        } else {
            unsigned int fence;
            if (n->split_type == TYPE_VERTICAL) {
                fence = rect.width * n->split_ratio;
                first_rect = (xcb_rectangle_t) {rect.x, rect.y, fence, rect.height};
                second_rect = (xcb_rectangle_t) {rect.x + fence, rect.y, rect.width - fence, rect.height};

            } else if (n->split_type == TYPE_HORIZONTAL) {
                fence = rect.height * n->split_ratio;
                first_rect = (xcb_rectangle_t) {rect.x, rect.y, rect.width, fence};
                second_rect = (xcb_rectangle_t) {rect.x, rect.y + fence, rect.width, rect.height - fence};
            }
        }

        apply_layout(m, d, n->first_child, first_rect, root_rect);
        apply_layout(m, d, n->second_child, second_rect, root_rect);
    }
}
Esempio n. 8
0
winid_t glk_window_open(winid_t split, glui32 method, glui32 size,
                        glui32 wintype, glui32 rock)
{
   winid_t win = (winid_t)nano_malloc(sizeof(struct glk_window_struct));
   nanoglk_log("glk_window_open(%p, %d, %d, %d, %d) => %p",
              split, method, size, wintype, rock, win);

   win->stream = nanoglk_stream_new(streamtype_Window, 0);
   win->stream->x.window = win;

   win->method = method;
   win->size = size;
   win->wintype = wintype;
   win->rock = rock;
   win->left = win->right = NULL;
   win->cur_styl = style_Normal;
   
   // Colors for styles. See comment at the beginning of this file.
   int i;
   switch(win->wintype) {
   case wintype_TextBuffer:
      for(i = 0; i < style_NUMSTYLES; i++) {
         win->fg[i] = next_buffer_fg[i];
         win->bg[i] = next_buffer_bg[i];
      }
      break;

   case wintype_TextGrid:
      for(i = 0; i < style_NUMSTYLES; i++) {
         win->fg[i] = next_grid_fg[i];
         win->bg[i] = next_grid_bg[i];
      }
      break;
   }

   winid_t pair;
   
   if(split == NULL) {
      // parent is NULL => new root window
      nano_failunless(root == NULL, "two root windows");

      win->parent = NULL;
      win->area.x = win->area.y = 0;
      win->area.w = nanoglk_surface->w;
      win->area.h = nanoglk_surface->h;

      root = win;

      pair = NULL; // no pair window created

      nano_trace("[glk_window_open] root %p: (%d, %d, %d x %d)",
                 win, win->area.x, win->area.y, win->area.w, win->area.h);
   } else {
      // Create a pair window. The old parent "split" becomes the left
      // child, the newly created becomes the right child. (See also
      // comment on these members in "nanoglk.h".)
      pair = (winid_t)nano_malloc(sizeof(struct glk_window_struct));
      pair->stream = NULL;
      pair->wintype = wintype_Pair;
      pair->rock = 0;
      pair->left = split;
      pair->right = win;
      pair->area = split->area;
      pair->method = split->method;
      pair->size = split->size;
      pair->parent = split->parent;

      // Rearrange tree: "pair" takes over the place of "split".
      if(pair->parent == NULL)
         root = pair;
      else {
         if(pair->parent->left == split)
            pair->parent->left = pair;
         else if(pair->parent->right == split)
            pair->parent->right = pair;
         else
            nano_fail("split not child of parent?");
      }

      split->parent = win->parent = pair;
      pair->left = split;
      pair->right = win;

      win->area = split->area;
      SDL_Rect split_area, win_area;
      window_calc_sizes(pair, &split_area, &win_area);
      window_resize(split, &split_area);
      win->area = win_area;

      window_draw_border(pair);

      nano_trace("split %p: (%d, %d, %d x %d)", split, split->area.x,
                split->area.y, split->area.w, split->area.h);
      nano_trace("new win %p: (%d, %d, %d x %d)", win, win->area.x,
                 win->area.y, win->area.w, win->area.h);
   }

   // Further initialization depending on the type.
   switch(win->wintype) {
   case wintype_TextBuffer:
      nanoglk_wintextbuffer_init(win);
      break;

   case wintype_TextGrid:
      nanoglk_wintextgrid_init(win);
      break;

   case wintype_Graphics:
      nanoglk_wingraphics_init(win);
      break;
   }

   if(pair)
      pair->disprock = nanoglk_call_regi_obj(pair, gidisp_Class_Window);

   win->stream->disprock
      = nanoglk_call_regi_obj(win->stream, gidisp_Class_Stream);
   win->disprock = nanoglk_call_regi_obj(win, gidisp_Class_Window);
   
   return win;
}