X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fscreen.c;h=d89bf8564660ea23c80cf889d2df7320e007ea2f;hb=e2ddfaf9fff1fb9dd6ebdc1a95f2b228d6baedb2;hp=9ebeffee80691b07e20f5e54609f6450ea6def57;hpb=556eb7b7fb20b3b0db03b6d92259ad3bb16dccde;p=chaz%2Fopenbox diff --git a/openbox/screen.c b/openbox/screen.c index 9ebeffee..d89bf856 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -20,7 +20,6 @@ #include "debug.h" #include "openbox.h" #include "dock.h" -#include "xerror.h" #include "prop.h" #include "grab.h" #include "startupnotify.h" @@ -34,9 +33,9 @@ #include "event.h" #include "focus.h" #include "popup.h" -#include "extensions.h" #include "render/render.h" #include "gettext.h" +#include "obt/display.h" #include #ifdef HAVE_UNISTD_H @@ -59,14 +58,16 @@ static void screen_fallback_focus(void); guint screen_num_desktops; guint screen_num_monitors; guint screen_desktop; -guint screen_last_desktop; -Size screen_physical_size; +guint screen_last_desktop = 1; gboolean screen_showing_desktop; ObDesktopLayout screen_desktop_layout; gchar **screen_desktop_names; Window screen_support_win; Time screen_desktop_user_time = CurrentTime; +static Size screen_physical_size; +static guint screen_old_desktop; +static gboolean screen_desktop_timeout = TRUE; /*! An array of desktops, holding array of areas per monitor */ static Rect *monitor_area = NULL; /*! An array of desktops, holding an array of struts */ @@ -77,6 +78,10 @@ static GSList *struts_bottom = NULL; static ObPagerPopup *desktop_popup; +/*! The number of microseconds that you need to be on a desktop before it will + replace the remembered "last desktop" */ +#define REMEMBER_LAST_DESKTOP_TIME 750000 + static gboolean replace_wm(void) { gchar *wm_sn; @@ -85,10 +90,10 @@ static gboolean replace_wm(void) Time timestamp; wm_sn = g_strdup_printf("WM_S%d", ob_screen); - wm_sn_atom = XInternAtom(ob_display, wm_sn, FALSE); + wm_sn_atom = XInternAtom(obt_display, wm_sn, FALSE); g_free(wm_sn); - current_wm_sn_owner = XGetSelectionOwner(ob_display, wm_sn_atom); + current_wm_sn_owner = XGetSelectionOwner(obt_display, wm_sn_atom); if (current_wm_sn_owner == screen_support_win) current_wm_sn_owner = None; if (current_wm_sn_owner) { @@ -97,24 +102,23 @@ static gboolean replace_wm(void) ob_screen); return FALSE; } - xerror_set_ignore(TRUE); - xerror_occured = FALSE; + obt_display_ignore_errors(TRUE); /* We want to find out when the current selection owner dies */ - XSelectInput(ob_display, current_wm_sn_owner, StructureNotifyMask); - XSync(ob_display, FALSE); + XSelectInput(obt_display, current_wm_sn_owner, StructureNotifyMask); + XSync(obt_display, FALSE); - xerror_set_ignore(FALSE); - if (xerror_occured) + obt_display_ignore_errors(FALSE); + if (obt_display_error_occured) current_wm_sn_owner = None; } timestamp = event_get_server_time(); - XSetSelectionOwner(ob_display, wm_sn_atom, screen_support_win, + XSetSelectionOwner(obt_display, wm_sn_atom, screen_support_win, timestamp); - if (XGetSelectionOwner(ob_display, wm_sn_atom) != screen_support_win) { + if (XGetSelectionOwner(obt_display, wm_sn_atom) != screen_support_win) { g_message(_("Could not acquire window manager selection on screen %d"), ob_screen); return FALSE; @@ -127,7 +131,7 @@ static gboolean replace_wm(void) const gulong timeout = G_USEC_PER_SEC * 15; /* wait for 15s max */ while (wait < timeout) { - if (XCheckWindowEvent(ob_display, current_wm_sn_owner, + if (XCheckWindowEvent(obt_display, current_wm_sn_owner, StructureNotifyMask, &event) && event.type == DestroyNotify) break; @@ -142,7 +146,7 @@ static gboolean replace_wm(void) } /* Send client message indicating that we are now the WM */ - prop_message(RootWindow(ob_display, ob_screen), prop_atoms.manager, + prop_message(RootWindow(obt_display, ob_screen), prop_atoms.manager, timestamp, wm_sn_atom, screen_support_win, 0, SubstructureNotifyMask); @@ -160,31 +164,30 @@ gboolean screen_annex(void) /* create the netwm support window */ attrib.override_redirect = TRUE; attrib.event_mask = PropertyChangeMask; - screen_support_win = XCreateWindow(ob_display, - RootWindow(ob_display, ob_screen), + screen_support_win = XCreateWindow(obt_display, + RootWindow(obt_display, ob_screen), -100, -100, 1, 1, 0, CopyFromParent, InputOutput, CopyFromParent, CWEventMask | CWOverrideRedirect, &attrib); - XMapWindow(ob_display, screen_support_win); - XLowerWindow(ob_display, screen_support_win); + XMapWindow(obt_display, screen_support_win); + XLowerWindow(obt_display, screen_support_win); if (!replace_wm()) { - XDestroyWindow(ob_display, screen_support_win); + XDestroyWindow(obt_display, screen_support_win); return FALSE; } - xerror_set_ignore(TRUE); - xerror_occured = FALSE; - XSelectInput(ob_display, RootWindow(ob_display, ob_screen), + obt_display_ignore_errors(TRUE); + XSelectInput(obt_display, RootWindow(obt_display, ob_screen), ROOT_EVENTMASK); - xerror_set_ignore(FALSE); - if (xerror_occured) { + obt_display_ignore_errors(FALSE); + if (obt_display_error_occured) { g_message(_("A window manager is already running on screen %d"), ob_screen); - XDestroyWindow(ob_display, screen_support_win); + XDestroyWindow(obt_display, screen_support_win); return FALSE; } @@ -192,11 +195,11 @@ gboolean screen_annex(void) /* set the OPENBOX_PID hint */ pid = getpid(); - PROP_SET32(RootWindow(ob_display, ob_screen), + PROP_SET32(RootWindow(obt_display, ob_screen), openbox_pid, cardinal, pid); /* set supporting window */ - PROP_SET32(RootWindow(ob_display, ob_screen), + PROP_SET32(RootWindow(obt_display, ob_screen), net_supporting_wm_check, window, screen_support_win); /* set properties on the supporting window */ @@ -283,6 +286,8 @@ gboolean screen_annex(void) supported[i++] = prop_atoms.net_wm_sync_request; supported[i++] = prop_atoms.net_wm_sync_request_counter; #endif + supported[i++] = prop_atoms.net_wm_pid; + supported[i++] = prop_atoms.net_wm_ping; supported[i++] = prop_atoms.kde_wm_change_state; supported[i++] = prop_atoms.kde_net_wm_frame_strut; @@ -295,7 +300,7 @@ gboolean screen_annex(void) supported[i++] = prop_atoms.ob_control; g_assert(i == num_support); - PROP_SETA32(RootWindow(ob_display, ob_screen), + PROP_SETA32(RootWindow(obt_display, ob_screen), net_supported, atom, supported, num_support); g_free(supported); @@ -328,13 +333,13 @@ static void screen_tell_ksplash(void) hear it anyways. perhaps it is for old ksplash. or new ksplash. or something. oh well. */ e.xclient.type = ClientMessage; - e.xclient.display = ob_display; - e.xclient.window = RootWindow(ob_display, ob_screen); + e.xclient.display = obt_display; + e.xclient.window = RootWindow(obt_display, ob_screen); e.xclient.message_type = - XInternAtom(ob_display, "_KDE_SPLASH_PROGRESS", False ); + XInternAtom(obt_display, "_KDE_SPLASH_PROGRESS", False ); e.xclient.format = 8; strcpy(e.xclient.data.b, "wm started"); - XSendEvent(ob_display, RootWindow(ob_display, ob_screen), + XSendEvent(obt_display, RootWindow(obt_display, ob_screen), False, SubstructureNotifyMask, &e ); } @@ -359,7 +364,7 @@ void screen_startup(gboolean reconfig) screen_resize(); /* have names already been set for the desktops? */ - if (PROP_GETSS(RootWindow(ob_display, ob_screen), + if (PROP_GETSS(RootWindow(obt_display, ob_screen), net_desktop_names, utf8, &names)) { g_strfreev(names); @@ -382,7 +387,8 @@ void screen_startup(gboolean reconfig) names[i] = g_strdup(it->data); /* set the root window property */ - PROP_SETSS(RootWindow(ob_display, ob_screen), net_desktop_names,names); + PROP_SETSS(RootWindow(obt_display, ob_screen), + net_desktop_names,names); g_strfreev(names); } @@ -392,7 +398,7 @@ void screen_startup(gboolean reconfig) this will also set the default names from the config file up for desktops that don't have names yet */ screen_num_desktops = 0; - if (PROP_GET32(RootWindow(ob_display, ob_screen), + if (PROP_GET32(RootWindow(obt_display, ob_screen), net_number_of_desktops, cardinal, &d)) screen_set_num_desktops(d); /* restore from session if possible */ @@ -403,7 +409,7 @@ void screen_startup(gboolean reconfig) screen_desktop = screen_num_desktops; /* something invalid */ /* start on the current desktop when a wm was already running */ - if (PROP_GET32(RootWindow(ob_display, ob_screen), + if (PROP_GET32(RootWindow(obt_display, ob_screen), net_current_desktop, cardinal, &d) && d < screen_num_desktops) { @@ -418,7 +424,7 @@ void screen_startup(gboolean reconfig) /* don't start in showing-desktop mode */ screen_showing_desktop = FALSE; - PROP_SET32(RootWindow(ob_display, ob_screen), + PROP_SET32(RootWindow(obt_display, ob_screen), net_showing_desktop, cardinal, screen_showing_desktop); if (session_desktop_layout_present && @@ -437,17 +443,17 @@ void screen_shutdown(gboolean reconfig) if (reconfig) return; - XSelectInput(ob_display, RootWindow(ob_display, ob_screen), + XSelectInput(obt_display, RootWindow(obt_display, ob_screen), NoEventMask); /* we're not running here no more! */ - PROP_ERASE(RootWindow(ob_display, ob_screen), openbox_pid); + PROP_ERASE(RootWindow(obt_display, ob_screen), openbox_pid); /* not without us */ - PROP_ERASE(RootWindow(ob_display, ob_screen), net_supported); + PROP_ERASE(RootWindow(obt_display, ob_screen), net_supported); /* don't keep this mode */ - PROP_ERASE(RootWindow(ob_display, ob_screen), net_showing_desktop); + PROP_ERASE(RootWindow(obt_display, ob_screen), net_showing_desktop); - XDestroyWindow(ob_display, screen_support_win); + XDestroyWindow(obt_display, screen_support_win); g_strfreev(screen_desktop_names); screen_desktop_names = NULL; @@ -460,8 +466,8 @@ void screen_resize(void) GList *it; gulong geometry[2]; - w = WidthOfScreen(ScreenOfDisplay(ob_display, ob_screen)); - h = HeightOfScreen(ScreenOfDisplay(ob_display, ob_screen)); + w = WidthOfScreen(ScreenOfDisplay(obt_display, ob_screen)); + h = HeightOfScreen(ScreenOfDisplay(obt_display, ob_screen)); if (w == oldw && h == oldh) return; @@ -470,7 +476,7 @@ void screen_resize(void) /* Set the _NET_DESKTOP_GEOMETRY hint */ screen_physical_size.width = geometry[0] = w; screen_physical_size.height = geometry[1] = h; - PROP_SETA32(RootWindow(ob_display, ob_screen), + PROP_SETA32(RootWindow(obt_display, ob_screen), net_desktop_geometry, cardinal, geometry, 2); if (ob_state() == OB_STATE_STARTING) @@ -495,12 +501,12 @@ void screen_set_num_desktops(guint num) old = screen_num_desktops; screen_num_desktops = num; - PROP_SET32(RootWindow(ob_display, ob_screen), + PROP_SET32(RootWindow(obt_display, ob_screen), net_number_of_desktops, cardinal, num); /* set the viewport hint */ viewport = g_new0(gulong, num * 2); - PROP_SETA32(RootWindow(ob_display, ob_screen), + PROP_SETA32(RootWindow(obt_display, ob_screen), net_desktop_viewport, cardinal, viewport, num * 2); g_free(viewport); @@ -577,23 +583,90 @@ static void screen_fallback_focus(void) } } +static gboolean last_desktop_func(gpointer data) +{ + screen_desktop_timeout = TRUE; + return FALSE; +} + void screen_set_desktop(guint num, gboolean dofocus) { GList *it; - guint old; + guint previous; gulong ignore_start; g_assert(num < screen_num_desktops); - old = screen_desktop; + previous = screen_desktop; screen_desktop = num; - if (old == num) return; + if (previous == num) return; - PROP_SET32(RootWindow(ob_display, ob_screen), + PROP_SET32(RootWindow(obt_display, ob_screen), net_current_desktop, cardinal, num); - screen_last_desktop = old; + /* This whole thing decides when/how to save the screen_last_desktop so + that it can be restored later if you want */ + if (screen_desktop_timeout) { + /* If screen_desktop_timeout is true, then we've been on this desktop + long enough and we can save it as the last desktop. */ + + /* save the "last desktop" as the "old desktop" */ + screen_old_desktop = screen_last_desktop; + /* save the desktop we're coming from as the "last desktop" */ + screen_last_desktop = previous; + } + else { + /* If screen_desktop_timeout is false, then we just got to this desktop + and we are moving away again. */ + + if (screen_desktop == screen_last_desktop) { + /* If we are moving to the "last desktop" .. */ + if (previous == screen_old_desktop) { + /* .. from the "old desktop", change the last desktop to + be where we are coming from */ + screen_last_desktop = screen_old_desktop; + } + else if (screen_last_desktop == screen_old_desktop) { + /* .. and also to the "old desktop", change the "last + desktop" to be where we are coming from */ + screen_last_desktop = previous; + } + else { + /* .. from some other desktop, then set the "last desktop" to + be the saved "old desktop", i.e. where we were before the + "last desktop" */ + screen_last_desktop = screen_old_desktop; + } + } + else { + /* If we are moving to any desktop besides the "last desktop".. + (this is the normal case) */ + if (screen_desktop == screen_old_desktop) { + /* If moving to the "old desktop", which is not the + "last desktop", don't save anything */ + } + else if (previous == screen_old_desktop) { + /* If moving from the "old desktop", and not to the + "last desktop", don't save anything */ + } + else if (screen_last_desktop == screen_old_desktop) { + /* If the "last desktop" is the same as "old desktop" and + you're not moving to the "last desktop" then save where + we're coming from as the "last desktop" */ + screen_last_desktop = previous; + } + else { + /* If the "last desktop" is different from the "old desktop" + and you're not moving to the "last desktop", then don't save + anything */ + } + } + } + screen_desktop_timeout = FALSE; + ob_main_loop_timeout_remove(ob_main_loop, last_desktop_func); + ob_main_loop_timeout_add(ob_main_loop, REMEMBER_LAST_DESKTOP_TIME, + last_desktop_func, NULL, NULL, NULL); ob_debug("Moving to desktop %d\n", num+1); @@ -1019,7 +1092,7 @@ void screen_update_layout(void) screen_desktop_layout.rows = 1; screen_desktop_layout.columns = screen_num_desktops; - if (PROP_GETA32(RootWindow(ob_display, ob_screen), + if (PROP_GETA32(RootWindow(obt_display, ob_screen), net_desktop_layout, cardinal, &data, &num)) { if (num == 3 || num == 4) { @@ -1064,7 +1137,7 @@ void screen_update_desktop_names(void) g_strfreev(screen_desktop_names); screen_desktop_names = NULL; - if (PROP_GETSS(RootWindow(ob_display, ob_screen), + if (PROP_GETSS(RootWindow(obt_display, ob_screen), net_desktop_names, utf8, &screen_desktop_names)) for (i = 0; screen_desktop_names[i] && i < screen_num_desktops; ++i); else @@ -1091,7 +1164,7 @@ void screen_update_desktop_names(void) /* if we changed any names, then set the root property so we can all agree on the names */ - PROP_SETSS(RootWindow(ob_display, ob_screen), net_desktop_names, + PROP_SETSS(RootWindow(obt_display, ob_screen), net_desktop_names, screen_desktop_names); } @@ -1159,7 +1232,7 @@ void screen_show_desktop(gboolean show, ObClient *show_only) } show = !!show; /* make it boolean */ - PROP_SET32(RootWindow(ob_display, ob_screen), + PROP_SET32(RootWindow(obt_display, ob_screen), net_showing_desktop, cardinal, show); } @@ -1167,16 +1240,16 @@ void screen_install_colormap(ObClient *client, gboolean install) { if (client == NULL || client->colormap == None) { if (install) - XInstallColormap(RrDisplay(ob_rr_inst), RrColormap(ob_rr_inst)); + XInstallColormap(obt_display, RrColormap(ob_rr_inst)); else - XUninstallColormap(RrDisplay(ob_rr_inst), RrColormap(ob_rr_inst)); + XUninstallColormap(obt_display, RrColormap(ob_rr_inst)); } else { - xerror_set_ignore(TRUE); + obt_display_ignore_errors(TRUE); if (install) - XInstallColormap(RrDisplay(ob_rr_inst), client->colormap); + XInstallColormap(obt_display, client->colormap); else - XUninstallColormap(RrDisplay(ob_rr_inst), client->colormap); - xerror_set_ignore(FALSE); + XUninstallColormap(obt_display, client->colormap); + obt_display_ignore_errors(FALSE); } } @@ -1218,6 +1291,55 @@ typedef struct { } \ } +static void get_xinerama_screens(Rect **xin_areas, guint *nxin) +{ + guint i; + gint l, r, t, b; + + if (ob_debug_xinerama) { + g_print("Using fake xinerama !\n"); + gint w = WidthOfScreen(ScreenOfDisplay(obt_display, ob_screen)); + gint h = HeightOfScreen(ScreenOfDisplay(obt_display, ob_screen)); + *nxin = 2; + *xin_areas = g_new(Rect, *nxin + 1); + RECT_SET((*xin_areas)[0], 0, 0, w/2, h); + RECT_SET((*xin_areas)[1], w/2, 0, w-(w/2), h); + } +#ifdef XINERAMA + else if (obt_display_extension_xinerama) { + guint i; + gint n; + XineramaScreenInfo *info = XineramaQueryScreens(obt_display, &n); + *nxin = n; + *xin_areas = g_new(Rect, *nxin + 1); + for (i = 0; i < *nxin; ++i) + RECT_SET((*xin_areas)[i], info[i].x_org, info[i].y_org, + info[i].width, info[i].height); + XFree(info); + } +#endif + else { + *nxin = 1; + *xin_areas = g_new(Rect, *nxin + 1); + RECT_SET((*xin_areas)[0], 0, 0, + WidthOfScreen(ScreenOfDisplay(obt_display, ob_screen)), + HeightOfScreen(ScreenOfDisplay(obt_display, ob_screen))); + } + + /* returns one extra with the total area in it */ + l = (*xin_areas)[0].x; + t = (*xin_areas)[0].y; + r = (*xin_areas)[0].x + (*xin_areas)[0].width - 1; + b = (*xin_areas)[0].y + (*xin_areas)[0].height - 1; + for (i = 1; i < *nxin; ++i) { + l = MIN(l, (*xin_areas)[i].x); + t = MIN(l, (*xin_areas)[i].y); + r = MAX(r, (*xin_areas)[i].x + (*xin_areas)[i].width - 1); + b = MAX(b, (*xin_areas)[i].y + (*xin_areas)[i].height - 1); + } + RECT_SET((*xin_areas)[*nxin], l, t, r - l + 1, b - t + 1); +} + void screen_update_areas(void) { guint i, j; @@ -1226,7 +1348,7 @@ void screen_update_areas(void) GSList *sit; g_free(monitor_area); - extensions_xinerama_screens(&monitor_area, &screen_num_monitors); + get_xinerama_screens(&monitor_area, &screen_num_monitors); /* set up the user-specified margins */ config_margins.top_start = RECT_LEFT(monitor_area[screen_num_monitors]); @@ -1335,7 +1457,7 @@ void screen_update_areas(void) /* all the work areas are not used here, only the ones for the first monitor are */ - PROP_SETA32(RootWindow(ob_display, ob_screen), net_workarea, cardinal, + PROP_SETA32(RootWindow(obt_display, ob_screen), net_workarea, cardinal, dims, 4 * screen_num_desktops); /* the area has changed, adjust all the windows if they need it */ @@ -1510,7 +1632,7 @@ Rect* screen_area(guint desktop, guint head, Rect *search) guint screen_find_monitor(Rect *search) { guint i; - guint most = 0; + guint most = screen_num_monitors; guint mostv = 0; for (i = 0; i < screen_num_monitors; ++i) { @@ -1577,10 +1699,10 @@ Rect* screen_physical_area_active(void) void screen_set_root_cursor(void) { if (sn_app_starting()) - XDefineCursor(ob_display, RootWindow(ob_display, ob_screen), + XDefineCursor(obt_display, RootWindow(obt_display, ob_screen), ob_cursor(OB_CURSOR_BUSYPOINTER)); else - XDefineCursor(ob_display, RootWindow(ob_display, ob_screen), + XDefineCursor(obt_display, RootWindow(obt_display, ob_screen), ob_cursor(OB_CURSOR_POINTER)); } @@ -1591,12 +1713,12 @@ gboolean screen_pointer_pos(gint *x, gint *y) guint u; gboolean ret; - ret = !!XQueryPointer(ob_display, RootWindow(ob_display, ob_screen), + ret = !!XQueryPointer(obt_display, RootWindow(obt_display, ob_screen), &w, &w, x, y, &i, &i, &u); if (!ret) { - for (i = 0; i < ScreenCount(ob_display); ++i) + for (i = 0; i < ScreenCount(obt_display); ++i) if (i != ob_screen) - if (XQueryPointer(ob_display, RootWindow(ob_display, i), + if (XQueryPointer(obt_display, RootWindow(obt_display, i), &w, &w, x, y, &i, &i, &u)) break; }