]> git.sur5r.net Git - i3/i3/blobdiff - src/workspace.c
Implement default border styles (thanks litemotiv).
[i3/i3] / src / workspace.c
index cdea982750e9154acbadd275b95475ba0c1e5910..9ce28e523ae05ec3c675dbf05dc397098c267c0a 100644 (file)
@@ -38,14 +38,28 @@ Con *workspace_get(const char *num) {
         LOG("need to create this one\n");
         output = con_get_output(focused);
         LOG("got output %p\n", output);
-        workspace = con_new(output);
+        /* We need to attach this container after setting its type. con_attach
+         * will handle CT_WORKSPACEs differently */
+        workspace = con_new(NULL);
         char *name;
         asprintf(&name, "[i3 con] workspace %s", num);
         x_set_name(workspace, name);
         free(name);
         workspace->type = CT_WORKSPACE;
         workspace->name = strdup(num);
+        /* We set ->num to the number if this workspace’s name consists only of
+         * a positive number. Otherwise it’s a named ws and num will be -1. */
+        char *end;
+        long parsed_num = strtol(num, &end, 10);
+        if (parsed_num == LONG_MIN ||
+            parsed_num == LONG_MAX ||
+            parsed_num < 0 ||
+            (end && *end != '\0'))
+            workspace->num = -1;
+        else workspace->num = parsed_num;
+        LOG("num = %d\n", workspace->num);
         workspace->orientation = HORIZ;
+        con_attach(workspace, output, false);
 
         ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"init\"}");
     }
@@ -205,17 +219,20 @@ void workspace_show(const char *num) {
         next = TAILQ_FIRST(&(next->focus_head));
 
 
-    if (TAILQ_EMPTY(&(old->nodes_head))) {
+    if (TAILQ_EMPTY(&(old->nodes_head)) && TAILQ_EMPTY(&(old->floating_head))) {
         /* check if this workspace is currently visible */
         if (!workspace_is_visible(old)) {
             LOG("Closing old workspace (%p / %s), it is empty\n", old, old->name);
             tree_close(old, false, false);
+            ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"empty\"}");
         }
     }
 
     con_focus(next);
     workspace->fullscreen_mode = CF_OUTPUT;
     LOG("focused now = %p / %s\n", focused, focused->name);
+
+    ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"focus\"}");
 #if 0
 
         /* Check if the workspace has not been used yet */
@@ -433,93 +450,6 @@ Workspace *get_first_workspace_for_output(Output *output) {
         return result;
 }
 
-/*
- * Maps all clients (and stack windows) of the given workspace.
- *
- */
-void workspace_map_clients(xcb_connection_t *conn, Workspace *ws) {
-        Client *client;
-
-        ignore_enter_notify_forall(conn, ws, true);
-
-        /* Map all clients on the new workspace */
-        FOR_TABLE(ws)
-                CIRCLEQ_FOREACH(client, &(ws->table[cols][rows]->clients), clients)
-                        client_map(conn, client);
-
-        /* Map all floating clients */
-        if (!ws->floating_hidden)
-                TAILQ_FOREACH(client, &(ws->floating_clients), floating_clients)
-                        client_map(conn, client);
-
-        /* Map all stack windows, if any */
-        struct Stack_Window *stack_win;
-        SLIST_FOREACH(stack_win, &stack_wins, stack_windows)
-                if (stack_win->container->workspace == ws && stack_win->rect.height > 0)
-                        xcb_map_window(conn, stack_win->window);
-
-        ignore_enter_notify_forall(conn, ws, false);
-}
-
-/*
- * Unmaps all clients (and stack windows) of the given workspace.
- *
- * This needs to be called separately when temporarily rendering
- * a workspace which is not the active workspace to force
- * reconfiguration of all clients, like in src/xinerama.c when
- * re-assigning a workspace to another screen.
- *
- */
-void workspace_unmap_clients(xcb_connection_t *conn, Workspace *u_ws) {
-        Client *client;
-        struct Stack_Window *stack_win;
-
-        /* Ignore notify events because they would cause focus to be changed */
-        ignore_enter_notify_forall(conn, u_ws, true);
-
-        /* Unmap all clients of the given workspace */
-        int unmapped_clients = 0;
-        FOR_TABLE(u_ws)
-                CIRCLEQ_FOREACH(client, &(u_ws->table[cols][rows]->clients), clients) {
-                        DLOG("unmapping normal client %p / %p / %p\n", client, client->frame, client->child);
-                        client_unmap(conn, client);
-                        unmapped_clients++;
-                }
-
-        /* To find floating clients, we traverse the focus stack */
-        SLIST_FOREACH(client, &(u_ws->focus_stack), focus_clients) {
-                if (!client_is_floating(client))
-                        continue;
-
-                DLOG("unmapping floating client %p / %p / %p\n", client, client->frame, client->child);
-
-                client_unmap(conn, client);
-                unmapped_clients++;
-        }
-
-        /* If we did not unmap any clients, the workspace is empty and we can destroy it, at least
-         * if it is not the current workspace. */
-        if (unmapped_clients == 0 && u_ws != c_ws) {
-                /* Re-assign the workspace of all dock clients which use this workspace */
-                Client *dock;
-                DLOG("workspace %p is empty\n", u_ws);
-                SLIST_FOREACH(dock, &(u_ws->output->dock_clients), dock_clients) {
-                        if (dock->workspace != u_ws)
-                                continue;
-
-                        DLOG("Re-assigning dock client to c_ws (%p)\n", c_ws);
-                        dock->workspace = c_ws;
-                }
-                u_ws->output = NULL;
-        }
-
-        /* Unmap the stack windows on the given workspace, if any */
-        SLIST_FOREACH(stack_win, &stack_wins, stack_windows)
-                if (stack_win->container->workspace == u_ws)
-                        xcb_unmap_window(conn, stack_win->window);
-
-        ignore_enter_notify_forall(conn, u_ws, false);
-}
 #endif
 
 static bool get_urgency_flag(Con *con) {
@@ -548,35 +478,3 @@ void workspace_update_urgent_flag(Con *ws) {
     if (old_flag != ws->urgent)
         ipc_send_event("workspace", I3_IPC_EVENT_WORKSPACE, "{\"change\":\"urgent\"}");
 }
-
-#if 0
-
-/*
- * Returns the width of the workspace.
- *
- */
-int workspace_width(Workspace *ws) {
-        return ws->rect.width;
-}
-
-/*
- * Returns the effective height of the workspace (without the internal bar and
- * without dock clients).
- *
- */
-int workspace_height(Workspace *ws) {
-        int height = ws->rect.height;
-        i3Font *font = load_font(global_conn, config.font);
-
-        /* Reserve space for dock clients */
-        Client *client;
-        SLIST_FOREACH(client, &(ws->output->dock_clients), dock_clients)
-                height -= client->desired_height;
-
-        /* Space for the internal bar */
-        if (!config.disable_workspace_bar)
-                height -= (font->height + 6);
-
-        return height;
-}
-#endif