}
void
-update_iconic(struct ws_win *win, int newv)
+set_swm_iconic(struct ws_win *win, int newv)
{
int32_t v = newv;
if (new_ws->focus_pending) {
/* if workspaces were swapped, then don't wait to set focus */
if (old_ws->r)
- focus_win(new_ws->focus);
+ focus_win(new_ws->focus_pending);
} else {
/* make sure bar gets updated if ws is empty */
bar_update();
struct ws_win *win = NULL, *parent;
struct workspace *ws, *nws;
char ws_idx_str[SWM_PROPLEN];
- union arg a;
if (wsid >= workspace_limit)
return;
win = r->ws->focus;
else
return;
- if (win == NULL)
- return;
+
if (win->ws->idx == wsid)
return;
- DNPRINTF(SWM_D_MOVE, "send_to_ws: window: 0x%x\n", win->id);
+ DNPRINTF(SWM_D_MOVE, "send_to_ws: win 0x%x, ws %d -> %d\n", win->id,
+ win->ws->idx, wsid);
ws = win->ws;
nws = &win->s->ws[wsid];
- a.id = SWM_ARG_ID_FOCUSPREV;
- focus(r, &a);
- if (win->transient) {
- parent = find_window(win->transient);
- if (parent) {
- unmap_window(parent);
- TAILQ_REMOVE(&ws->winlist, parent, entry);
- TAILQ_INSERT_TAIL(&nws->winlist, parent, entry);
- parent->ws = nws;
+ /* Update the window's workspace property: _SWM_WS */
+ if (snprintf(ws_idx_str, SWM_PROPLEN, "%d", nws->idx) < SWM_PROPLEN) {
+ ws->focus_pending = get_focus_prev(win);
+
+ /* Move the parent if this is a transient window. */
+ if (win->transient) {
+ parent = find_window(win->transient);
+ if (parent) {
+ /* Set new focus in parent's ws if needed. */
+ if (parent->ws->focus == parent) {
+ parent->ws->focus_pending =
+ get_focus_prev(parent);
+ unfocus_win(parent);
+ parent->ws->focus =
+ parent->ws->focus_pending;
+ parent->ws->focus_pending = NULL;
+ }
+
+ /* Don't unmap parent if new ws is visible */
+ if (nws->r == NULL)
+ unmap_window(parent);
+
+ /* Transfer */
+ TAILQ_REMOVE(&ws->winlist, parent, entry);
+ TAILQ_INSERT_TAIL(&nws->winlist, parent, entry);
+ parent->ws = nws;
+
+ DNPRINTF(SWM_D_PROP, "send_to_ws: set "
+ "property: _SWM_WS: %s\n", ws_idx_str);
+ xcb_change_property(conn, XCB_PROP_MODE_REPLACE,
+ parent->id, a_swm_ws, XCB_ATOM_STRING, 8,
+ strlen(ws_idx_str), ws_idx_str);
+ }
}
- }
- unmap_window(win);
- TAILQ_REMOVE(&ws->winlist, win, entry);
- TAILQ_INSERT_TAIL(&nws->winlist, win, entry);
- if (TAILQ_EMPTY(&ws->winlist))
- r->ws->focus = NULL;
- win->ws = nws;
- /* Try to update the window's workspace property */
- if (snprintf(ws_idx_str, SWM_PROPLEN, "%d", nws->idx) < SWM_PROPLEN) {
+ unfocus_win(win);
+
+ /* Don't unmap if new ws is visible */
+ if (nws->r == NULL)
+ unmap_window(win);
+
+ /* Transfer */
+ TAILQ_REMOVE(&ws->winlist, win, entry);
+ TAILQ_INSERT_TAIL(&nws->winlist, win, entry);
+ win->ws = nws;
+
+ /* Set focus on new ws. */
+ unfocus_win(nws->focus);
+ nws->focus = win;
+
DNPRINTF(SWM_D_PROP, "send_to_ws: set property: _SWM_WS: %s\n",
ws_idx_str);
xcb_change_property(conn, XCB_PROP_MODE_REPLACE, win->id,
a_swm_ws, XCB_ATOM_STRING, 8, strlen(ws_idx_str),
ws_idx_str);
- }
- stack();
- bar_update();
+ /* Restack and set new focus. */
+ stack();
+ focus_win(ws->focus_pending);
+ ws->focus_pending = NULL;
- focus_flush();
+ focus_flush();
+ }
+
+ DNPRINTF(SWM_D_MOVE, "send_to_ws: done.\n");
}
void
if (r->ws->focus == NULL)
return;
- update_iconic(r->ws->focus, 1);
+ set_swm_iconic(r->ws->focus, 1);
xcb_flush(conn);
}
free(name);
if (strncmp(s, resp, len) == 0) {
/* XXX this should be a callback to generalize */
- update_iconic(win, 0);
+ set_swm_iconic(win, 0);
xcb_flush(conn);
free(s);
break;
last_event_time = e->time;
if (e->atom == a_swm_iconic) {
- if (e->state == XCB_PROPERTY_DELETE) {
- /* The window is no longer iconic, restack ws. */
- win->ws->focus_pending = get_focus_magic(win);
- stack();
-
- /* Flush EnterNotify for mapnotify, if needed. */
- focus_flush();
- return;
- } else if (e->state == XCB_PROPERTY_NEW_VALUE) {
+ if (e->state == XCB_PROPERTY_NEW_VALUE) {
win->ws->focus_pending = get_focus_prev(win);
unfocus_win(win);
unmap_window(win);
win->ws->focus_pending = NULL;
focus_flush();
}
+ } else if (e->state == XCB_PROPERTY_DELETE) {
+ /* The window is no longer iconic, restack ws. */
+ win->ws->focus_pending = get_focus_magic(win);
+ stack();
+
+ /* Flush EnterNotify for mapnotify, if needed. */
+ focus_flush();
}
- } else if (e->atom == a_state && e->state == XCB_PROPERTY_NEW_VALUE) {
+ } else if (e->atom == a_state) {
/* State just changed, make sure it gets focused if mapped. */
- if (win->mapped && win->ws->focus_pending == win) {
- win->ws->focus_pending = NULL;
- focus_win(win);
+ if (e->state == XCB_PROPERTY_NEW_VALUE) {
+ if (win->mapped && win->ws->focus_pending == win) {
+ win->ws->focus_pending = NULL;
+ focus_win(win);
+ }
}
- }
-
- switch (e->atom) {
- case XCB_ATOM_WM_CLASS:
- case XCB_ATOM_WM_NAME:
+ } else if (e->atom == XCB_ATOM_WM_CLASS ||
+ e->atom == XCB_ATOM_WM_NAME) {
bar_update();
- break;
- default:
- break;
}
xcb_flush(conn);