X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=src%2Fmain.c;h=8bbd23baf6a86ff5fa35853e684012f14104f00c;hb=bccd702e857067e4942f7eb23682744e484e3a14;hp=b4ec3720ec34c1e5f7b52d452e8065f806ac649a;hpb=14a4e0c6f8500b981ed36b3e772c65c3ca35749d;p=i3%2Fi3 diff --git a/src/main.c b/src/main.c index b4ec3720..8bbd23ba 100644 --- a/src/main.c +++ b/src/main.c @@ -59,7 +59,7 @@ xcb_window_t root; * pixmaps. Will use 32 bit depth and an appropriate visual, if available, * otherwise the root window’s default (usually 24 bit TrueColor). */ uint8_t root_depth; -xcb_visualid_t visual_id; +xcb_visualtype_t *visual_type; xcb_colormap_t colormap; struct ev_loop *main_loop; @@ -87,6 +87,7 @@ struct ws_assignments_head ws_assignments = TAILQ_HEAD_INITIALIZER(ws_assignment /* We hope that those are supported and set them to true */ bool xcursor_supported = true; +bool xkb_supported = true; /* * This callback is only a dummy, see xcb_prepare_cb and xcb_check_cb. @@ -480,15 +481,29 @@ int main(int argc, char *argv[]) { #include "atoms.xmacro" #undef xmacro - /* By default, we use the same depth and visual as the root window, which - * usually is TrueColor (24 bit depth) and the corresponding visual. - * However, we also check if a 32 bit depth and visual are available (for - * transparency) and use it if so. */ root_depth = root_screen->root_depth; - visual_id = root_screen->root_visual; colormap = root_screen->default_colormap; + visual_type = xcb_aux_find_visual_by_attrs(root_screen, -1, 32); + if (visual_type != NULL) { + root_depth = xcb_aux_get_depth_of_visual(root_screen, visual_type->visual_id); + colormap = xcb_generate_id(conn); + + xcb_void_cookie_t cm_cookie = xcb_create_colormap_checked(conn, + XCB_COLORMAP_ALLOC_NONE, + colormap, + root, + visual_type->visual_id); + + xcb_generic_error_t *error = xcb_request_check(conn, cm_cookie); + if (error != NULL) { + ELOG("Could not create colormap. Error code: %d\n", error->error_code); + exit(EXIT_FAILURE); + } + } else { + visual_type = get_visualtype(root_screen); + } - DLOG("root_depth = %d, visual_id = 0x%08x.\n", root_depth, visual_id); + DLOG("root_depth = %d, visual_id = 0x%08x.\n", root_depth, visual_type->visual_id); DLOG("root_screen->height_in_pixels = %d, root_screen->height_in_millimeters = %d, dpi = %d\n", root_screen->height_in_pixels, root_screen->height_in_millimeters, (int)((double)root_screen->height_in_pixels * 25.4 / (double)root_screen->height_in_millimeters)); @@ -543,6 +558,7 @@ int main(int argc, char *argv[]) { const xcb_query_extension_reply_t *extreply; extreply = xcb_get_extension_data(conn, &xcb_xkb_id); + xkb_supported = extreply->present; if (!extreply->present) { DLOG("xkb is not present on this server\n"); } else { @@ -607,7 +623,7 @@ int main(int argc, char *argv[]) { grab_all_keys(conn); bool needs_tree_init = true; - if (layout_path) { + if (layout_path != NULL) { LOG("Trying to restore the layout from \"%s\".\n", layout_path); needs_tree_init = !tree_restore(layout_path, greply); if (delete_layout_path) { @@ -617,7 +633,6 @@ int main(int argc, char *argv[]) { * sockets) left. */ rmdir(dir); } - free(layout_path); } if (needs_tree_init) tree_init(greply); @@ -642,6 +657,33 @@ int main(int argc, char *argv[]) { randr_init(&randr_base); } + /* We need to force disabling outputs which have been loaded from the + * layout file but are no longer active. This can happen if the output has + * been disabled in the short time between writing the restart layout file + * and restarting i3. See #2326. */ + if (layout_path != NULL && randr_base > -1) { + Con *con; + TAILQ_FOREACH(con, &(croot->nodes_head), nodes) { + Output *output; + TAILQ_FOREACH(output, &outputs, outputs) { + if (output->active || strcmp(con->name, output->name) != 0) + continue; + + /* This will correctly correlate the output with its content + * container. We need to make the connection to properly + * disable the output. */ + if (output->con == NULL) { + output_init_con(output); + output->changed = false; + } + + output->to_be_disabled = true; + randr_disable_output(output); + } + } + } + FREE(layout_path); + scratchpad_fix_resolution(); xcb_query_pointer_reply_t *pointerreply; @@ -655,11 +697,10 @@ int main(int argc, char *argv[]) { ELOG("ERROR: No screen at (%d, %d), starting on the first screen\n", pointerreply->root_x, pointerreply->root_y); output = get_first_output(); - if (!output) - die("No usable outputs available.\n"); } con_focus(con_descend_focused(output_get_content(output->con))); + free(pointerreply); } tree_render(); @@ -787,6 +828,11 @@ int main(int argc, char *argv[]) { xcb_free_pixmap(conn, pixmap); } +#if defined(__OpenBSD__) + if (pledge("stdio rpath wpath cpath proc exec unix", NULL) == -1) + err(EXIT_FAILURE, "pledge"); +#endif + struct sigaction action; action.sa_sigaction = handle_signal; @@ -819,18 +865,28 @@ int main(int argc, char *argv[]) { /* Autostarting exec-lines */ if (autostart) { - struct Autostart *exec; - TAILQ_FOREACH(exec, &autostarts, autostarts) { + while (!TAILQ_EMPTY(&autostarts)) { + struct Autostart *exec = TAILQ_FIRST(&autostarts); + LOG("auto-starting %s\n", exec->command); start_application(exec->command, exec->no_startup_id); + + FREE(exec->command); + TAILQ_REMOVE(&autostarts, exec, autostarts); + FREE(exec); } } /* Autostarting exec_always-lines */ - struct Autostart *exec_always; - TAILQ_FOREACH(exec_always, &autostarts_always, autostarts_always) { + while (!TAILQ_EMPTY(&autostarts_always)) { + struct Autostart *exec_always = TAILQ_FIRST(&autostarts_always); + LOG("auto-starting (always!) %s\n", exec_always->command); start_application(exec_always->command, exec_always->no_startup_id); + + FREE(exec_always->command); + TAILQ_REMOVE(&autostarts_always, exec_always, autostarts_always); + FREE(exec_always); } /* Start i3bar processes for all configured bars */