changeset 103665:340c701162a6

* emacs.c (USAGE3, standard_args): Add -mm and --maximized. * frame.c: Qmaximized is new. (x_set_frame_parameters): Do not handle fullscreen specially. Only set width and height if explicitly set. (x_set_fullscreen): Handle Qmaximized. (x_set_font, x_figure_window_size): Do not handle fullscreen specially. (syms_of_frame): Initialize Qmaximized. * frame.h (fullscreen_type): Add FULLSCREEN_MAXIMIZED. Declare Qfullwidth, Qfullheight, Qfullboth, Qmaximized. * xterm.c (handle_one_xevent): Remove call to x_check_fullscreen for Expose event. Add call to x_check_fullscreen for MapNotify event. Remove all code w.r.t. fullscreen from ConfigureNotify event. Do not set gravity to NorthWestGravity when USE_GTK. (set_wm_state): New function. (do_ewmh_fullscreen): Use set_wm_state. Also handle FULLSCREEN_MAXIMIZED. (x_handle_net_wm_state): Handle FULLSCREEN_MAXIMIZED. (x_check_fullscreen): Simplify so we only handle EMWH type of fullscreen or the case when no window manager is running. That means remove calls to x_real_positions and x_fullscreen_adjust. * gtkutil.c (flush_and_sync, x_wm_size_hint_off): Remove. (xg_frame_set_char_size): Remove calls to x_wm_size_hint_off and flush_and_sync. (xg_height_changed): New function. (xg_create_frame_widgets): Remove call to gtk_widget_set_size_request and gtk_window_set_policy. Set frame gravity after parsing the geometry string. (xg_update_frame_menubar, free_frame_menubar) (xg_tool_bar_detach_callback, xg_tool_bar_attach_callback) (update_frame_tool_bar, free_frame_tool_bar): Call xg_height_changed. Remove calls to xg_frame_set_char_size. * startup.el (command-line-x-option-alist): Add -mm and --maximized. * NEWS: Mention maximized. * frames.texi (Size Parameters): Mention maximized for fullscreen. * xresources.texi (Table of Resources): Mention maximized for fullscreen. * cmdargs.texi (Window Size X): -mm/--maximized is new.
author Jan Djärv <jan.h.d@swipnet.se>
date Wed, 01 Jul 2009 14:02:27 +0000
parents fa336161482c
children 3337a01621b2
files doc/emacs/ChangeLog doc/emacs/cmdargs.texi doc/emacs/xresources.texi doc/lispref/ChangeLog doc/lispref/frames.texi etc/ChangeLog etc/NEWS lisp/ChangeLog lisp/startup.el src/ChangeLog src/emacs.c src/frame.c src/frame.h src/gtkutil.c src/xterm.c
diffstat 15 files changed, 231 insertions(+), 274 deletions(-) [+]
line wrap: on
line diff
--- a/doc/emacs/ChangeLog	Wed Jul 01 13:03:45 2009 +0000
+++ b/doc/emacs/ChangeLog	Wed Jul 01 14:02:27 2009 +0000
@@ -1,3 +1,10 @@
+2009-07-01  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* xresources.texi (Table of Resources): Mention maximized for
+	fullscreen.
+
+	* cmdargs.texi (Window Size X): -mm/--maximized is new.
+
 2009-07-01  Chong Yidong  <cyd@stupidchicken.com>
 
 	* anti.texi (Antinews): Correct the list of removed platforms.
--- a/doc/emacs/cmdargs.texi	Wed Jul 01 13:03:45 2009 +0000
+++ b/doc/emacs/cmdargs.texi	Wed Jul 01 14:02:27 2009 +0000
@@ -1184,7 +1184,16 @@
 @itemx --fullscreen
 @opindex --fullscreen
 @cindex fullscreen, command-line argument
-Specify that width and height shall be the size of the screen.
+Specify that width and height shall be the size of the screen. Normally
+no window manager decorations are shown.
+
+@item -mm
+@opindex -mm
+@itemx --maximized
+@opindex --maximized
+@cindex maximized, command-line argument
+Specify that the Emacs frame shall be maximized.  This normally
+means that the frame has window manager decorations.
 
 @item -fh
 @opindex -fh
@@ -1258,8 +1267,8 @@
 (@pxref{Table of Resources}); then Emacs will already know there's no
 tool bar when it processes the specified geometry.
 
-  When using one of @samp{--fullscreen}, @samp{--fullwidth} or
-@samp{--fullheight} there may be some space around the frame
+  When using one of @samp{--fullscreen}, @samp{--maximized}, @samp{--fullwidth}
+or @samp{--fullheight} there may be some space around the frame
 anyway.  That is because Emacs rounds the sizes so they are an
 even number of character heights and widths.
 
--- a/doc/emacs/xresources.texi	Wed Jul 01 13:03:45 2009 +0000
+++ b/doc/emacs/xresources.texi	Wed Jul 01 14:02:27 2009 +0000
@@ -217,8 +217,8 @@
 @ifnottex
 @item @code{fullscreen} (class @code{Fullscreen})
 The desired fullscreen size.  The value can be one of @code{fullboth},
-@code{fullwidth} or @code{fullheight}, which correspond to
-the command-line options @samp{-fs}, @samp{-fw}, and @samp{-fh}
+@code{maximized}, @code{fullwidth} or @code{fullheight}, which correspond to
+the command-line options @samp{-fs}, @samp{-mm}, @samp{-fw}, and @samp{-fh}
 (@pxref{Window Size X}).
 
 Note that this applies to the initial frame only.
--- a/doc/lispref/ChangeLog	Wed Jul 01 13:03:45 2009 +0000
+++ b/doc/lispref/ChangeLog	Wed Jul 01 14:02:27 2009 +0000
@@ -1,3 +1,7 @@
+2009-07-01  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* frames.texi (Size Parameters): Mention maximized for fullscreen.
+
 2009-06-24  Chong Yidong  <cyd@stupidchicken.com>
 
 	* display.texi (Window Systems): Add ns to the list.
--- a/doc/lispref/frames.texi	Wed Jul 01 13:03:45 2009 +0000
+++ b/doc/lispref/frames.texi	Wed Jul 01 14:02:27 2009 +0000
@@ -609,11 +609,15 @@
 parameters @code{top} and @code{left}.
 
 @item fullscreen
-Specify that width, height or both shall be set to the size of the screen.
-The value @code{fullwidth} specifies that width shall be the size of the
-screen.  The value @code{fullheight} specifies that height shall be the
-size of the screen.  The value @code{fullboth} specifies that both the
+Specify that width, height or both shall be maximized.
+The value @code{fullwidth} specifies that width shall as wide as possible.
+The value @code{fullheight} specifies that height shall be as tall as
+possible.  The value @code{fullboth} specifies that both the
 width and the height shall be set to the size of the screen.
+The value @code{maximized} specifies that the frame shall be maximized.
+The difference between @code{maximized} and @code{fullboth} is that
+the first does have window manager decorations but the second does not
+and thus really covers the whole screen.
 @end table
 
 @node Layout Parameters
--- a/etc/ChangeLog	Wed Jul 01 13:03:45 2009 +0000
+++ b/etc/ChangeLog	Wed Jul 01 14:02:27 2009 +0000
@@ -1,3 +1,7 @@
+2009-07-01  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* NEWS: Mention maximized.
+
 2009-06-30  Michael Albinus  <michael.albinus@gmx.de>
 
 	* NEWS: Add "synce" connection method of Tramp.
--- a/etc/NEWS	Wed Jul 01 13:03:45 2009 +0000
+++ b/etc/NEWS	Wed Jul 01 14:02:27 2009 +0000
@@ -30,6 +30,11 @@
 KDE, and XFCE desktops.  (This change has no effect on Windows, which
 uses `system-move-file-to-trash' for trashing.)
 
++++
+** Emacs frames can be maximized.
+The command line arguments -mm/--maximized and the value maximized to the
+frame parameter fullscreen makes the Emacs frame maximized.
+
 
 * Changes in Specialized Modes and Packages in Emacs 23.2
 
--- a/lisp/ChangeLog	Wed Jul 01 13:03:45 2009 +0000
+++ b/lisp/ChangeLog	Wed Jul 01 14:02:27 2009 +0000
@@ -1,3 +1,7 @@
+2009-07-01  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* startup.el (command-line-x-option-alist): Add -mm and --maximized.
+
 2009-07-01  Eduard Wiebe  <usenet@pusto.de>  (tiny change)
 
 	* language/korean.el (set-language-info-alist): Add korean-cp949,
--- a/lisp/startup.el	Wed Jul 01 13:03:45 2009 +0000
+++ b/lisp/startup.el	Wed Jul 01 14:02:27 2009 +0000
@@ -134,6 +134,7 @@
     ("-fs" 0 x-handle-initial-switch fullscreen fullboth)
     ("-fw" 0 x-handle-initial-switch fullscreen fullwidth)
     ("-fh" 0 x-handle-initial-switch fullscreen fullheight)
+    ("-mm" 0 x-handle-initial-switch fullscreen maximized)
     ("-ib" 1 x-handle-numeric-switch internal-border-width)
     ("-g" 1 x-handle-geometry)
     ("-lsp" 1 x-handle-numeric-switch line-spacing)
@@ -159,6 +160,7 @@
     ("--fullscreen" 0 x-handle-initial-switch fullscreen fullboth)
     ("--fullwidth" 0 x-handle-initial-switch fullscreen fullwidth)
     ("--fullheight" 0 x-handle-initial-switch fullscreen fullheight)
+    ("--maximized" 0 x-handle-initial-switch fullscreen maximized)
     ("--internal-border" 1 x-handle-numeric-switch internal-border-width)
     ("--geometry" 1 x-handle-geometry)
     ("--foreground-color" 1 x-handle-switch foreground-color)
--- a/src/ChangeLog	Wed Jul 01 13:03:45 2009 +0000
+++ b/src/ChangeLog	Wed Jul 01 14:02:27 2009 +0000
@@ -1,3 +1,40 @@
+2009-07-01  Jan Djärv  <jan.h.d@swipnet.se>
+
+	* emacs.c (USAGE3, standard_args): Add -mm and --maximized.
+
+	* frame.c: Qmaximized is new.
+	(x_set_frame_parameters): Do not handle fullscreen specially.
+	Only set width and height if explicitly set.
+	(x_set_fullscreen): Handle Qmaximized.
+	(x_set_font, x_figure_window_size): Do not handle fullscreen specially.
+	(syms_of_frame): Initialize Qmaximized.
+
+	* frame.h (fullscreen_type): Add FULLSCREEN_MAXIMIZED.  Declare
+	Qfullwidth, Qfullheight, Qfullboth, Qmaximized.
+
+	* xterm.c (handle_one_xevent): Remove call to x_check_fullscreen
+	for Expose event. Add call to x_check_fullscreen for MapNotify event.
+	Remove all code w.r.t. fullscreen from ConfigureNotify event. Do not
+	set gravity to NorthWestGravity when USE_GTK.
+	(set_wm_state): New function.
+	(do_ewmh_fullscreen): Use set_wm_state. Also handle FULLSCREEN_MAXIMIZED.
+	(x_handle_net_wm_state): Handle FULLSCREEN_MAXIMIZED.
+	(x_check_fullscreen): Simplify so we only handle EMWH type of fullscreen
+	or the case when no window manager is running. That means remove calls
+	to x_real_positions and x_fullscreen_adjust.
+
+	* gtkutil.c (flush_and_sync, x_wm_size_hint_off): Remove.
+	(xg_frame_set_char_size): Remove calls to x_wm_size_hint_off and
+	flush_and_sync.
+	(xg_height_changed): New function.
+	(xg_create_frame_widgets): Remove call to gtk_widget_set_size_request
+	and gtk_window_set_policy.  Set frame gravity after parsing the geometry
+	string.
+	(xg_update_frame_menubar, free_frame_menubar)
+	(xg_tool_bar_detach_callback, xg_tool_bar_attach_callback)
+	(update_frame_tool_bar, free_frame_tool_bar): Call xg_height_changed.
+	Remove calls to xg_frame_set_char_size.
+
 2009-07-01  Kenichi Handa  <handa@m17n.org>
 
 	* keyboard.c (decode_keyboard_code): New function.
--- a/src/emacs.c	Wed Jul 01 13:03:45 2009 +0000
+++ b/src/emacs.c	Wed Jul 01 14:02:27 2009 +0000
@@ -321,6 +321,7 @@
 --fullheight, -fh               make the first frame high as the screen\n\
 --fullscreen, -fs               make first frame fullscreen\n\
 --fullwidth, -fw                make the first frame wide as the screen\n\
+--maximized, -mm                make the first frame maximized\n\
 --geometry, -g GEOMETRY         window geometry\n\
 --no-bitmap-icon, -nbi          do not use picture of gnu for Emacs icon\n\
 --iconic                        start Emacs in iconified state\n\
@@ -1917,6 +1918,7 @@
   { "-fs", "--fullscreen", 10, 0 },
   { "-fw", "--fullwidth", 10, 0 },
   { "-fh", "--fullheight", 10, 0 },
+  { "-mm", "--maximized", 10, 0 },
   { "-g", "--geometry", 10, 1 },
   { "-geometry", 0, 10, 1 },
   { "-T", "--title", 10, 1 },
--- a/src/frame.c	Wed Jul 01 13:03:45 2009 +0000
+++ b/src/frame.c	Wed Jul 01 14:02:27 2009 +0000
@@ -120,7 +120,7 @@
 Lisp_Object Qtty_color_mode;
 Lisp_Object Qtty, Qtty_type;
 
-Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth;
+Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth, Qmaximized;
 Lisp_Object Qfont_backend;
 Lisp_Object Qalpha;
 
@@ -2930,11 +2930,7 @@
   int i, p;
   int left_no_change = 0, top_no_change = 0;
   int icon_left_no_change = 0, icon_top_no_change = 0;
-  int fullscreen_is_being_set = 0;
-  int height_for_full_width = 0;
-  int width_for_full_height = 0;
-  enum fullscreen_type fullscreen_wanted = FULLSCREEN_NONE;
-
+  int size_changed = 0;
   struct gcpro gcpro1, gcpro2;
 
   i = 0;
@@ -2976,7 +2972,6 @@
      They are independent of other properties, but other properties (e.g.,
      cursor_color) are dependent upon them.  */
   /* Process default font as well, since fringe widths depends on it.  */
-  /* Also, process fullscreen, width and height depend upon that.  */
   for (p = 0; p < i; p++)
     {
       Lisp_Object prop, val;
@@ -2985,26 +2980,11 @@
       val = values[p];
       if (EQ (prop, Qforeground_color)
 	  || EQ (prop, Qbackground_color)
-	  || EQ (prop, Qfont)
-          || EQ (prop, Qfullscreen))
+	  || EQ (prop, Qfont))
 	{
 	  register Lisp_Object param_index, old_value;
 
-	  if (EQ (prop, Qfullscreen))
-	    {
-	      /* The parameter handler can reset f->want_fullscreen to
-	         FULLSCREEN_NONE.  But we need the requested value later
-	         to decide whether a height or width parameter shall be
-	         applied.  Therefore, we remember the requested value in
-	         fullscreen_wanted for the following two cases.  */ 
-	      if (EQ (val, Qfullheight))
-		fullscreen_wanted = FULLSCREEN_HEIGHT;
-	      else if (EQ (val, Qfullwidth))
-		fullscreen_wanted = FULLSCREEN_WIDTH;
-	    }
-
 	  old_value = get_frame_param (f, prop);
- 	  fullscreen_is_being_set |= EQ (prop, Qfullscreen);
 	  if (NILP (Fequal (val, old_value)))
 	    {
 	      store_frame_param (f, prop, val);
@@ -3028,9 +3008,15 @@
       val = values[i];
 
       if (EQ (prop, Qwidth) && NATNUMP (val))
-	width_for_full_height = width = XFASTINT (val);
+        {
+          size_changed = 1;
+          width = XFASTINT (val);
+        }
       else if (EQ (prop, Qheight) && NATNUMP (val))
-	height_for_full_width = height = XFASTINT (val);
+        {
+          size_changed = 1;
+          height = XFASTINT (val);
+        }
       else if (EQ (prop, Qtop))
 	top = val;
       else if (EQ (prop, Qleft))
@@ -3041,8 +3027,7 @@
 	icon_left = val;
       else if (EQ (prop, Qforeground_color)
 	       || EQ (prop, Qbackground_color)
-	       || EQ (prop, Qfont)
-               || EQ (prop, Qfullscreen))
+	       || EQ (prop, Qfont))
 	/* Processed above.  */
 	continue;
       else
@@ -3096,31 +3081,6 @@
 	XSETINT (icon_top, 0);
     }
 
-  if (FRAME_VISIBLE_P (f) && fullscreen_is_being_set)
-    {
-      /* If the frame is visible already and the fullscreen parameter is
-         being set, it is too late to set WM manager hints to specify
-         size and position.
-         Here we first get the width, height and position that applies to
-         fullscreen.  We then move the frame to the appropriate
-         position.  Resize of the frame is taken care of in the code after
-         this if-statement. */
-      int new_left, new_top;
-
-      x_fullscreen_adjust (f, &width, &height, &new_top, &new_left);
-      if (new_top != f->top_pos || new_left != f->left_pos)
-        x_set_offset (f, new_left, new_top, 1);
-
-      /* When both height and fullwidth were requested, make sure the
-	 requested value for height gets applied.  */
-      if (height_for_full_width && fullscreen_wanted == FULLSCREEN_WIDTH)
-	height = height_for_full_width;
-      /* When both width and fullheight were requested, make sure the
-	 requested value for width gets applied.  */
-      if (width_for_full_height && fullscreen_wanted == FULLSCREEN_HEIGHT)
-	width = width_for_full_height;
-    }
-
   /* Don't set these parameters unless they've been explicitly
      specified.  The window might be mapped or resized while we're in
      this function, and we don't want to override that unless the lisp
@@ -3136,10 +3096,11 @@
 
     XSETFRAME (frame, f);
 
-    if (width != FRAME_COLS (f)
-	|| height != FRAME_LINES (f)
-	|| f->new_text_lines || f->new_text_cols)
-      Fset_frame_size (frame, make_number (width), make_number (height));
+    if (size_changed
+        && (width != FRAME_COLS (f)
+            || height != FRAME_LINES (f)
+            || f->new_text_lines || f->new_text_cols))
+        Fset_frame_size (frame, make_number (width), make_number (height));
 
     if ((!NILP (left) || !NILP (top))
 	&& ! (left_no_change && top_no_change)
@@ -3299,12 +3260,14 @@
 {
   if (NILP (new_value))
     f->want_fullscreen = FULLSCREEN_NONE;
-  else if (EQ (new_value, Qfullboth))
+  else if (EQ (new_value, Qfullboth) || EQ (new_value, Qfullscreen))
     f->want_fullscreen = FULLSCREEN_BOTH;
   else if (EQ (new_value, Qfullwidth))
     f->want_fullscreen = FULLSCREEN_WIDTH;
   else if (EQ (new_value, Qfullheight))
     f->want_fullscreen = FULLSCREEN_HEIGHT;
+  else if (EQ (new_value, Qmaximized))
+    f->want_fullscreen = FULLSCREEN_MAXIMIZED;
 
   if (FRAME_TERMINAL (f)->fullscreen_hook != NULL)
     FRAME_TERMINAL (f)->fullscreen_hook (f);
@@ -3443,19 +3406,6 @@
   if (CONSP (lval)) lval = CDR (lval);
 
   x_new_font (f, font_object, fontset);
-  /* If the fullscreen property is non-nil, adjust lines and columns so we
-     keep the same pixel height and width.  */
-  if (! NILP (lval))
-    {
-      int height = FRAME_LINES (f), width = FRAME_COLS (f);
-      if (EQ (lval, Qfullboth) || EQ (lval, Qfullwidth))
-        width = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, FRAME_PIXEL_WIDTH (f));
-      if (EQ (lval, Qfullboth) || EQ (lval, Qfullheight))
-        height = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, FRAME_PIXEL_HEIGHT (f));
-      
-      change_frame_size (f, height, width, 0, 0, 1);
-    }
-
   store_frame_param (f, Qfont, arg);
   /* Recalculate toolbar height.  */
   f->n_tool_bar_rows = 0;
@@ -4374,22 +4324,6 @@
 	window_prompting |= PPosition;
     }
 
-  if (f->want_fullscreen != FULLSCREEN_NONE)
-    {
-      int left, top;
-      int width, height;
-
-      /* It takes both for some WM:s to place it where we want */
-      window_prompting |= USPosition | PPosition;
-      x_fullscreen_adjust (f, &width, &height, &top, &left);
-      FRAME_COLS (f) = width;
-      FRAME_LINES (f) = height;
-      FRAME_PIXEL_WIDTH (f) = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, width);
-      FRAME_PIXEL_HEIGHT (f) = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, height);
-      f->left_pos = left;
-      f->top_pos = top;
-    }
-
   if (window_prompting & XNegative)
     {
       if (window_prompting & YNegative)
@@ -4503,6 +4437,8 @@
   staticpro (&Qfullheight);
   Qfullboth = intern ("fullboth");
   staticpro (&Qfullboth);
+  Qmaximized = intern ("maximized");
+  staticpro (&Qmaximized);
   Qx_resource_name = intern ("x-resource-name");
   staticpro (&Qx_resource_name);
 
--- a/src/frame.h	Wed Jul 01 13:03:45 2009 +0000
+++ b/src/frame.h	Wed Jul 01 14:02:27 2009 +0000
@@ -75,12 +75,12 @@
 
 enum fullscreen_type
 {
-  /* Values used as a bit mask, BOTH == WIDTH | HEIGHT.  */
-  FULLSCREEN_NONE       = 0,
-  FULLSCREEN_WIDTH      = 1,
-  FULLSCREEN_HEIGHT     = 2,
-  FULLSCREEN_BOTH       = 3,
-  FULLSCREEN_WAIT       = 4
+  FULLSCREEN_NONE,
+  FULLSCREEN_WIDTH     = 0x001,
+  FULLSCREEN_HEIGHT    = 0x002,
+  FULLSCREEN_BOTH      = 0x003,
+  FULLSCREEN_MAXIMIZED = 0x013,
+  FULLSCREEN_WAIT      = 0x100
 };
 
 
@@ -1038,6 +1038,7 @@
 extern Lisp_Object Qline_spacing;
 extern Lisp_Object Qwait_for_wm;
 extern Lisp_Object Qfullscreen;
+extern Lisp_Object Qfullwidth, Qfullheight, Qfullboth, Qmaximized;
 extern Lisp_Object Qfont_backend;
 extern Lisp_Object Qalpha;
 
--- a/src/gtkutil.c	Wed Jul 01 13:03:45 2009 +0000
+++ b/src/gtkutil.c	Wed Jul 01 14:02:27 2009 +0000
@@ -308,7 +308,7 @@
 }
 
 static Lisp_Object
-file_for_image(image)
+file_for_image (image)
      Lisp_Object image;
 {
   Lisp_Object specified_file = Qnil;
@@ -655,48 +655,6 @@
     }
 }
 
-/* Process all pending events on the display for frame F.  */
-
-static void
-flush_and_sync (f)
-     FRAME_PTR f;
-{
-  gdk_window_process_all_updates ();
-  x_sync (f);
-  while (gtk_events_pending ())
-    {
-      gtk_main_iteration ();
-      gdk_window_process_all_updates ();
-      x_sync (f);
-    }
-}
-
-/* Turn wm hints for resize off on frame F */
-
-static void
-x_wm_size_hint_off (f)
-     FRAME_PTR f;
-{
-  GdkGeometry size_hints;
-  gint hint_flags = 0;
-  memset (&size_hints, 0, sizeof (size_hints));
-  hint_flags |= GDK_HINT_RESIZE_INC | GDK_HINT_MIN_SIZE;
-  size_hints.width_inc = 1;
-  size_hints.height_inc = 1;
-  hint_flags |= GDK_HINT_BASE_SIZE;
-  size_hints.base_width = 1;
-  size_hints.base_height = 1;
-  size_hints.min_width  = 1;
-  size_hints.min_height = 1;
-  gtk_window_set_geometry_hints (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
-                                 NULL,
-                                 &size_hints,
-                                 hint_flags);
-  /* Make sure these get set again in next call to x_wm_set_size_hint. */
-  f->output_data.x->hint_flags &= ~hint_flags;
-  flush_and_sync (f);
-}
-
 /* Resize the outer window of frame F after chainging the height.
    This happend when the menu bar or the tool bar is added or removed.
    COLUMNS/ROWS is the size the edit area shall have after the resize.  */
@@ -729,13 +687,10 @@
   pixelwidth = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, cols);
 
   /* Must resize our top level widget.  Font size may have changed,
-     but not rows/cols.
-     Turn wm hints (min/max size and size increments) of temporarly.
-     It interferes too much, when for example adding or removing the
-     menu/tool bar.  */
-  x_wm_size_hint_off (f);
+     but not rows/cols.  */
   gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
                      pixelwidth, pixelheight);
+  x_wm_set_size_hint (f, 0, 0);
 
   /* Now, strictly speaking, we can't be sure that this is accurate,
      but the window manager will get around to dealing with the size
@@ -759,7 +714,18 @@
      for, then the event won't cause the screen to become garbaged, so
      we have to make sure to do it here.  */
   SET_FRAME_GARBAGED (f);
-  flush_and_sync (f);
+}
+
+/* Handle height changes (i.e. add/remove menu/toolbar).
+   The policy is to keep the number of editable lines.  */
+
+static void
+xg_height_changed (f)
+     FRAME_PTR f;
+{
+  gtk_window_resize (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)),
+                     FRAME_PIXEL_WIDTH (f), FRAME_TOTAL_PIXEL_HEIGHT (f));
+  f->output_data.x->hint_flags = 0;
   x_wm_set_size_hint (f, 0, 0);
 }
 
@@ -859,9 +825,6 @@
 
   gtk_fixed_set_has_window (GTK_FIXED (wfixed), TRUE);
 
-  gtk_widget_set_size_request (wfixed, FRAME_PIXEL_WIDTH (f),
-                               FRAME_PIXEL_HEIGHT (f));
-
   gtk_container_add (GTK_CONTAINER (wtop), wvbox);
   gtk_box_pack_end (GTK_BOX (wvbox), wfixed, TRUE, TRUE, 0);
 
@@ -875,9 +838,6 @@
      a lot, so we turn off double buffering.  */
   gtk_widget_set_double_buffered (wfixed, FALSE);
 
-  /* GTK documents says use gtk_window_set_resizable.  But then a user
-     can't shrink the window from its starting size.  */
-  gtk_window_set_policy (GTK_WINDOW (wtop), TRUE, TRUE, TRUE);
   gtk_window_set_wmclass (GTK_WINDOW (wtop),
                           SSDATA (Vx_resource_name),
                           SSDATA (Vx_resource_class));
@@ -891,6 +851,8 @@
      and specify it.
      GTK will itself handle calculating the real position this way.  */
   xg_set_geometry (f);
+  int grav = gtk_window_get_gravity (GTK_WINDOW (FRAME_GTK_OUTER_WIDGET (f)));
+  f->win_gravity = grav;
 
   gtk_widget_add_events (wfixed,
                          GDK_POINTER_MOTION_MASK
@@ -2987,14 +2949,8 @@
 
   gtk_widget_show_all (x->menubar_widget);
   gtk_widget_size_request (x->menubar_widget, &req);
-
   FRAME_MENUBAR_HEIGHT (f) = req.height;
-
-  /* The height has changed, resize outer widget and set columns
-     rows to what we had before adding the menu bar.  */
-  xg_frame_set_char_size (f, FRAME_COLS (f), FRAME_LINES (f));
-
-  SET_FRAME_GARBAGED (f);
+  xg_height_changed (f);
   UNBLOCK_INPUT;
 
   return 1;
@@ -3018,12 +2974,7 @@
           the container.  */
       x->menubar_widget = 0;
       FRAME_MENUBAR_HEIGHT (f) = 0;
-
-      /* The height has changed, resize outer widget and set columns
-         rows to what we had before removing the menu bar.  */
-      xg_frame_set_char_size (f, FRAME_COLS (f), FRAME_LINES (f));
-
-      SET_FRAME_GARBAGED (f);
+      xg_height_changed (f);
       UNBLOCK_INPUT;
     }
 }
@@ -3627,11 +3578,8 @@
       /* When detaching a tool bar, not everything dissapear.  There are
          a few pixels left that are used to drop the tool bar back into
          place.  */
-      FRAME_TOOLBAR_HEIGHT (f) = 2;
-
-      /* The height has changed, resize outer widget and set columns
-         rows to what we had before detaching the tool bar.  */
-      xg_frame_set_char_size (f, FRAME_COLS (f), FRAME_LINES (f));
+      FRAME_TOOLBAR_HEIGHT (f) = 4;
+      xg_height_changed (f);
     }
 }
 
@@ -3659,10 +3607,7 @@
 
       gtk_widget_size_request (w, &req);
       FRAME_TOOLBAR_HEIGHT (f) = req.height;
-
-      /* The height has changed, resize outer widget and set columns
-         rows to what we had before attaching the tool bar.  */
-      xg_frame_set_char_size (f, FRAME_COLS (f), FRAME_LINES (f));
+      xg_height_changed (f);
     }
 }
 
@@ -4149,20 +4094,17 @@
     } while (ti != NULL);
 
   new_req.height = 0;
-  gtk_widget_size_request (GTK_WIDGET (wtoolbar), &new_req);
-
   if (pack_tool_bar && f->n_tool_bar_items != 0)
-    xg_pack_tool_bar (f);
-
-  if (new_req.height != 0
-      && f->n_tool_bar_items != 0
-      && old_req.height != new_req.height
+      xg_pack_tool_bar (f);
+  
+
+  gtk_widget_size_request (GTK_WIDGET (x->toolbar_widget), &new_req);
+  if (old_req.height != new_req.height
       && ! FRAME_X_OUTPUT (f)->toolbar_detached)
     {
       FRAME_TOOLBAR_HEIGHT (f) = new_req.height;
-      xg_frame_set_char_size (f, FRAME_COLS (f), FRAME_LINES (f));
+      xg_height_changed (f);
     }
-
   UNBLOCK_INPUT;
 }
 
@@ -4190,10 +4132,8 @@
       x->toolbar_widget = 0;
       x->handlebox_widget = 0;
       FRAME_TOOLBAR_HEIGHT (f) = 0;
-
-      /* The height has changed, resize outer widget and set columns
-         rows to what we had before removing the tool bar.  */
-      xg_frame_set_char_size (f, FRAME_COLS (f), FRAME_LINES (f));
+      xg_height_changed (f);
+
       UNBLOCK_INPUT;
     }
 }
--- a/src/xterm.c	Wed Jul 01 13:03:45 2009 +0000
+++ b/src/xterm.c	Wed Jul 01 14:02:27 2009 +0000
@@ -6059,8 +6059,6 @@
       f = x_window_to_frame (dpyinfo, event.xexpose.window);
       if (f)
         {
-          x_check_fullscreen (f);
-
 #ifdef USE_GTK
           /* This seems to be needed for GTK 2.6.  */
           x_clear_area (event.xexpose.display,
@@ -6205,6 +6203,9 @@
                to update the frame titles
                in case this is the second frame.  */
             record_asynch_buffer_change ();
+
+          /* Check if fullscreen was specified before we where mapped. */
+          x_check_fullscreen (f);
         }
       goto OTHER;
 
@@ -6705,19 +6706,9 @@
         {
 #ifndef USE_X_TOOLKIT
 #ifndef USE_GTK
-          /* If there is a pending resize for fullscreen, don't
-             do this one, the right one will come later.
-             The toolkit version doesn't seem to need this, but we
-             need to reset it below.  */
-          int dont_resize
-	    = ((f->want_fullscreen & FULLSCREEN_WAIT)
-	       && f->new_text_cols != 0);
           int rows = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, event.xconfigure.height);
           int columns = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, event.xconfigure.width);
 
-          if (dont_resize)
-            goto OTHER;
-
           /* In the toolkit version, change_frame_size
              is called by the code that handles resizing
              of the EmacsFrame widget.  */
@@ -6748,9 +6739,6 @@
 #endif
             {
 	      x_real_positions (f, &f->left_pos, &f->top_pos);
-
-	      if (f->want_fullscreen & FULLSCREEN_WAIT)
-		f->want_fullscreen &= ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
             }
 
 #ifdef HAVE_X_I18N
@@ -6758,6 +6746,7 @@
             xic_set_statusarea (f);
 #endif
 
+#ifndef USE_GTK
           if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
             {
               /* Since the WM decorations come below top_pos now,
@@ -6765,6 +6754,7 @@
               f->win_gravity = NorthWestGravity;
               x_wm_set_size_hint (f, (long) 0, 0);
             }
+#endif
         }
       goto OTHER;
 
@@ -8444,6 +8434,28 @@
   return rc;
 }
 
+static void
+set_wm_state (frame, add, what, what2)
+     Lisp_Object frame;
+     int add;
+     const char *what;
+     const char *what2;
+{
+  const char *atom = "_NET_WM_STATE";
+  Fx_send_client_event (frame, make_number (0), frame,
+                        make_unibyte_string (atom, strlen (atom)),
+                        make_number (32),
+                        /* 1 = add, 0 = remove */
+                        Fcons
+                        (make_number (add ? 1 : 0),
+                         Fcons
+                         (make_unibyte_string (what, strlen (what)),
+                          what2 != 0
+                          ? Fcons (make_unibyte_string (what2, strlen (what2)),
+                                   Qnil)
+                          : Qnil)));
+}
+
 /* Do fullscreen as specified in extended window manager hints */
 
 static int
@@ -8460,66 +8472,36 @@
   if (have_net_atom)
     {
       Lisp_Object frame;
-      const char *atom = "_NET_WM_STATE";
       const char *fs = "_NET_WM_STATE_FULLSCREEN";
       const char *fw = "_NET_WM_STATE_MAXIMIZED_HORZ";
       const char *fh = "_NET_WM_STATE_MAXIMIZED_VERT";
-      const char *what = NULL;
 
       XSETFRAME (frame, f);
 
+      set_wm_state (frame, 0, fs, NULL);
+      set_wm_state (frame, 0, fh, NULL);
+      set_wm_state (frame, 0, fw, NULL);
+      
       /* If there are _NET_ atoms we assume we have extended window manager
          hints.  */
       switch (f->want_fullscreen)
         {
         case FULLSCREEN_BOTH:
-          what = fs;
+          set_wm_state (frame, 1, fs, NULL);
           break;
         case FULLSCREEN_WIDTH:
-          what = fw;
+          set_wm_state (frame, 1, fw, NULL);
           break;
         case FULLSCREEN_HEIGHT:
-          what = fh;
+          set_wm_state (frame, 1, fh, NULL);
+          break;
+        case FULLSCREEN_MAXIMIZED:
+          set_wm_state (frame, 1, fw, fh);
           break;
         }
 
-      if (what != NULL && !wm_supports (f, what)) return 0;
-
-
-      Fx_send_client_event (frame, make_number (0), frame,
-                            make_unibyte_string (atom, strlen (atom)),
-                            make_number (32),
-                            Fcons (make_number (0), /* Remove */
-                                   Fcons
-                                   (make_unibyte_string (fs,
-                                                         strlen (fs)),
-                                    Qnil)));
-      Fx_send_client_event (frame, make_number (0), frame,
-                            make_unibyte_string (atom, strlen (atom)),
-                            make_number (32),
-                            Fcons (make_number (0), /* Remove */
-                                   Fcons
-                                   (make_unibyte_string (fh,
-                                                         strlen (fh)),
-                                    Qnil)));
-      Fx_send_client_event (frame, make_number (0), frame,
-                            make_unibyte_string (atom, strlen (atom)),
-                            make_number (32),
-                            Fcons (make_number (0), /* Remove */
-                                   Fcons
-                                   (make_unibyte_string (fw,
-                                                         strlen (fw)),
-                                    Qnil)));
       f->want_fullscreen = FULLSCREEN_NONE;
-      if (what != NULL)
-        Fx_send_client_event (frame, make_number (0), frame,
-                              make_unibyte_string (atom, strlen (atom)),
-                              make_number (32),
-                              Fcons (make_number (1), /* Add */
-                                     Fcons
-                                     (make_unibyte_string (what,
-                                                           strlen (what)),
-                                      Qnil)));
+
     }
 
   return have_net_atom;
@@ -8532,14 +8514,13 @@
   if (f->async_visible)
     {
       BLOCK_INPUT;
-      do_ewmh_fullscreen (f);
+      x_check_fullscreen (f);
       x_sync (f);
       UNBLOCK_INPUT;
     }
 }
 
 
-extern Lisp_Object Qfullwidth, Qfullheight, Qfullboth;
 static void
 x_handle_net_wm_state (f, event)
      struct frame *f;
@@ -8547,7 +8528,7 @@
 {
   Atom actual_type;
   unsigned long actual_size, bytes_remaining;
-  int i, rc, actual_format, value = 0;
+  int i, rc, actual_format, value = FULLSCREEN_NONE;
   struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
   long max_len = 65536;
   Display *dpy = FRAME_X_DISPLAY (f);
@@ -8575,12 +8556,22 @@
   for (i = 0; i < actual_size; ++i)
     {
       Atom a = ((Atom*)tmp_data)[i];
-      if (a == dpyinfo->Xatom_net_wm_state_maximized_horz)
-        value |= FULLSCREEN_WIDTH;
+      if (a == dpyinfo->Xatom_net_wm_state_maximized_horz) 
+        {
+          if (value == FULLSCREEN_HEIGHT)
+            value = FULLSCREEN_MAXIMIZED;
+          else
+            value = FULLSCREEN_WIDTH;
+        }
       else if (a == dpyinfo->Xatom_net_wm_state_maximized_vert)
-        value |= FULLSCREEN_HEIGHT;
+        {
+          if (value == FULLSCREEN_WIDTH)
+            value = FULLSCREEN_MAXIMIZED;
+          else
+            value = FULLSCREEN_HEIGHT;
+        }
       else if (a == dpyinfo->Xatom_net_wm_state_fullscreen_atom)
-        value |= FULLSCREEN_BOTH;
+        value = FULLSCREEN_BOTH;
     }
 
   lval = Qnil;
@@ -8595,6 +8586,9 @@
     case FULLSCREEN_BOTH:
       lval = Qfullboth;
       break;
+    case FULLSCREEN_MAXIMIZED:
+      lval = Qmaximized;
+      break;
     }
       
   store_frame_param (f, Qfullscreen, lval);
@@ -8609,29 +8603,37 @@
 x_check_fullscreen (f)
      struct frame *f;
 {
-  if (f->want_fullscreen & FULLSCREEN_BOTH)
-    {
-      int width, height, ign;
-
-      if (do_ewmh_fullscreen (f))
-        return;
-
-      x_real_positions (f, &f->left_pos, &f->top_pos);
-
-      x_fullscreen_adjust (f, &width, &height, &ign, &ign);
-
-      /* We do not need to move the window, it shall be taken care of
-         when setting WM manager hints.
-         If the frame is visible already, the position is checked by
-         x_check_expected_move. */
+  if (do_ewmh_fullscreen (f))
+    return;
+
+  if (f->output_data.x->parent_desc != FRAME_X_DISPLAY_INFO (f)->root_window)
+    return; // Only fullscreen without WM or with EWM hints (above).
+
+  if (f->want_fullscreen != FULLSCREEN_NONE)
+    {
+      int width = FRAME_COLS (f), height = FRAME_LINES (f);
+      struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+
+      switch (f->want_fullscreen)
+        {
+          /* No difference between these two when there is no WM */
+        case FULLSCREEN_BOTH:
+        case FULLSCREEN_MAXIMIZED:
+          width = x_display_pixel_width (dpyinfo);
+          height = x_display_pixel_height (dpyinfo);
+          break;
+        case FULLSCREEN_WIDTH:
+          width = x_display_pixel_width (dpyinfo);
+          break;
+        case FULLSCREEN_HEIGHT:
+          height = x_display_pixel_height (dpyinfo);
+        }
+      
       if (FRAME_COLS (f) != width || FRAME_LINES (f) != height)
         {
           change_frame_size (f, height, width, 0, 1, 0);
           SET_FRAME_GARBAGED (f);
           cancel_mouse_face (f);
-
-          /* Wait for the change of frame size to occur */
-          f->want_fullscreen |= FULLSCREEN_WAIT;
         }
     }
 }
@@ -8658,7 +8660,7 @@
   x_real_positions (f, &current_left, &current_top);
 
   if (current_left != expected_left || current_top != expected_top)
-      {
+    {
       /* It's a "Type A" window manager. */
 
       int adjusted_left;
@@ -8677,7 +8679,7 @@
                    adjusted_left, adjusted_top);
 
       x_sync_with_move (f, expected_left, expected_top, 0);
-      }
+    }
   else
     /* It's a "Type B" window manager.  We don't have to adjust the
        frame's position. */