X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fscreen.c;h=d438a8000114e67192672eddd0ff16f0ae71c373;hb=a4a0cb78294bb1809b836ea1e86e9d7294bb2929;hp=50db863870473aadb4651278fa0b7c752d0ed4dd;hpb=3175986d3ae670a9023fc464a0311c278973873e;p=chaz%2Fopenbox diff --git a/openbox/screen.c b/openbox/screen.c index 50db8638..d438a800 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -1,13 +1,23 @@ #include "openbox.h" +#include "dock.h" +#include "xerror.h" #include "prop.h" +#include "startup.h" +#include "timer.h" #include "config.h" #include "screen.h" #include "client.h" #include "frame.h" #include "focus.h" #include "dispatch.h" +#include "extensions.h" #include "../render/render.h" +#ifdef USE_LIBSN +# define SN_API_NOT_YET_FROZEN +# include +#endif + #include #ifdef HAVE_UNISTD_H # include @@ -15,7 +25,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,13 +35,22 @@ guint screen_desktop = 0; Size screen_physical_size; gboolean screen_showing_desktop; DesktopLayout screen_desktop_layout; -char **screen_desktop_names; +char **screen_desktop_names = NULL; static Rect *area = NULL; static Strut *strut = NULL; static Window support_window = None; +#ifdef USE_LIBSN +static SnMonitorContext *sn_context; +static int sn_busy_cnt; +static Timer *sn_timer = NULL; + +static void sn_event_func(SnMonitorEvent *event, void *data); +#endif + static void screen_update_area(); +static void set_root_cursor(); static gboolean running; static int another_running(Display *d, XErrorEvent *e) @@ -48,7 +67,7 @@ gboolean screen_annex() XErrorHandler old; pid_t pid; int i, num_support; - Atom *supported; + guint32 *supported; running = FALSE; old = XSetErrorHandler(another_running); @@ -60,8 +79,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); + set_root_cursor(); /* set the OPENBOX_PID hint */ pid = getpid(); @@ -74,13 +92,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, "Openbox"); + PROP_SETS(support_window, net_wm_name, "Openbox3"); 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,14 +147,21 @@ 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; */ @@ -152,27 +177,37 @@ void screen_startup() guint i; /* get the initial size */ - screen_resize(); + 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); - screen_desktop = 0; - screen_set_desktop(0); + 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; PROP_SET32(ob_root, net_showing_desktop, cardinal, screen_showing_desktop); screen_update_layout(); + +#ifdef USE_LIBSN + sn_context = sn_monitor_context_new(ob_sn_display, ob_screen, + sn_event_func, NULL, NULL); + sn_busy_cnt = 0; +#endif } void screen_shutdown() @@ -190,14 +225,14 @@ void screen_shutdown() g_free(area); } -void screen_resize() +void screen_resize(int w, int h) { - /* XXX RandR support here? */ + 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)); + 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]; @@ -205,9 +240,11 @@ void screen_resize() 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) @@ -227,9 +264,6 @@ void screen_set_num_desktops(guint num) 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(); @@ -249,10 +283,13 @@ void screen_set_num_desktops(guint num) /* 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) + 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! */ @@ -280,23 +317,28 @@ void screen_set_desktop(guint num) /* 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)) - 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) { - Client *c = it->data; - if (c->frame->visible && !client_should_show(c)) - frame_hide(c->frame); + 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 */ - XSync(ob_display, FALSE); while (XCheckTypedEvent(ob_display, EnterNotify, &e)); + g_message("switch fallback"); focus_fallback(Fallback_Desktop); + g_message("/switch fallback"); dispatch_ob(Event_Ob_Desktop, num, old); } @@ -377,13 +419,16 @@ void screen_update_desktop_names() /* empty the array */ g_strfreev(screen_desktop_names); + screen_desktop_names = NULL; - PROP_GETSS(ob_root, net_desktop_names, utf8, &screen_desktop_names); - - for (i = 0; screen_desktop_names[i] && i < screen_num_desktops; ++i); - if (i < screen_num_desktops) { + 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"); } @@ -400,19 +445,33 @@ void screen_show_desktop(gboolean show) if (show) { /* bottom to top */ for (it = g_list_last(stacking_list); it != NULL; it = it->prev) { - Client *client = it->data; - if (client->frame->visible && !client_should_show(client)) - 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)) - 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) { + /* 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 */ PROP_SET32(ob_root, net_showing_desktop, cardinal, show); @@ -425,16 +484,18 @@ void screen_install_colormap(Client *client, gboolean install) if (client == NULL) { if (install) - XInstallColormap(ob_display, render_colormap); + XInstallColormap(RrDisplay(ob_rr_inst), RrColormap(ob_rr_inst)); else - XUninstallColormap(ob_display, render_colormap); + XUninstallColormap(RrDisplay(ob_rr_inst), RrColormap(ob_rr_inst)); } else { if (XGetWindowAttributes(ob_display, client->window, &wa) && wa.colormap != None) { + xerror_set_ignore(TRUE); if (install) - XInstallColormap(ob_display, wa.colormap); + XInstallColormap(RrDisplay(ob_rr_inst), wa.colormap); else - XUninstallColormap(ob_display, wa.colormap); + XUninstallColormap(RrDisplay(ob_rr_inst), wa.colormap); + xerror_set_ignore(FALSE); } } } @@ -461,6 +522,10 @@ 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(); } @@ -518,11 +583,11 @@ static void screen_update_area() Client *c = it->data; if (i < screen_num_desktops) { if (c->desktop == i) - client_remaximize(c); + client_reconfigure(c); } else { /* the 'all desktops' size */ if (c->desktop == DESKTOP_ALL) - client_remaximize(c); + client_reconfigure(c); } } } @@ -559,3 +624,68 @@ Strut *screen_strut(guint desktop) } return &strut[desktop]; } + +static void set_root_cursor() +{ +#ifdef USE_LIBSN + if (sn_busy_cnt) + XDefineCursor(ob_display, ob_root, ob_cursors.busy); + else +#endif + XDefineCursor(ob_display, ob_root, ob_cursors.ptr); +} + +#ifdef USE_LIBSN +static void sn_timeout(void *data) +{ + timer_stop(sn_timer); + sn_timer = NULL; + sn_busy_cnt = 0; + + set_root_cursor(); +} + +static void sn_event_func(SnMonitorEvent *ev, void *data) +{ + SnStartupSequence *seq; + const char *seq_id, *bin_name; + int cnt = sn_busy_cnt; + + if (!(seq = sn_monitor_event_get_startup_sequence(ev))) + return; + + seq_id = sn_startup_sequence_get_id(seq); + bin_name = sn_startup_sequence_get_binary_name(seq); + + if (!(seq_id && bin_name)) + return; + + switch (sn_monitor_event_get_type(ev)) { + case SN_MONITOR_EVENT_INITIATED: + ++sn_busy_cnt; + if (sn_timer) + timer_stop(sn_timer); + /* 30 second timeout for apps to start */ + sn_timer = timer_start(30 * 1000000, sn_timeout, NULL); + break; + case SN_MONITOR_EVENT_CHANGED: + break; + case SN_MONITOR_EVENT_COMPLETED: + if (sn_busy_cnt) --sn_busy_cnt; + if (sn_timer) { + timer_stop(sn_timer); + sn_timer = NULL; + } + break; + case SN_MONITOR_EVENT_CANCELED: + if (sn_busy_cnt) --sn_busy_cnt; + if (sn_timer) { + timer_stop(sn_timer); + sn_timer = NULL; + } + }; + + if (sn_busy_cnt != cnt) + set_root_cursor(); +} +#endif