X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=openbox%2Fscreen.c;h=4ad46af738c79135dd8118b28c633a88ac1b0e2f;hb=ed4d0ca31a9c1c6c815cb87a058bb1d36a0888c1;hp=b305e68535726d753f141432e4c4e9b9b92f735a;hpb=3409148047e2d179fbe9fc5ef194253cc0f0ad85;p=chaz%2Fopenbox diff --git a/openbox/screen.c b/openbox/screen.c index b305e685..4ad46af7 100644 --- a/openbox/screen.c +++ b/openbox/screen.c @@ -28,6 +28,7 @@ #include "config.h" #include "screen.h" #include "client.h" +#include "session.h" #include "frame.h" #include "event.h" #include "focus.h" @@ -169,6 +170,7 @@ gboolean screen_annex() CopyFromParent, CWOverrideRedirect, &attrib); XMapWindow(ob_display, screen_support_win); + XLowerWindow(ob_display, screen_support_win); if (!replace_wm()) { XDestroyWindow(ob_display, screen_support_win); @@ -188,7 +190,6 @@ gboolean screen_annex() return FALSE; } - screen_set_root_cursor(); /* set the OPENBOX_PID hint */ @@ -256,6 +257,8 @@ gboolean screen_annex() supported[i++] = prop_atoms.net_wm_action_fullscreen; supported[i++] = prop_atoms.net_wm_action_change_desktop; supported[i++] = prop_atoms.net_wm_action_close; + supported[i++] = prop_atoms.net_wm_action_above; + supported[i++] = prop_atoms.net_wm_action_below; supported[i++] = prop_atoms.net_wm_state; supported[i++] = prop_atoms.net_wm_state_modal; supported[i++] = prop_atoms.net_wm_state_maximized_vert; @@ -271,7 +274,10 @@ gboolean screen_annex() supported[i++] = prop_atoms.net_moveresize_window; supported[i++] = prop_atoms.net_wm_moveresize; supported[i++] = prop_atoms.net_wm_user_time; + supported[i++] = prop_atoms.net_wm_user_time_window; supported[i++] = prop_atoms.net_frame_extents; + supported[i++] = prop_atoms.net_request_frame_extents; + supported[i++] = prop_atoms.net_restack_window; supported[i++] = prop_atoms.net_startup_id; #ifdef SYNC supported[i++] = prop_atoms.net_wm_sync_request; @@ -282,10 +288,11 @@ gboolean screen_annex() supported[i++] = prop_atoms.kde_net_wm_frame_strut; supported[i++] = prop_atoms.kde_net_wm_window_type_override; - supported[i++] = prop_atoms.openbox_wm_state_undecorated; + supported[i++] = prop_atoms.ob_wm_action_undecorate; + supported[i++] = prop_atoms.ob_wm_state_undecorated; supported[i++] = prop_atoms.openbox_pid; - supported[i++] = prop_atoms.openbox_rc; - supported[i++] = prop_atoms.openbox_control; + supported[i++] = prop_atoms.ob_config; + supported[i++] = prop_atoms.ob_control; g_assert(i == num_support); PROP_SETA32(RootWindow(ob_display, ob_screen), @@ -297,48 +304,60 @@ gboolean screen_annex() void screen_startup(gboolean reconfig) { + guint i, numnames; + gchar **names; GSList *it; - guint i; + guint32 d; desktop_cycle_popup = pager_popup_new(FALSE); + pager_popup_height(desktop_cycle_popup, POPUP_HEIGHT); + + if (reconfig) { + /* update the pager popup's width */ + pager_popup_text_width_to_strings(desktop_cycle_popup, + screen_desktop_names, + screen_num_desktops); + return; + } - if (!reconfig) - /* get the initial size */ - screen_resize(); + /* get the initial size */ + screen_resize(); - /* set the names */ - screen_desktop_names = g_new(gchar*, - g_slist_length(config_desktops_names) + 1); + /* get the desktop names */ + numnames = g_slist_length(config_desktops_names); + names = g_new(gchar*, numnames + 1); + names[numnames] = NULL; for (i = 0, it = config_desktops_names; it; ++i, it = g_slist_next(it)) - screen_desktop_names[i] = it->data; /* dont strdup */ - screen_desktop_names[i] = NULL; - PROP_SETSS(RootWindow(ob_display, ob_screen), - net_desktop_names, screen_desktop_names); - g_free(screen_desktop_names); /* dont free the individual strings */ - screen_desktop_names = NULL; + names[i] = g_strdup(it->data); + + /* set the root window property */ + PROP_SETSS(RootWindow(ob_display, ob_screen), net_desktop_names,names); + + g_strfreev(names); - if (!reconfig) - screen_num_desktops = 0; + /* set the number of desktops */ + screen_num_desktops = 0; screen_set_num_desktops(config_desktops_num); - if (!reconfig) { - guint32 d; - /* start on the current desktop when a wm was already running */ - if (PROP_GET32(RootWindow(ob_display, ob_screen), - net_current_desktop, cardinal, &d) && - d < screen_num_desktops) - { - screen_set_desktop(d); - } else - screen_set_desktop(MIN(config_screen_firstdesk, - screen_num_desktops) - 1); - /* don't start in showing-desktop mode */ - screen_showing_desktop = FALSE; - PROP_SET32(RootWindow(ob_display, ob_screen), - net_showing_desktop, cardinal, screen_showing_desktop); + /* start on the current desktop when a wm was already running */ + if (PROP_GET32(RootWindow(ob_display, ob_screen), + net_current_desktop, cardinal, &d) && + d < screen_num_desktops) + { + screen_set_desktop(d, FALSE); + } else if (session_desktop >= 0) + screen_set_desktop(MIN((guint)session_desktop, + screen_num_desktops), FALSE); + else + screen_set_desktop(MIN(config_screen_firstdesk, + screen_num_desktops) - 1, FALSE); - screen_update_layout(); - } + /* don't start in showing-desktop mode */ + screen_showing_desktop = FALSE; + PROP_SET32(RootWindow(ob_display, ob_screen), + net_showing_desktop, cardinal, screen_showing_desktop); + + screen_update_layout(); } void screen_shutdown(gboolean reconfig) @@ -347,22 +366,24 @@ void screen_shutdown(gboolean reconfig) pager_popup_free(desktop_cycle_popup); - if (!reconfig) { - XSelectInput(ob_display, RootWindow(ob_display, ob_screen), - NoEventMask); + if (reconfig) + return; + + XSelectInput(ob_display, RootWindow(ob_display, ob_screen), + NoEventMask); - /* we're not running here no more! */ - PROP_ERASE(RootWindow(ob_display, ob_screen), openbox_pid); - /* not without us */ - PROP_ERASE(RootWindow(ob_display, ob_screen), net_supported); - /* don't keep this mode */ - PROP_ERASE(RootWindow(ob_display, ob_screen), net_showing_desktop); + /* we're not running here no more! */ + PROP_ERASE(RootWindow(ob_display, ob_screen), openbox_pid); + /* not without us */ + PROP_ERASE(RootWindow(ob_display, ob_screen), net_supported); + /* don't keep this mode */ + PROP_ERASE(RootWindow(ob_display, ob_screen), net_showing_desktop); - XDestroyWindow(ob_display, screen_support_win); - } + XDestroyWindow(ob_display, screen_support_win); g_strfreev(screen_desktop_names); screen_desktop_names = NULL; + for (r = area; *r; ++r) g_free(*r); g_free(area); @@ -423,9 +444,6 @@ void screen_set_num_desktops(guint num) /* the number of rows/columns will differ */ screen_update_layout(); - /* may be some unnamed desktops that we need to fill in with names */ - screen_update_desktop_names(); - /* move windows on desktops that will no longer exist! */ for (it = client_list; it; it = g_list_next(it)) { ObClient *c = it->data; @@ -436,12 +454,16 @@ void screen_set_num_desktops(guint num) /* change our struts/area to match (after moving windows) */ screen_update_areas(); + /* may be some unnamed desktops that we need to fill in with names + (after updating the areas so the popup can resize) */ + screen_update_desktop_names(); + /* change our desktop if we're on one that no longer exists! */ if (screen_desktop >= screen_num_desktops) - screen_set_desktop(num - 1); + screen_set_desktop(num - 1, TRUE); } -void screen_set_desktop(guint num) +void screen_set_desktop(guint num, gboolean dofocus) { ObClient *c; GList *it; @@ -465,7 +487,7 @@ void screen_set_desktop(guint num) /* show windows before hiding the rest to lessen the enter/leave events */ - /* show/hide windows from top to bottom */ + /* show windows from top to bottom */ for (it = stacking_list; it; it = g_list_next(it)) { if (WINDOW_IS_CLIENT(it->data)) { ObClient *c = it->data; @@ -473,6 +495,26 @@ void screen_set_desktop(guint num) } } + /* have to try focus here because when you leave an empty desktop + there is no focus out to watch for + + do this before hiding the windows so if helper windows are coming + with us, they don't get hidden + */ + if (dofocus && (c = focus_fallback(TRUE))) { + /* only do the flicker reducing stuff ahead of time if we are going + to call xsetinputfocus on the window ourselves. otherwise there is + no guarantee the window will actually take focus.. */ + if (c->can_focus) { + /* reduce flicker by hiliting now rather than waiting for the + server FocusIn event */ + frame_adjust_focus(c->frame, TRUE); + /* do this here so that if you switch desktops to a window with + helper windows then the helper windows won't flash */ + client_bring_helper_windows(c); + } + } + /* hide windows from bottom to top */ for (it = g_list_last(stacking_list); it; it = g_list_previous(it)) { if (WINDOW_IS_CLIENT(it->data)) { @@ -481,16 +523,7 @@ void screen_set_desktop(guint num) } } - /* have to try focus here because when you leave an empty desktop - there is no focus out to watch for */ - if ((c = focus_fallback_target(TRUE, focus_client))) { - /* reduce flicker by hiliting now rather than waiting for the server - FocusIn event */ - frame_adjust_focus(c->frame, TRUE); - client_focus(c); - } - - event_ignore_queued_enters(); + event_ignore_all_queued_enters(); if (event_curtime != CurrentTime) screen_desktop_user_time = event_curtime; @@ -614,9 +647,13 @@ void screen_desktop_popup(guint d, gboolean show) a = screen_physical_area_monitor(0); pager_popup_position(desktop_cycle_popup, CenterGravity, a->x + a->width / 2, a->y + a->height / 2); - pager_popup_width(desktop_cycle_popup, MAX(a->width/3, POPUP_WIDTH)); - pager_popup_height(desktop_cycle_popup, POPUP_HEIGHT); - + pager_popup_icon_size_multiplier(desktop_cycle_popup, + (screen_desktop_layout.columns / + screen_desktop_layout.rows) / 2, + (screen_desktop_layout.rows/ + screen_desktop_layout.columns) / 2); + pager_popup_max_width(desktop_cycle_popup, + MAX(a->width/3, POPUP_WIDTH)); pager_popup_show(desktop_cycle_popup, screen_desktop_names[d], d); } } @@ -624,21 +661,17 @@ void screen_desktop_popup(guint d, gboolean show) guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, gboolean dialog, gboolean done, gboolean cancel) { - static gboolean first = TRUE; - static guint origd, d; guint r, c; + static guint d = (guint)-1; + guint ret, oldd; - if (cancel) { - d = origd; - goto done_cycle; - } else if (done && dialog) { - goto done_cycle; - } - if (first) { - first = FALSE; - d = origd = screen_desktop; - } + if (d == (guint)-1) + d = screen_desktop; + + if ((cancel || done) && dialog) + goto show_cycle_dialog; + oldd = d; get_row_col(d, &r, &c); if (linear) { @@ -664,19 +697,17 @@ guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, case OB_DIRECTION_EAST: ++c; if (c >= screen_desktop_layout.columns) { - if (wrap) { + if (wrap) c = 0; - } else { - d = screen_desktop; + else goto show_cycle_dialog; - } } d = translate_row_col(r, c); if (d >= screen_num_desktops) { if (wrap) { ++c; } else { - d = screen_desktop; + d = oldd; goto show_cycle_dialog; } } @@ -684,19 +715,17 @@ guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, case OB_DIRECTION_WEST: --c; if (c >= screen_desktop_layout.columns) { - if (wrap) { + if (wrap) c = screen_desktop_layout.columns - 1; - } else { - d = screen_desktop; + else goto show_cycle_dialog; - } } d = translate_row_col(r, c); if (d >= screen_num_desktops) { if (wrap) { --c; } else { - d = screen_desktop; + d = oldd; goto show_cycle_dialog; } } @@ -704,19 +733,17 @@ guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, case OB_DIRECTION_SOUTH: ++r; if (r >= screen_desktop_layout.rows) { - if (wrap) { + if (wrap) r = 0; - } else { - d = screen_desktop; + else goto show_cycle_dialog; - } } d = translate_row_col(r, c); if (d >= screen_num_desktops) { if (wrap) { ++r; } else { - d = screen_desktop; + d = oldd; goto show_cycle_dialog; } } @@ -724,19 +751,17 @@ guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, case OB_DIRECTION_NORTH: --r; if (r >= screen_desktop_layout.rows) { - if (wrap) { + if (wrap) r = screen_desktop_layout.rows - 1; - } else { - d = screen_desktop; + else goto show_cycle_dialog; - } } d = translate_row_col(r, c); if (d >= screen_num_desktops) { if (wrap) { --r; } else { - d = screen_desktop; + d = oldd; goto show_cycle_dialog; } } @@ -750,17 +775,16 @@ guint screen_cycle_desktop(ObDirection dir, gboolean wrap, gboolean linear, } show_cycle_dialog: - if (dialog) { + if (dialog && !cancel && !done) { screen_desktop_popup(d, TRUE); - return d; - } - -done_cycle: - first = TRUE; + } else + screen_desktop_popup(0, FALSE); + ret = d; - screen_desktop_popup(0, FALSE); + if (!dialog || cancel || done) + d = (guint)-1; - return d; + return ret; } void screen_update_layout() @@ -864,19 +888,24 @@ void screen_update_desktop_names() if (PROP_GETSS(RootWindow(ob_display, ob_screen), net_desktop_names, utf8, &screen_desktop_names)) - for (i = 0; screen_desktop_names[i] && i <= screen_num_desktops; ++i); + for (i = 0; screen_desktop_names[i] && i < screen_num_desktops; ++i); else i = 0; - if (i <= screen_num_desktops) { + if (i < screen_num_desktops) { screen_desktop_names = g_renew(gchar*, 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_printf("Desktop %i", i + 1); + screen_desktop_names[i] = g_strdup_printf("desktop %i", i + 1); } + + /* resize the pager for these names */ + pager_popup_text_width_to_strings(desktop_cycle_popup, + screen_desktop_names, + screen_num_desktops); } -void screen_show_desktop(gboolean show, gboolean restore_focus) +void screen_show_desktop(gboolean show, ObClient *show_only) { GList *it; @@ -885,25 +914,31 @@ void screen_show_desktop(gboolean show, gboolean restore_focus) screen_showing_desktop = show; if (show) { - /* bottom to top */ + /* hide windows bottom to top */ for (it = g_list_last(stacking_list); it; it = g_list_previous(it)) { if (WINDOW_IS_CLIENT(it->data)) { ObClient *client = it->data; client_showhide(client); } } - } else { - /* top to bottom */ + } + else { + /* restore windows top to bottom */ for (it = stacking_list; it; it = g_list_next(it)) { if (WINDOW_IS_CLIENT(it->data)) { ObClient *client = it->data; - client_showhide(client); + if (client_should_show(client)) { + if (!show_only || client == show_only) + client_show(client); + else + client_iconify(client, TRUE, FALSE, TRUE); + } } } } if (show) { - /* focus desktop */ + /* focus the desktop */ for (it = focus_order; it; it = g_list_next(it)) { ObClient *c = it->data; if (c->type == OB_CLIENT_TYPE_DESKTOP && @@ -911,13 +946,20 @@ void screen_show_desktop(gboolean show, gboolean restore_focus) client_focus(it->data)) break; } - } else if (restore_focus) { + } + else if (!show_only) { ObClient *c; - /* use NULL for the "old" argument because the desktop was focused - and we don't want to fallback to the desktop by default */ - if ((c = focus_fallback_target(TRUE, NULL))) - client_focus(c); + if ((c = focus_fallback(TRUE))) { + /* only do the flicker reducing stuff ahead of time if we are going + to call xsetinputfocus on the window ourselves. otherwise there + is no guarantee the window will actually take focus.. */ + if (c->can_focus) { + /* reduce flicker by hiliting now rather than waiting for the + server FocusIn event */ + frame_adjust_focus(c->frame, TRUE); + } + } } show = !!show; /* make it boolean */ @@ -1228,7 +1270,7 @@ void screen_set_root_cursor() { if (sn_app_starting()) XDefineCursor(ob_display, RootWindow(ob_display, ob_screen), - ob_cursor(OB_CURSOR_BUSY)); + ob_cursor(OB_CURSOR_BUSYPOINTER)); else XDefineCursor(ob_display, RootWindow(ob_display, ob_screen), ob_cursor(OB_CURSOR_POINTER)); @@ -1239,7 +1281,16 @@ gboolean screen_pointer_pos(gint *x, gint *y) Window w; gint i; guint u; - - return !!XQueryPointer(ob_display, RootWindow(ob_display, ob_screen), - &w, &w, x, y, &i, &i, &u); + gboolean ret; + + ret = !!XQueryPointer(ob_display, RootWindow(ob_display, ob_screen), + &w, &w, x, y, &i, &i, &u); + if (!ret) { + for (i = 0; i < ScreenCount(ob_display); ++i) + if (i != ob_screen) + if (XQueryPointer(ob_display, RootWindow(ob_display, i), + &w, &w, x, y, &i, &i, &u)) + break; + } + return ret; }