X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fscreen.c;h=fd6244665cc99cc8827a90a3ff1745386dec543d;hb=7a166a383805f7693e0800f3bf693e3736463a0d;hp=21fff19b6d8a41be507158c01a4a16305c0bee33;hpb=d42335e54d9eb70957eb3f4938b69cc3682cfec2;p=chaz%2Fopenbox diff --git a/openbox/screen.c b/openbox/screen.c index 21fff19b..fd624466 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -1,11 +1,14 @@ #include "openbox.h" +#include "dock.h" #include "prop.h" +#include "startup.h" +#include "config.h" #include "screen.h" #include "client.h" #include "frame.h" -#include "engine.h" #include "focus.h" #include "dispatch.h" +#include "extensions.h" #include "../render/render.h" #include @@ -15,7 +18,7 @@ #endif /*! The event mask to grab on the root window */ -#define ROOT_EVENTMASK (/*ColormapChangeMask |*/ PropertyChangeMask | \ +#define ROOT_EVENTMASK (StructureNotifyMask | PropertyChangeMask | \ EnterWindowMask | LeaveWindowMask | \ SubstructureNotifyMask | SubstructureRedirectMask | \ ButtonPressMask | ButtonReleaseMask | ButtonMotionMask) @@ -25,7 +28,7 @@ guint screen_desktop = 0; Size screen_physical_size; gboolean screen_showing_desktop; DesktopLayout screen_desktop_layout; -GPtrArray *screen_desktop_names; +char **screen_desktop_names = NULL; static Rect *area = NULL; static Strut *strut = NULL; @@ -48,7 +51,7 @@ gboolean screen_annex() XErrorHandler old; pid_t pid; int i, num_support; - Atom *supported; + guint32 *supported; running = FALSE; old = XSetErrorHandler(another_running); @@ -61,7 +64,7 @@ gboolean screen_annex() g_message("Managing screen %d", ob_screen); /* set the mouse cursor for the root window (the default cursor) */ - XDefineCursor(ob_display, ob_root, ob_cursors.left_ptr); + XDefineCursor(ob_display, ob_root, ob_cursors.ptr); /* set the OPENBOX_PID hint */ pid = getpid(); @@ -74,13 +77,13 @@ gboolean screen_annex() PROP_SET32(ob_root, net_supporting_wm_check, window, support_window); /* set properties on the supporting window */ - PROP_SETS(support_window, net_wm_name, utf8, "Openbox"); + PROP_SETS(support_window, net_wm_name, "Openbox"); PROP_SET32(support_window, net_supporting_wm_check, window,support_window); /* set the _NET_SUPPORTED_ATOMS hint */ - num_support = 48; + num_support = 61; i = 0; - supported = g_new(Atom, num_support); + supported = g_new(guint32, num_support); supported[i++] = prop_atoms.net_current_desktop; supported[i++] = prop_atoms.net_number_of_desktops; supported[i++] = prop_atoms.net_desktop_geometry; @@ -129,18 +132,25 @@ gboolean screen_annex() supported[i++] = prop_atoms.net_wm_state_fullscreen; supported[i++] = prop_atoms.net_wm_state_above; supported[i++] = prop_atoms.net_wm_state_below; + supported[i++] = prop_atoms.net_moveresize_window; + supported[i++] = prop_atoms.net_wm_moveresize; + supported[i++] = prop_atoms.net_wm_moveresize_size_topleft; + supported[i++] = prop_atoms.net_wm_moveresize_size_top; + supported[i++] = prop_atoms.net_wm_moveresize_size_topright; + supported[i++] = prop_atoms.net_wm_moveresize_size_right; + supported[i++] = prop_atoms.net_wm_moveresize_size_bottomright; + supported[i++] = prop_atoms.net_wm_moveresize_size_bottom; + supported[i++] = prop_atoms.net_wm_moveresize_size_bottomleft; + supported[i++] = prop_atoms.net_wm_moveresize_size_left; + supported[i++] = prop_atoms.net_wm_moveresize_move; + supported[i++] = prop_atoms.net_wm_moveresize_size_keyboard; + supported[i++] = prop_atoms.net_wm_moveresize_move_keyboard; g_assert(i == num_support); /* - supported[] = prop_atoms.net_wm_moveresize; - supported[] = prop_atoms.net_wm_moveresize_size_topleft; - supported[] = prop_atoms.net_wm_moveresize_size_topright; - supported[] = prop_atoms.net_wm_moveresize_size_bottomleft; - supported[] = prop_atoms.net_wm_moveresize_size_bottomright; - supported[] = prop_atoms.net_wm_moveresize_move; supported[] = prop_atoms.net_wm_action_stick; */ - PROP_SET32A(ob_root, net_supported, atom, supported, num_support); + PROP_SETA32(ob_root, net_supported, atom, supported, num_support); g_free(supported); return TRUE; @@ -148,13 +158,29 @@ gboolean screen_annex() void screen_startup() { - screen_desktop_names = g_ptr_array_new(); - - /* get the initial size */ - screen_resize(); + GSList *it; + guint i; - screen_set_num_desktops(4); - screen_set_desktop(0); + /* get the initial size */ + screen_resize(WidthOfScreen(ScreenOfDisplay(ob_display, ob_screen)), + HeightOfScreen(ScreenOfDisplay(ob_display, ob_screen))); + + /* set the names */ + screen_desktop_names = g_new(char*, + g_slist_length(config_desktops_names) + 1); + for (i = 0, it = config_desktops_names; it; ++i, it = it->next) + screen_desktop_names[i] = it->data; /* dont strdup */ + screen_desktop_names[i] = NULL; + PROP_SETSS(ob_root, net_desktop_names, screen_desktop_names); + g_free(screen_desktop_names); /* dont free the individual strings */ + screen_desktop_names = NULL; + + screen_num_desktops = 0; + screen_set_num_desktops(config_desktops_num); + if (startup_desktop >= screen_num_desktops) + startup_desktop = 0; + screen_desktop = startup_desktop; + screen_set_desktop(startup_desktop); /* don't start in showing-desktop mode */ screen_showing_desktop = FALSE; @@ -165,8 +191,6 @@ void screen_startup() void screen_shutdown() { - guint i; - XSelectInput(ob_display, ob_root, NoEventMask); PROP_ERASE(ob_root, openbox_pid); /* we're not running here no more! */ @@ -175,71 +199,50 @@ void screen_shutdown() XDestroyWindow(ob_display, support_window); - for (i = 0; i < screen_desktop_names->len; ++i) - g_free(g_ptr_array_index(screen_desktop_names, i)); - g_ptr_array_free(screen_desktop_names, TRUE); + g_strfreev(screen_desktop_names); g_free(strut); g_free(area); } -void screen_resize() +void screen_resize(int w, int h) { - /* XXX RandR support here? */ - int geometry[2]; + GList *it; + guint32 geometry[2]; /* Set the _NET_DESKTOP_GEOMETRY hint */ - geometry[0] = WidthOfScreen(ScreenOfDisplay(ob_display, ob_screen)); - geometry[1] = HeightOfScreen(ScreenOfDisplay(ob_display, ob_screen)); - PROP_SET32A(ob_root, net_desktop_geometry, cardinal, geometry, 2); + geometry[0] = w; + geometry[1] = h; + PROP_SETA32(ob_root, net_desktop_geometry, cardinal, geometry, 2); screen_physical_size.width = geometry[0]; screen_physical_size.height = geometry[1]; if (ob_state == State_Starting) return; + dock_configure(); screen_update_struts(); - /* XXX adjust more stuff ? */ + for (it = client_list; it; it = it->next) + client_move_onscreen(it->data); } void screen_set_num_desktops(guint num) { guint i, old; - gulong *viewport; - + guint32 *viewport; + GList *it; + g_assert(num > 0); - - /* move windows on desktops that will no longer exist! */ - /* XXX - std::list::iterator it, end = clients.end(); - for (it = clients.begin(); it != end; ++it) { - unsigned int d = (*it)->desktop(); - if (d >= num && d != 0xffffffff) { - XEvent ce; - ce.xclient.type = ClientMessage; - ce.xclient.message_type = otk::Property::atoms.net_wm_desktop; - ce.xclient.display = **otk::display; - ce.xclient.window = (*it)->window(); - ce.xclient.format = 32; - ce.xclient.data.l[0] = num - 1; - XSendEvent(**otk::display, _info->rootWindow(), false, - SubstructureNotifyMask | SubstructureRedirectMask, &ce); - } - } - */ old = screen_num_desktops; screen_num_desktops = num; PROP_SET32(ob_root, net_number_of_desktops, cardinal, num); /* set the viewport hint */ - viewport = g_new0(gulong, num * 2); - PROP_SET32A(ob_root, net_desktop_viewport, cardinal, viewport, num * 2); + viewport = g_new0(guint32, num * 2); + PROP_SETA32(ob_root, net_desktop_viewport, cardinal, viewport, num * 2); g_free(viewport); - /* change our struts/area to match */ - screen_update_struts(); - /* the number of rows/columns will differ */ screen_update_layout(); @@ -256,6 +259,16 @@ void screen_set_num_desktops(guint num) for (i = old; i < num; ++i) focus_order[i] = NULL; + /* move windows on desktops that will no longer exist! */ + for (it = client_list; it != NULL; it = it->next) { + Client *c = it->data; + if (c->desktop >= num && c->desktop != DESKTOP_ALL) + client_set_desktop(c, num - 1, FALSE); + } + + /* change our struts/area to match (after moving windows) */ + screen_update_struts(); + dispatch_ob(Event_Ob_NumDesktops, num, old); /* change our desktop if we're on one that no longer exists! */ @@ -267,37 +280,50 @@ void screen_set_desktop(guint num) { GList *it; guint old; + XEvent e; g_assert(num < screen_num_desktops); - g_message("Moving to desktop %u", num); - old = screen_desktop; screen_desktop = num; PROP_SET32(ob_root, net_current_desktop, cardinal, num); if (old == num) return; - /* hide windows from bottom to top */ - for (it = g_list_last(stacking_list); it != NULL; it = it->prev) { - Client *c = it->data; - if (c->frame->visible && !client_should_show(c)) - engine_frame_hide(c->frame); - } + g_message("Moving to desktop %d", num+1); + + /* show windows before hiding the rest to lessen the enter/leave events */ /* show windows from top to bottom */ for (it = stacking_list; it != NULL; it = it->next) { - Client *c = it->data; - if (!c->frame->visible && client_should_show(c)) - engine_frame_show(c->frame); + if (WINDOW_IS_CLIENT(it->data)) { + Client *c = it->data; + if (!c->frame->visible && client_should_show(c)) + frame_show(c->frame); + } } + /* hide windows from bottom to top */ + for (it = g_list_last(stacking_list); it != NULL; it = it->prev) { + if (WINDOW_IS_CLIENT(it->data)) { + Client *c = it->data; + if (c->frame->visible && !client_should_show(c)) + frame_hide(c->frame); + } + } + + /* focus the last focused window on the desktop, and ignore enter events + from the switch so it doesnt mess with the focus */ + while (XCheckTypedEvent(ob_display, EnterNotify, &e)); + focus_fallback(Fallback_Desktop); + dispatch_ob(Event_Ob_Desktop, num, old); } void screen_update_layout() { - unsigned long *data = NULL; + guint32 *data = NULL; + guint num; /* defaults */ screen_desktop_layout.orientation = prop_atoms.net_wm_orientation_horz; @@ -305,54 +331,61 @@ void screen_update_layout() screen_desktop_layout.rows = 1; screen_desktop_layout.columns = screen_num_desktops; - if (PROP_GET32A(ob_root, net_desktop_layout, cardinal, data, 4)) { - if (data[0] == prop_atoms.net_wm_orientation_vert) - screen_desktop_layout.orientation = data[0]; - if (data[3] == prop_atoms.net_wm_topright) - screen_desktop_layout.start_corner = data[3]; - else if (data[3] == prop_atoms.net_wm_bottomright) - screen_desktop_layout.start_corner = data[3]; - else if (data[3] == prop_atoms.net_wm_bottomleft) - screen_desktop_layout.start_corner = data[3]; - - /* fill in a zero rows/columns */ - if (!(data[1] == 0 && data[2] == 0)) { /* both 0's is bad data.. */ - if (data[1] == 0) { - data[1] = (screen_num_desktops + - screen_num_desktops % data[2]) / data[2]; - } else if (data[2] == 0) { - data[2] = (screen_num_desktops + - screen_num_desktops % data[1]) / data[1]; - } - screen_desktop_layout.columns = data[1]; - screen_desktop_layout.rows = data[2]; - } - - /* bounds checking */ - if (screen_desktop_layout.orientation == - prop_atoms.net_wm_orientation_horz) { - if (screen_desktop_layout.rows > screen_num_desktops) - screen_desktop_layout.rows = screen_num_desktops; - if (screen_desktop_layout.columns > ((screen_num_desktops + - screen_num_desktops % - screen_desktop_layout.rows) / - screen_desktop_layout.rows)) - screen_desktop_layout.columns = - (screen_num_desktops + screen_num_desktops % - screen_desktop_layout.rows) / - screen_desktop_layout.rows; - } else { - if (screen_desktop_layout.columns > screen_num_desktops) - screen_desktop_layout.columns = screen_num_desktops; - if (screen_desktop_layout.rows > ((screen_num_desktops + - screen_num_desktops % - screen_desktop_layout.columns) / - screen_desktop_layout.columns)) - screen_desktop_layout.rows = - (screen_num_desktops + screen_num_desktops % - screen_desktop_layout.columns) / - screen_desktop_layout.columns; - } + if (PROP_GETA32(ob_root, net_desktop_layout, cardinal, &data, &num)) { + if (num == 3 || num == 4) { + if (data[0] == prop_atoms.net_wm_orientation_vert) + screen_desktop_layout.orientation = data[0]; + if (num == 3) + screen_desktop_layout.start_corner = + prop_atoms.net_wm_topright; + else { + if (data[3] == prop_atoms.net_wm_topright) + screen_desktop_layout.start_corner = data[3]; + else if (data[3] == prop_atoms.net_wm_bottomright) + screen_desktop_layout.start_corner = data[3]; + else if (data[3] == prop_atoms.net_wm_bottomleft) + screen_desktop_layout.start_corner = data[3]; + } + + /* fill in a zero rows/columns */ + if (!(data[1] == 0 && data[2] == 0)) { /* both 0's is bad data.. */ + if (data[1] == 0) { + data[1] = (screen_num_desktops + + screen_num_desktops % data[2]) / data[2]; + } else if (data[2] == 0) { + data[2] = (screen_num_desktops + + screen_num_desktops % data[1]) / data[1]; + } + screen_desktop_layout.columns = data[1]; + screen_desktop_layout.rows = data[2]; + } + + /* bounds checking */ + if (screen_desktop_layout.orientation == + prop_atoms.net_wm_orientation_horz) { + if (screen_desktop_layout.rows > screen_num_desktops) + screen_desktop_layout.rows = screen_num_desktops; + if (screen_desktop_layout.columns > + ((screen_num_desktops + screen_num_desktops % + screen_desktop_layout.rows) / + screen_desktop_layout.rows)) + screen_desktop_layout.columns = + (screen_num_desktops + screen_num_desktops % + screen_desktop_layout.rows) / + screen_desktop_layout.rows; + } else { + if (screen_desktop_layout.columns > screen_num_desktops) + screen_desktop_layout.columns = screen_num_desktops; + if (screen_desktop_layout.rows > + ((screen_num_desktops + screen_num_desktops % + screen_desktop_layout.columns) / + screen_desktop_layout.columns)) + screen_desktop_layout.rows = + (screen_num_desktops + screen_num_desktops % + screen_desktop_layout.columns) / + screen_desktop_layout.columns; + } + } g_free(data); } } @@ -362,55 +395,58 @@ void screen_update_desktop_names() guint i; /* empty the array */ - for (i = 0; i < screen_desktop_names->len; ++i) - g_free(g_ptr_array_index(screen_desktop_names, i)); - g_ptr_array_set_size(screen_desktop_names, 0); - - PROP_GETSA(ob_root, net_desktop_names, utf8, screen_desktop_names); - - while (screen_desktop_names->len < screen_num_desktops) - g_ptr_array_add(screen_desktop_names, g_strdup("Unnamed Desktop")); + g_strfreev(screen_desktop_names); + screen_desktop_names = NULL; + + if (PROP_GETSS(ob_root, net_desktop_names, utf8, &screen_desktop_names)) + for (i = 0; screen_desktop_names[i] && i <= screen_num_desktops; ++i); + else + i = 0; + if (i <= screen_num_desktops) { + screen_desktop_names = g_renew(char*, screen_desktop_names, + screen_num_desktops + 1); + screen_desktop_names[screen_num_desktops] = NULL; + for (; i < screen_num_desktops; ++i) + screen_desktop_names[i] = g_strdup("Unnamed Desktop"); + } } void screen_show_desktop(gboolean show) { GList *it; - static Window saved_focus = 0; if (show == screen_showing_desktop) return; /* no change */ - /* save the window focus, and restore it when leaving the show-desktop - mode */ - if (show && focus_client) - saved_focus = focus_client->window; - screen_showing_desktop = show; if (show) { /* bottom to top */ for (it = g_list_last(stacking_list); it != NULL; it = it->prev) { - Client *client = it->data; - if (client->type == Type_Desktop) - client_focus(client); - else if (client->frame->visible && !client_should_show(client)) - engine_frame_hide(client->frame); + if (WINDOW_IS_CLIENT(it->data)) { + Client *client = it->data; + if (client->frame->visible && !client_should_show(client)) + frame_hide(client->frame); + } } } else { /* top to bottom */ for (it = stacking_list; it != NULL; it = it->next) { - Client *client = it->data; - if (!client->frame->visible && client_should_show(client)) - engine_frame_show(client->frame); + if (WINDOW_IS_CLIENT(it->data)) { + Client *client = it->data; + if (!client->frame->visible && client_should_show(client)) + frame_show(client->frame); + } } } - if (!show) { - Client *f = focus_client; - if (!f || f->type == Type_Desktop) { - Client *c = g_hash_table_lookup(client_map, - (gpointer)saved_focus); - if (c) client_focus(c); - } + if (show) { + /* focus desktop */ + for (it = focus_order[screen_desktop]; it; it = it->next) + if (((Client*)it->data)->type == Type_Desktop && + client_focus(it->data)) + break; + } else { + focus_fallback(Fallback_NoFocus); } show = !!show; /* make it boolean */ @@ -421,14 +457,16 @@ void screen_show_desktop(gboolean show) void screen_install_colormap(Client *client, gboolean install) { + XWindowAttributes wa; + if (client == NULL) { if (install) XInstallColormap(ob_display, render_colormap); else XUninstallColormap(ob_display, render_colormap); } else { - XWindowAttributes wa; - if (XGetWindowAttributes(ob_display, client->window, &wa)) { + if (XGetWindowAttributes(ob_display, client->window, &wa) && + wa.colormap != None) { if (install) XInstallColormap(ob_display, wa.colormap); else @@ -439,14 +477,13 @@ void screen_install_colormap(Client *client, gboolean install) void screen_update_struts() { - GSList *it; + GList *it; guint i; - if (strut != NULL) - g_free(strut); + g_free(strut); strut = g_new0(Strut, screen_num_desktops + 1); - for (it = client_list; it; it = it->next) { + for (it = client_list; it != NULL; it = it->next) { Client *c = it->data; if (c->iconic) continue; /* these dont count in the strut */ @@ -460,19 +497,22 @@ void screen_update_struts() /* apply to the 'all desktops' strut */ STRUT_ADD(strut[screen_num_desktops], c->strut); } + + for (i = 0; i < screen_num_desktops; ++i) + STRUT_ADD(strut[i], dock_strut); + screen_update_area(); } static void screen_update_area() { guint i; - gulong *dims; - - if (area != NULL) - g_free(area); + guint32 *dims; + + g_free(area); area = g_new0(Rect, screen_num_desktops + 1); - dims = g_new(unsigned long, 4 * screen_num_desktops); + dims = g_new(guint32, 4 * screen_num_desktops); for (i = 0; i < screen_num_desktops + 1; ++i) { Rect old_area = area[i]; /* @@ -513,7 +553,7 @@ static void screen_update_area() */ if (!RECT_EQUAL(old_area, area[i])) { /* the area has changed, adjust all the maximized windows */ - GSList *it; + GList *it; for (it = client_list; it; it = it->next) { Client *c = it->data; if (i < screen_num_desktops) { @@ -535,7 +575,7 @@ static void screen_update_area() dims[(i * 4) + 3] = area[i].height; } } - PROP_SET32A(ob_root, net_workarea, cardinal, + PROP_SETA32(ob_root, net_workarea, cardinal, dims, 4 * screen_num_desktops); g_free(dims); }