diff --git a/src/common.h b/src/common.h index 10f6bd17e..5f5411b1f 100644 --- a/src/common.h +++ b/src/common.h @@ -37,7 +37,8 @@ typedef enum META_FRAME_HAS_FOCUS = 1 << 6, META_FRAME_SHADED = 1 << 7, META_FRAME_STUCK = 1 << 8, - META_FRAME_MAXIMIZED = 1 << 9 + META_FRAME_MAXIMIZED = 1 << 9, + META_FRAME_ALLOWS_SHADE = 1 << 10 } MetaFrameFlags; typedef enum diff --git a/src/display.c b/src/display.c index 652260835..76408122b 100644 --- a/src/display.c +++ b/src/display.c @@ -274,6 +274,21 @@ meta_display_open (const char *name) display->leader_window, display->atom_net_wm_name, "Metacity"); + + { + /* The legacy GNOME hint is to set a cardinal which is the window + * id of the supporting_wm_check window on the supporting_wm_check + * window itself + */ + gulong data[1]; + + data[0] = display->leader_window; + XChangeProperty (display->xdisplay, + display->leader_window, + display->atom_win_supporting_wm_check, + XA_CARDINAL, + 32, PropModeReplace, (guchar*) data, 1); + } /* Now manage all existing windows */ tmp = display->screens; diff --git a/src/frame.c b/src/frame.c index 90df8c81a..758be83f2 100644 --- a/src/frame.c +++ b/src/frame.c @@ -166,21 +166,18 @@ meta_frame_get_flags (MetaFrame *frame) flags = META_FRAME_ALLOWS_MENU | META_FRAME_ALLOWS_RESIZE; - - if (frame->window->maximized) - flags |= META_FRAME_MAXIMIZED; if (frame->window->has_close_func) flags |= META_FRAME_ALLOWS_DELETE; - if (frame->window->type == META_WINDOW_NORMAL) - flags |= (META_FRAME_ALLOWS_MINIMIZE | META_FRAME_ALLOWS_MAXIMIZE); + if (frame->window->has_maximize_func) + flags |= META_FRAME_ALLOWS_MAXIMIZE; - if (!frame->window->has_maximize_func) - flags &= ~META_FRAME_ALLOWS_MAXIMIZE; + if (frame->window->has_minimize_func) + flags |= META_FRAME_ALLOWS_MINIMIZE; - if (!frame->window->has_minimize_func) - flags &= ~META_FRAME_ALLOWS_MINIMIZE; + if (frame->window->has_shade_func) + flags |= META_FRAME_ALLOWS_SHADE; if (frame->window->has_focus) flags |= META_FRAME_HAS_FOCUS; @@ -191,6 +188,9 @@ meta_frame_get_flags (MetaFrame *frame) if (frame->window->on_all_workspaces) flags |= META_FRAME_STUCK; + if (frame->window->maximized) + flags |= META_FRAME_MAXIMIZED; + return flags; } diff --git a/src/frames.c b/src/frames.c index 235406f9a..07ddfab6d 100644 --- a/src/frames.c +++ b/src/frames.c @@ -966,12 +966,15 @@ meta_frames_button_press_event (GtkWidget *widget, flags = meta_core_get_frame_flags (gdk_display, frame->xwindow); - if (flags & META_FRAME_SHADED) - meta_core_unshade (gdk_display, - frame->xwindow); - else - meta_core_shade (gdk_display, - frame->xwindow); + if (flags & META_FRAME_ALLOWS_SHADE) + { + if (flags & META_FRAME_SHADED) + meta_core_unshade (gdk_display, + frame->xwindow); + else + meta_core_shade (gdk_display, + frame->xwindow); + } return TRUE; } diff --git a/src/keybindings.c b/src/keybindings.c index 009c3bc2d..6c2b1a933 100644 --- a/src/keybindings.c +++ b/src/keybindings.c @@ -187,6 +187,11 @@ meta_window_grab_keys (MetaWindow *window) return; /* already all good */ } + /* no keybindings for Emacs ;-) */ + if (window->res_class && + g_strcasecmp (window->res_class, "Emacs") == 0) + return; + grab_keys (window_bindings, window->display, window->frame ? window->frame->xwindow : window->xwindow); diff --git a/src/screen.c b/src/screen.c index 966c47d4a..7e12be171 100644 --- a/src/screen.c +++ b/src/screen.c @@ -54,7 +54,7 @@ set_wm_check_hint (MetaScreen *screen) /* Legacy GNOME hint */ XChangeProperty (screen->display->xdisplay, screen->xroot, screen->display->atom_win_supporting_wm_check, - XA_WINDOW, + XA_CARDINAL, 32, PropModeReplace, (guchar*) data, 1); return Success; diff --git a/src/stack.c b/src/stack.c index 6e1864f51..89f881b06 100644 --- a/src/stack.c +++ b/src/stack.c @@ -258,7 +258,7 @@ compute_layer (MetaWindow *window) break; case META_WINDOW_DOCK: - window->layer = META_WINDOW_DOCK; + window->layer = META_LAYER_DOCK; break; default: @@ -493,8 +493,6 @@ meta_stack_sync_to_server (MetaStack *stack) { MetaStackLayer old_layer; - old_layer = op->window->layer; - if (op->add_order >= 0) { /* need to add to a layer */ @@ -502,6 +500,8 @@ meta_stack_sync_to_server (MetaStack *stack) g_list_prepend (stack->layers[op->window->layer], op->window); } + + old_layer = op->window->layer; if (op->update_layer) { @@ -572,12 +572,18 @@ meta_stack_sync_to_server (MetaStack *stack) stack->pending = NULL; stack->n_added = 0; - /* Create stacked xwindow arrays */ + /* Create stacked xwindow arrays. + * Painfully, "stacked" is in bottom-to-top order for the + * _NET hints, and "root_children_stacked" is in top-to-bottom + * order for XRestackWindows() + */ stacked = g_array_new (FALSE, FALSE, sizeof (Window)); root_children_stacked = g_array_new (FALSE, FALSE, sizeof (Window)); - i = 0; - while (i < META_LAYER_LAST) + i = META_LAYER_LAST; + do { + --i; + /* Sort each layer... */ if (needs_sort[i]) { @@ -593,8 +599,10 @@ meta_stack_sync_to_server (MetaStack *stack) { MetaWindow *w = tmp->data; - g_array_append_val (stacked, w->xwindow); + /* remember, stacked is in reverse order (bottom to top) */ + g_array_prepend_val (stacked, w->xwindow); + /* build XRestackWindows() array from top to bottom */ if (w->frame) g_array_append_val (root_children_stacked, w->frame->xwindow); else @@ -607,9 +615,8 @@ meta_stack_sync_to_server (MetaStack *stack) meta_verbose ("\n"); meta_pop_no_msg_prefix (); - - ++i; } + while (i > 0); /* All windows should be in some stacking order */ if (stacked->len != stack->windows->len) diff --git a/src/window.c b/src/window.c index 0fc1c9e31..46daf7b25 100644 --- a/src/window.c +++ b/src/window.c @@ -221,7 +221,8 @@ meta_window_new (MetaDisplay *display, Window xwindow, window->has_close_func = TRUE; window->has_minimize_func = TRUE; window->has_maximize_func = TRUE; - + window->has_shade_func = TRUE; + window->wm_state_modal = FALSE; window->wm_state_skip_taskbar = FALSE; window->wm_state_skip_pager = FALSE; @@ -285,17 +286,37 @@ meta_window_new (MetaDisplay *display, Window xwindow, meta_workspace_add_window (space, window); - /* Ignore USPosition on transients because the app is full - * of shit claiming the user set -geometry for a dialog + /* Only accept USPosition on normal windows because the app is full + * of shit claiming the user set -geometry for a dialog or dock */ - if (window->type != META_WINDOW_DIALOG && - window->type != META_WINDOW_MODAL_DIALOG && + if (window->type == META_WINDOW_NORMAL && (window->size_hints.flags & USPosition)) { /* don't constrain with placement algorithm */ window->placed = TRUE; meta_verbose ("Honoring USPosition for %s instead of using placement algorithm\n", window->desc); } + + if (window->type != META_WINDOW_NORMAL) + { + window->placed = TRUE; + meta_verbose ("Not placing non-normal-type window\n"); + } + + if (window->type == META_WINDOW_DESKTOP || + window->type == META_WINDOW_DOCK) + { + /* Change around the defaults */ + window->on_all_workspaces = TRUE; + window->has_close_func = FALSE; + window->has_shade_func = FALSE; + } + + if (window->type != META_WINDOW_NORMAL) + { + window->has_minimize_func = FALSE; + window->has_maximize_func = FALSE; + } /* Put our state back where it should be, * passing TRUE for is_configure_request, ICCCM says @@ -2968,9 +2989,6 @@ meta_window_show_menu (MetaWindow *window, ops |= META_MENU_OP_UNMAXIMIZE; else ops |= META_MENU_OP_MAXIMIZE; - - if (!window->has_maximize_func) - insensitive |= META_MENU_OP_UNMAXIMIZE | META_MENU_OP_MAXIMIZE; if (window->shaded) ops |= META_MENU_OP_UNSHADE; @@ -2981,13 +2999,19 @@ meta_window_show_menu (MetaWindow *window, ops |= META_MENU_OP_UNSTICK; else ops |= META_MENU_OP_STICK; - + + if (!window->has_maximize_func) + insensitive |= META_MENU_OP_UNMAXIMIZE | META_MENU_OP_MAXIMIZE; + if (!window->has_minimize_func) insensitive |= META_MENU_OP_MINIMIZE; if (!window->has_close_func) insensitive |= META_MENU_OP_DELETE; + if (!window->has_shade_func) + insensitive |= META_MENU_OP_SHADE | META_MENU_OP_UNSHADE; + menu = meta_ui_window_menu_new (window->screen->ui, window->xwindow, diff --git a/src/window.h b/src/window.h index 5292ef66e..fa103736b 100644 --- a/src/window.h +++ b/src/window.h @@ -104,13 +104,11 @@ struct _MetaWindow /* Globally active / No input */ guint input : 1; - /* MWM hints */ + /* Features of window */ guint decorated : 1; guint has_close_func : 1; guint has_minimize_func : 1; guint has_maximize_func : 1; - - /* similar hints */ guint has_shade_func : 1; /* Weird "_NET_WM_STATE_MODAL" flag */