/** Toggle the selected client to max * \param cmd uicb_t type unused */ void uicb_togglemax(uicb_t cmd) { (void)cmd; if(!sel || ishide(sel, selscreen) || (sel->flags & HintFlag)|| (sel->flags & FSSFlag)) return; if(!(sel->flags & MaxFlag)) { sel->ogeo = sel->geo; sel->free_geo = sel->geo; sel->flags &= ~(TileFlag | FreeFlag); client_maximize(sel); XRaiseWindow(dpy, sel->frame); sel->flags |= MaxFlag; } else { sel->geo = sel->ogeo; client_moveresize(sel, sel->geo, True); sel->flags &= ~MaxFlag; tags[selscreen][seltag[selscreen]].layout.func(selscreen); } return; }
void moveresize_end(gboolean cancel) { ungrab_keyboard(); ungrab_pointer(); popup_hide(popup); if (!moving) { #ifdef SYNC /* turn off the alarm */ if (moveresize_alarm != None) { XSyncDestroyAlarm(obt_display, moveresize_alarm); moveresize_alarm = None; } if (sync_timer) g_source_remove(sync_timer); sync_timer = 0; #endif } /* don't use client_move() here, use the same width/height as we've been using during the move, otherwise we get different results when moving maximized windows between monitors of different sizes ! */ client_configure(moveresize_client, (cancel ? start_cx : cur_x), (cancel ? start_cy : cur_y), (cancel ? start_cw : cur_w), (cancel ? start_ch : cur_h), TRUE, TRUE, FALSE); /* restore the client's maximized state. do this after putting the window back in its original spot to minimize visible flicker */ if (cancel && (was_max_horz || was_max_vert)) { const gboolean h = moveresize_client->max_horz; const gboolean v = moveresize_client->max_vert; client_maximize(moveresize_client, TRUE, was_max_horz && was_max_vert ? 0 : (was_max_horz ? 1 : 2)); /* replace the premax values with the ones we had saved if the client doesn't have any already set */ if (was_max_horz && !h) { moveresize_client->pre_max_area.x = pre_max_area.x; moveresize_client->pre_max_area.width = pre_max_area.width; } if (was_max_vert && !v) { moveresize_client->pre_max_area.y = pre_max_area.y; moveresize_client->pre_max_area.height = pre_max_area.height; } } /* dont edge warp after its ended */ cancel_edge_warp(); moveresize_in_progress = FALSE; moveresize_client = NULL; }
/* Always return FALSE because its not interactive */ static gboolean run_func_off(ObActionsData *data, gpointer options) { Options *o = options; if (data->client) { actions_client_move(data, TRUE); client_maximize(data->client, FALSE, o->dir); actions_client_move(data, FALSE); } return FALSE; }
/* Always return FALSE because its not interactive */ static gboolean run_func_toggle(ObActionsData *data, gpointer options) { Options *o = options; if (data->client) { gboolean toggle; actions_client_move(data, TRUE); toggle = ((o->dir == HORZ && !data->client->max_horz) || (o->dir == VERT && !data->client->max_vert) || (o->dir == BOTH && !(data->client->max_horz && data->client->max_vert))); client_maximize(data->client, toggle, o->dir); actions_client_move(data, FALSE); } return FALSE; }
/** Max layout function */ void maxlayout(int screen) { Client *c; int i; for(i = 0, c = tiled_client(screen, clients); c; c = tiled_client(screen, c->next), ++i) { c->flags &= ~TileFlag; c->flags |= LMaxFlag; client_maximize(c); } ewmh_update_current_tag_prop(); return; }
gboolean moveresize_event(XEvent *e) { gboolean used = FALSE; if (!moveresize_in_progress) return FALSE; if (e->type == ButtonPress) { if (!button) { start_x = e->xbutton.x_root; start_y = e->xbutton.y_root; button = e->xbutton.button; /* this will end it now */ } used = e->xbutton.button == button; } else if (e->type == ButtonRelease) { if (!button || e->xbutton.button == button) { moveresize_end(FALSE); used = TRUE; } } else if (e->type == MotionNotify) { if (moving) { cur_x = start_cx + e->xmotion.x_root - start_x; cur_y = start_cy + e->xmotion.y_root - start_y; do_move(FALSE, 0); do_edge_warp(e->xmotion.x_root, e->xmotion.y_root); } else { gint dw, dh; ObDirection dir; if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOPLEFT)) { dw = -(e->xmotion.x_root - start_x); dh = -(e->xmotion.y_root - start_y); dir = OB_DIRECTION_NORTHWEST; } else if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOP)) { dw = 0; dh = -(e->xmotion.y_root - start_y); dir = OB_DIRECTION_NORTH; } else if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOPRIGHT)) { dw = (e->xmotion.x_root - start_x); dh = -(e->xmotion.y_root - start_y); dir = OB_DIRECTION_NORTHEAST; } else if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_RIGHT)) { dw = (e->xmotion.x_root - start_x); dh = 0; dir = OB_DIRECTION_EAST; } else if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_BOTTOMRIGHT)) { dw = (e->xmotion.x_root - start_x); dh = (e->xmotion.y_root - start_y); dir = OB_DIRECTION_SOUTHEAST; } else if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_BOTTOM)) { dw = 0; dh = (e->xmotion.y_root - start_y); dir = OB_DIRECTION_SOUTH; } else if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT)) { dw = -(e->xmotion.x_root - start_x); dh = (e->xmotion.y_root - start_y); dir = OB_DIRECTION_SOUTHWEST; } else if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_LEFT)) { dw = -(e->xmotion.x_root - start_x); dh = 0; dir = OB_DIRECTION_WEST; } else if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_KEYBOARD)) { dw = (e->xmotion.x_root - start_x); dh = (e->xmotion.y_root - start_y); dir = OB_DIRECTION_SOUTHEAST; } else g_assert_not_reached(); /* override the client's max state if desired */ if (ABS(dw) >= config_resist_edge) { if (moveresize_client->max_horz) { /* 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 (was_max_horz && !moveresize_client->max_horz) { /* remax horz and put the premax back */ client_maximize(moveresize_client, TRUE, 1); moveresize_client->pre_max_area.x = pre_max_area.x; moveresize_client->pre_max_area.width = pre_max_area.width; } if (ABS(dh) >= config_resist_edge) { if (moveresize_client->max_vert) { /* 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); } } else if (was_max_vert && !moveresize_client->max_vert) { /* remax vert and put the premax back */ client_maximize(moveresize_client, TRUE, 2); moveresize_client->pre_max_area.y = pre_max_area.y; moveresize_client->pre_max_area.height = pre_max_area.height; } dw -= cur_w - start_cw; dh -= cur_h - start_ch; calc_resize(FALSE, 0, &dw, &dh, dir); cur_w += dw; cur_h += dh; if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOPLEFT) || corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_LEFT) || corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_BOTTOMLEFT)) { cur_x -= dw; } if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOPLEFT) || corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOP) || corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_TOPRIGHT)) { cur_y -= dh; } do_resize(); } used = TRUE; } else if (e->type == KeyPress) { KeySym sym = obt_keyboard_keypress_to_keysym(e); if (sym == XK_Escape) { moveresize_end(TRUE); used = TRUE; } else if (sym == XK_Return || sym == XK_KP_Enter) { moveresize_end(FALSE); used = TRUE; } else if (sym == XK_Right || sym == XK_Left || sym == XK_Up || sym == XK_Down) { if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_SIZE_KEYBOARD)) { resize_with_keys(sym, e->xkey.state); used = TRUE; } else if (corner == OBT_PROP_ATOM(NET_WM_MOVERESIZE_MOVE_KEYBOARD)) { move_with_keys(sym, e->xkey.state); used = TRUE; } } } #ifdef SYNC else if (e->type == obt_display_extension_sync_basep + XSyncAlarmNotify) { waiting_for_sync = 0; /* we got our sync... */ do_resize(); /* ...so try resize if there is more change pending */ used = TRUE; } #endif if (used && moveresize_client == focus_client) event_update_user_time(); return used; }
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; }