Пример #1
0
gboolean menu_frame_show_topmenu(ObMenuFrame *self, const GravityPoint *pos,
                                 gint monitor, gboolean mouse,
                                 gboolean user_positioned)
{
    gint px, py;
    gint x, y;

    if (menu_frame_is_visible(self))
        return TRUE;
    if (!menu_frame_show(self))
        return FALSE;

    if (self->menu->place_func) {
        x = pos->x.pos;
        y = pos->y.pos;
        self->menu->place_func(self, &x, &y, mouse, self->menu->data);
    } else {
        menu_frame_place_topmenu(self, pos, &x, &y, monitor,
                                 user_positioned);
    }

    menu_frame_move(self, x, y);

    XMapWindow(obt_display, self->window);

    if (screen_pointer_pos(&px, &py)) {
        ObMenuEntryFrame *e = menu_entry_frame_under(px, py);
        if (e && e->frame == self)
            e->ignore_enters++;
    }

    return TRUE;
}
Пример #2
0
static gboolean place_under_mouse(ObClient *client, gint *x, gint *y,
                                  Size frame_size)
{
    if (config_place_policy != OB_PLACE_POLICY_MOUSE)
        return FALSE;

    gint l, r, t, b;
    gint px, py;
    Rect *area;

    ob_debug("placing under mouse");

    if (!screen_pointer_pos(&px, &py))
        return FALSE;
    area = choose_pointer_monitor(client);

    l = area->x;
    t = area->y;
    r = area->x + area->width - frame_size.width;
    b = area->y + area->height - frame_size.height;

    *x = px - frame_size.width / 2;
    *x = MIN(MAX(*x, l), r);
    *y = py - frame_size.height / 2;
    *y = MIN(MAX(*y, t), b);

    g_slice_free(Rect, area);

    return TRUE;
}
Пример #3
0
static void edge_warp_move_ptr(void)
{
    gint x, y;
    const Rect* a;

    screen_pointer_pos(&x, &y);
    a = screen_physical_area_all_monitors();

    switch (edge_warp_dir) {
	case OB_DIRECTION_NORTH:
	    y = a->height - 1;
	    break;
	case OB_DIRECTION_EAST:
	    x = a->x;
	    break;
	case OB_DIRECTION_SOUTH:
	    y = a->y;
	    break;
	case OB_DIRECTION_WEST:
	    x = a->width - 1;
	    break;
	default:
        g_assert_not_reached();
    }

    XWarpPointer(obt_display, 0, obt_root(ob_screen), 0, 0, 0, 0, x, y);
}
Пример #4
0
void actions_run_acts(GSList *acts,
                      ObUserAction uact,
                      guint state,
                      gint x,
                      gint y,
                      gint button,
                      ObFrameContext con,
                      struct _ObClient *client)
{
    GSList *it;

    /* Don't allow saving the initial state when running things from the
       menu */
	syslog(LOG_INFO,"gslist len -> %d",g_slist_length(acts));
    if (uact == OB_USER_ACTION_MENU_SELECTION)
        state = 0;
    /* If x and y are < 0 then use the current pointer position */
    if (x < 0 && y < 0)
        screen_pointer_pos(&x, &y);

    for (it = acts; it; it = g_slist_next(it)) {
        ObActionsData data;
        ObActionsAct *act = it->data;
        gboolean ok = TRUE;
		syslog(LOG_INFO,"action ->%s",act->def->name);
        actions_setup_data(&data, uact, state, x, y, button, con, client);

        /* if they have the same run function, then we'll assume they are
           cooperating and not cancel eachother out */
        if (!interactive_act || interactive_act->def->run != act->def->run) {
            if (actions_act_is_interactive(act)) {
                /* cancel the old one */
                if (interactive_act)
                    actions_interactive_cancel_act();
                ok = actions_interactive_begin_act(act, state);
            }
        }

        /* fire the action's run function with this data */
        if (ok) {
            if (!act->def->run(&data, act->options)) {
                if (actions_act_is_interactive(act))
                    actions_interactive_end_act();
            } else {
                /* make sure its interactive if it returned TRUE */
                g_assert(act->def->i_cancel && act->def->i_input);

                /* no actions are run after the interactive one */
                break;
            }
        }
    }
}
Пример #5
0
gboolean menu_frame_show_submenu(ObMenuFrame *self, ObMenuFrame *parent,
                                 ObMenuEntryFrame *parent_entry)
{
    gint x, y, dx, dy;
    gint px, py;

    if (menu_frame_is_visible(self))
        return TRUE;

    self->monitor = parent->monitor;
    self->parent = parent;
    self->parent_entry = parent_entry;

    /* set up parent's child to be us */
    if ((parent->child) != self) {
        if (parent->child)
            menu_frame_hide(parent->child);
        parent->child = self;
        parent->child_entry = parent_entry;
    }

    if (!menu_frame_show(self)) {
        parent->child = NULL;
        parent->child_entry = NULL;
        return FALSE;
    }

    menu_frame_place_submenu(self, &x, &y);
    menu_frame_move_on_screen(self, x, y, &dx, &dy);

    if (dx != 0) {
        /*try the other side */
        self->direction_right = !self->direction_right;
        menu_frame_place_submenu(self, &x, &y);
        menu_frame_move_on_screen(self, x, y, &dx, &dy);
    }
    menu_frame_move(self, x + dx, y + dy);

    XMapWindow(obt_display, self->window);

    if (screen_pointer_pos(&px, &py)) {
        ObMenuEntryFrame *e = menu_entry_frame_under(px, py);
        if (e && e->frame == self)
            e->ignore_enters++;
    }

    return TRUE;
}
Пример #6
0
static void resize_with_keys(KeySym sym, guint state)
{
    gint dw = 0, dh = 0, pdx = 0, pdy = 0, opx, opy, px, py;
    gint resist = 0;
    ObDirection dir;

    /* pick the edge if it needs to move */
    if (sym == XK_Right) {
        dir = OB_DIRECTION_EAST;
        if (key_resize_edge != OB_DIRECTION_WEST &&
            key_resize_edge != OB_DIRECTION_EAST)
        {
            key_resize_edge = OB_DIRECTION_EAST;
            return;
        }
    } else if (sym == XK_Left) {
        dir = OB_DIRECTION_WEST;
        if (key_resize_edge != OB_DIRECTION_WEST &&
            key_resize_edge != OB_DIRECTION_EAST)
        {
            key_resize_edge = OB_DIRECTION_WEST;
            return;
        }
    } else if (sym == XK_Up) {
        dir = OB_DIRECTION_NORTH;
        if (key_resize_edge != OB_DIRECTION_NORTH &&
            key_resize_edge != OB_DIRECTION_SOUTH)
        {
            key_resize_edge = OB_DIRECTION_NORTH;
            return;
        }
    } else /* if (sym == XK_Down) */ {
        dir = OB_DIRECTION_SOUTH;
        if (key_resize_edge != OB_DIRECTION_NORTH &&
            key_resize_edge != OB_DIRECTION_SOUTH)
        {
            key_resize_edge = OB_DIRECTION_SOUTH;
            return;
        }
    }

    /* shift means jump to edge */
    if (state & obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_SHIFT))
    {
        gint x, y, w, h;

        if (sym == XK_Right)
            dir = OB_DIRECTION_EAST;
        else if (sym == XK_Left)
            dir = OB_DIRECTION_WEST;
        else if (sym == XK_Down)
            dir = OB_DIRECTION_SOUTH;
        else /* if (sym == XK_Up)) */
            dir = OB_DIRECTION_NORTH;

        client_find_resize_directional(moveresize_client, key_resize_edge,
                                       key_resize_edge == dir,
                                       &x, &y, &w, &h);
        dw = w - moveresize_client->area.width;
        dh = h - moveresize_client->area.height;
    } else {
        gint distw, disth;

        /* control means fine grained */
        if (moveresize_client->size_inc.width > 1) {
            distw = moveresize_client->size_inc.width;
            resist = 1;
        }
        else if (state &
                 obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_CONTROL))
        {
            distw = 1;
            resist = 1;
        }
        else {
            distw = KEY_DIST;
            resist = KEY_DIST;
        }
        if (moveresize_client->size_inc.height > 1) {
            disth = moveresize_client->size_inc.height;
            resist = 1;
        }
        else if (state &
                 obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_CONTROL))
        {
            disth = 1;
            resist = 1;
        }
        else {
            disth = KEY_DIST;
            resist = KEY_DIST;
        }

        if (key_resize_edge == OB_DIRECTION_WEST) {
            if (dir == OB_DIRECTION_WEST)
                dw = distw;
            else
                dw = -distw;
        }
        else if (key_resize_edge == OB_DIRECTION_EAST) {
            if (dir == OB_DIRECTION_EAST)
                dw = distw;
            else
                dw = -distw;
        }
        else if (key_resize_edge == OB_DIRECTION_NORTH) {
            if (dir == OB_DIRECTION_NORTH)
                dh = disth;
            else
                dh = -disth;
        }
        else /*if (key_resize_edge == OB_DIRECTION_SOUTH)*/ {
            if (dir == OB_DIRECTION_SOUTH)
                dh = disth;
            else
                dh = -disth;
        }
    }

    if (moveresize_client->max_horz &&
        (key_resize_edge == OB_DIRECTION_WEST ||
         key_resize_edge == OB_DIRECTION_EAST))
    {
        /* unmax horz */
        was_max_horz = TRUE;
        pre_max_area.x = moveresize_client->pre_max_area.x;
        pre_max_area.width = moveresize_client->pre_max_area.width;

        moveresize_client->pre_max_area.x = cur_x;
        moveresize_client->pre_max_area.width = cur_w;
        client_maximize(moveresize_client, FALSE, 1);
    }
    else if (moveresize_client->max_vert &&
             (key_resize_edge == OB_DIRECTION_NORTH ||
              key_resize_edge == OB_DIRECTION_SOUTH))
    {
        /* unmax vert */
        was_max_vert = TRUE;
        pre_max_area.y = moveresize_client->pre_max_area.y;
        pre_max_area.height = moveresize_client->pre_max_area.height;

        moveresize_client->pre_max_area.y = cur_y;
        moveresize_client->pre_max_area.height = cur_h;
        client_maximize(moveresize_client, FALSE, 2);
    }

    calc_resize(TRUE, resist, &dw, &dh, dir);
    if (key_resize_edge == OB_DIRECTION_WEST)
        cur_x -= dw;
    else if (key_resize_edge == OB_DIRECTION_NORTH)
        cur_y -= dh;
    cur_w += dw;
    cur_h += dh;

    /* how to move the pointer to keep up with the change */
    if (key_resize_edge == OB_DIRECTION_WEST)
        pdx = -dw;
    else if (key_resize_edge == OB_DIRECTION_EAST)
        pdx = dw;
    else if (key_resize_edge == OB_DIRECTION_NORTH)
        pdy = -dh;
    else if (key_resize_edge == OB_DIRECTION_SOUTH)
        pdy = dh;

    screen_pointer_pos(&opx, &opy);
    XWarpPointer(obt_display, None, None, 0, 0, 0, 0, pdx, pdy);
    /* steal the motion events this causes */
    XSync(obt_display, FALSE);
    {
        XEvent ce;
        while (xqueue_remove_local(&ce, xqueue_match_type,
                                   GINT_TO_POINTER(MotionNotify)));
    }
    screen_pointer_pos(&px, &py);

    do_resize();

    /* because the cursor moves even though the window does
       not nessesarily (resistance), this adjusts where the cursor
       thinks it started so that it keeps up with where the window
       actually is */
    start_x += (px - opx) - dw;
    start_y += (py - opy) - dh;

}
Пример #7
0
static void move_with_keys(KeySym sym, guint state)
{
    gint dx = 0, dy = 0, ox = cur_x, oy = cur_y;
    gint opx, px, opy, py;
    gint dist = 0;

    /* shift means jump to edge */
    if (state & obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_SHIFT))
    {
        gint x, y;
        ObDirection dir;

        if (sym == XK_Right)
            dir = OB_DIRECTION_EAST;
        else if (sym == XK_Left)
            dir = OB_DIRECTION_WEST;
        else if (sym == XK_Down)
            dir = OB_DIRECTION_SOUTH;
        else /* sym == XK_Up */
            dir = OB_DIRECTION_NORTH;

        client_find_move_directional(moveresize_client, dir, &x, &y);
        dx = x - moveresize_client->area.x;
        dy = y - moveresize_client->area.y;
    } else {
        /* control means fine grained */
        if (state &
            obt_keyboard_modkey_to_modmask(OBT_KEYBOARD_MODKEY_CONTROL))
        {
            dist = 1;
        }
        else
            dist = KEY_DIST;

        if (sym == XK_Right)
            dx = dist;
        else if (sym == XK_Left)
            dx = -dist;
        else if (sym == XK_Down)
            dy = dist;
        else /* if (sym == XK_Up) */
            dy = -dist;
    }

    screen_pointer_pos(&opx, &opy);
    XWarpPointer(obt_display, None, None, 0, 0, 0, 0, dx, dy);
    /* steal the motion events this causes */
    XSync(obt_display, FALSE);
    {
        XEvent ce;
        while (xqueue_remove_local(&ce, xqueue_match_type,
                                   GINT_TO_POINTER(MotionNotify)));
    }
    screen_pointer_pos(&px, &py);

    cur_x += dx;
    cur_y += dy;
    do_move(TRUE, dist);

    /* because the cursor moves even though the window does
       not nessesarily (resistance), this adjusts where the curor
       thinks it started so that it keeps up with where the window
       actually is */
    start_x += (px - opx) - (cur_x - ox);
    start_y += (py - opy) - (cur_y - oy);
}
Пример #8
0
void actions_run_acts(GSList *acts,
                      ObUserAction uact,
                      guint state,
                      gint x,
                      gint y,
                      gint button,
                      ObFrameContext con,
                      struct _ObClient *client)
{
    GSList *it;
    gboolean update_user_time;

    /* Don't allow saving the initial state when running things from the
       menu */
    if (uact == OB_USER_ACTION_MENU_SELECTION)
        state = 0;
    /* If x and y are < 0 then use the current pointer position */
    if (x < 0 && y < 0)
        screen_pointer_pos(&x, &y);

    update_user_time = FALSE;
    for (it = acts; it; it = g_slist_next(it)) {
        ObActionsData data;
        ObActionsAct *act = it->data;
        gboolean ok = TRUE;

        actions_setup_data(&data, uact, state, x, y, button, con, client);

        /* if they have the same run function, then we'll assume they are
           cooperating and not cancel eachother out */
        if (!interactive_act || interactive_act->def->run != act->def->run) {
            if (actions_act_is_interactive(act)) {
                /* cancel the old one */
                if (interactive_act)
                    actions_interactive_cancel_act();
                if (act->i_pre)
                    if (!act->i_pre(state, act->options))
                        act->i_input = NULL; /* remove the interactivity */
            }
            /* check again cuz it might have been cancelled */
            if (actions_act_is_interactive(act))
                ok = actions_interactive_begin_act(act, state);
        }

        /* fire the action's run function with this data */
        if (ok) {
            if (!act->def->run(&data, act->options)) {
                if (actions_act_is_interactive(act))
                    actions_interactive_end_act();
                if (client && client == focus_client &&
                        act->def->modifies_focused_window)
                {
                    update_user_time = TRUE;
                }
            } else {
                /* make sure its interactive if it returned TRUE */
                g_assert(act->i_input);

                /* no actions are run after the interactive one */
                break;
            }
        }
    }
    if (update_user_time)
        event_update_user_time();
}