]> code.delx.au - gnu-emacs/blobdiff - src/widget.c
Don't install keyboard hook when debugged on MS-Windows
[gnu-emacs] / src / widget.c
index c4d69407176355c4d76c8534527e0a5a62b9c439..28bb475ddfa769dc300f4e0a8fc598f7bbcc395f 100644 (file)
@@ -1,12 +1,12 @@
 /* The emacs frame widget.
-   Copyright (C) 1992-1993, 2000-2015 Free Software Foundation, Inc.
+   Copyright (C) 1992-1993, 2000-2016 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
 GNU Emacs is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
+the Free Software Foundation, either version 3 of the License, or (at
+your option) any later version.
 
 GNU Emacs is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -29,17 +29,13 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
    */
 
 #include <config.h>
+#include "widget.h"
+
 #include <stdio.h>
 
 #include "lisp.h"
 #include "xterm.h"
-
-#include "keyboard.h"
 #include "frame.h"
-#include "window.h"
-
-#include "dispextern.h"
-#include "blockinput.h"
 
 #include <X11/StringDefs.h>
 #include <X11/IntrinsicP.h>
@@ -50,10 +46,6 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #include <X11/ShellP.h>
 #include "../lwlib/lwlib.h"
 
-#include "character.h"
-#include "font.h"
-
-
 static void EmacsFrameInitialize (Widget request, Widget new, ArgList dum1, Cardinal *dum2);
 static void EmacsFrameDestroy (Widget widget);
 static void EmacsFrameRealize (Widget widget, XtValueMask *mask, XSetWindowAttributes *attrs);
@@ -61,10 +53,7 @@ static void EmacsFrameResize (Widget widget);
 static XtGeometryResult EmacsFrameQueryGeometry (Widget widget, XtWidgetGeometry *request, XtWidgetGeometry *result);
 
 
-#undef XtOffset
-#define XtOffset(p_type,field) \
-       ((Cardinal) (((char *) (&(((p_type)0)->field))) - ((char *)0)))
-#define offset(field) XtOffset (EmacsFrame, emacs_frame.field)
+#define offset(field) offsetof (EmacsFrameRec, emacs_frame.field)
 
 static XtResource resources[] = {
   {XtNgeometry, XtCGeometry, XtRString, sizeof (String),
@@ -271,173 +260,32 @@ set_frame_size (EmacsFrame ew)
    */
 
   /* Hairily merged geometry */
-  unsigned int w = FRAME_COLS (ew->emacs_frame.frame);
-  unsigned int h = FRAME_LINES (ew->emacs_frame.frame);
-
+  struct frame *f = ew->emacs_frame.frame;
+  int w = FRAME_COLS (f);
+  int h = FRAME_LINES (f);
   Widget wmshell = get_wm_shell ((Widget) ew);
+  Dimension pixel_width, pixel_height;
   /* Each Emacs shell is now independent and top-level.  */
 
   if (! XtIsSubclass (wmshell, shellWidgetClass)) emacs_abort ();
 
-  /* We don't need this for the moment. The geometry is computed in
-     xfns.c.  */
-#if 0
-  /* If the EmacsFrame doesn't have a geometry but the shell does,
-     treat that as the geometry of the frame.  (Is this bogus?
-     I'm not sure.) */
-  if (ew->emacs_frame.geometry == 0)
-    XtVaGetValues (wmshell, XtNgeometry, &ew->emacs_frame.geometry, NULL);
-
-  /* If the Shell is iconic, then the EmacsFrame is iconic.  (Is
-     this bogus? I'm not sure.) */
-  if (!ew->emacs_frame.iconic)
-    XtVaGetValues (wmshell, XtNiconic, &ew->emacs_frame.iconic, NULL);
-
-
-  {
-    char *geom = 0;
-    XtVaGetValues (app_shell, XtNgeometry, &geom, NULL);
-    if (geom)
-      app_flags = XParseGeometry (geom, &app_x, &app_y, &app_w, &app_h);
-  }
-
-  if (ew->emacs_frame.geometry)
-    frame_flags = XParseGeometry (ew->emacs_frame.geometry,
-                                  &frame_x, &frame_y,
-                                  &frame_w, &frame_h);
-
-  if (first_frame_p)
-    {
-      /* If this is the first frame created:
-         ====================================
-
-         - Use the ApplicationShell's size/position, if specified.
-           (This is "Emacs.geometry", or the "-geometry" command line arg.)
-         - Else use the EmacsFrame's size/position.
-           (This is "*Frame-NAME.geometry")
-
-        - If the AppShell is iconic, the frame should be iconic.
-
-        AppShell comes first so that -geometry always applies to the first
-        frame created, even if there is an "every frame" entry in the
-        resource database.
-       */
-      if (app_flags & (XValue | YValue))
-       {
-         x = app_x; y = app_y;
-         flags |= (app_flags & (XValue | YValue | XNegative | YNegative));
-       }
-      else if (frame_flags & (XValue | YValue))
-       {
-         x = frame_x; y = frame_y;
-         flags |= (frame_flags & (XValue | YValue | XNegative | YNegative));
-       }
-
-      if (app_flags & (WidthValue | HeightValue))
-       {
-         w = app_w; h = app_h;
-         flags |= (app_flags & (WidthValue | HeightValue));
-       }
-      else if (frame_flags & (WidthValue | HeightValue))
-       {
-         w = frame_w; h = frame_h;
-         flags |= (frame_flags & (WidthValue | HeightValue));
-       }
-
-      /* If the AppShell is iconic, then the EmacsFrame is iconic. */
-      if (!ew->emacs_frame.iconic)
-       XtVaGetValues (app_shell, XtNiconic, &ew->emacs_frame.iconic, NULL);
-
-      first_frame_p = False;
-    }
-  else
-    {
-      /* If this is not the first frame created:
-         ========================================
-
-         - use the EmacsFrame's size/position if specified
-         - Otherwise, use the ApplicationShell's size, but not position.
-
-         So that means that one can specify the position of the first frame
-         with "Emacs.geometry" or `-geometry'; but can only specify the
-        position of subsequent frames with "*Frame-NAME.geometry".
-
-        AppShell comes second so that -geometry does not apply to subsequent
-        frames when there is an "every frame" entry in the resource db,
-        but does apply to the first frame.
-       */
-      if (frame_flags & (XValue | YValue))
-       {
-         x = frame_x; y = frame_y;
-         flags |= (frame_flags & (XValue | YValue | XNegative | YNegative));
-       }
-
-      if (frame_flags & (WidthValue | HeightValue))
-       {
-         w = frame_w; h = frame_h;
-         flags |= (frame_flags & (WidthValue | HeightValue));
-       }
-      else if (app_flags & (WidthValue | HeightValue))
-       {
-         w = app_w;
-         h = app_h;
-         flags |= (app_flags & (WidthValue | HeightValue));
-       }
-    }
-#endif /* 0 */
-  {
-    Dimension pixel_width, pixel_height;
-
-    /* Take into account the size of the scrollbar.  Always use the
-       number of columns occupied by the scroll bar here otherwise we
-       might end up with a frame width that is not a multiple of the
-       frame's character width which is bad for vertically split
-       windows.  */
-
-#if 0 /* This can run Lisp code, and it is dangerous to give
-        out the frame to Lisp code before it officially exists.
-        This is handled in Fx_create_frame so not needed here.  */
-    change_frame_size (f, w, h, 1, 0, 0, 0);
-#endif
-    char_to_pixel_size (ew, w, h, &pixel_width, &pixel_height);
-    ew->core.width = pixel_width;
-    ew->core.height = pixel_height;
-
-#if 0 /* xfns.c takes care of this now.  */
-    /* If a position was specified, assign it to the shell widget.
-       (Else WM won't do anything with it.)
-     */
-    if (flags & (XValue | YValue))
-      {
-       /* the tricky things with the sign is to make sure that
-          -0 is printed -0. */
-       sprintf (shell_position, "=%c%d%c%d",
-                flags & XNegative ? '-' : '+', x < 0 ? -x : x,
-                flags & YNegative ? '-' : '+', y < 0 ? -y : y);
-       XtVaSetValues (wmshell, XtNgeometry, xstrdup (shell_position), NULL);
-      }
-    else if (flags & (WidthValue | HeightValue))
-      {
-       sprintf (shell_position, "=%dx%d", pixel_width, pixel_height);
-       XtVaSetValues (wmshell, XtNgeometry, xstrdup (shell_position), NULL);
-      }
-
-    /* If the geometry spec we're using has W/H components, mark the size
-       in the WM_SIZE_HINTS as user specified. */
-    if (flags & (WidthValue | HeightValue))
-      mark_shell_size_user_specified (wmshell);
-
-    /* Also assign the iconic status of the frame to the Shell, so that
-       the WM sees it. */
-    XtVaSetValues (wmshell, XtNiconic, ew->emacs_frame.iconic, NULL);
-#endif /* 0 */
-  }
+  char_to_pixel_size (ew, w, h, &pixel_width, &pixel_height);
+  ew->core.width = (frame_resize_pixelwise
+                   ? FRAME_PIXEL_WIDTH (f)
+                   : pixel_width);
+  ew->core.height = (frame_resize_pixelwise
+                    ? FRAME_PIXEL_HEIGHT (f)
+                    : pixel_height);
+
+  frame_size_history_add
+    (f, Qset_frame_size, FRAME_TEXT_WIDTH (f), FRAME_TEXT_HEIGHT (f),
+     list2 (make_number (ew->core.width), make_number (ew->core.height)));
 }
 
 static void
 update_wm_hints (EmacsFrame ew)
 {
-  Widget wmshell = get_wm_shell ((Widget)ew);
+  Widget wmshell = get_wm_shell ((Widget) ew);
   int cw;
   int ch;
   Dimension rounded_width;
@@ -460,7 +308,7 @@ update_wm_hints (EmacsFrame ew)
   base_width = (wmshell->core.width - ew->core.width
                + (rounded_width - (char_width * cw)));
   base_height = (wmshell->core.height - ew->core.height
-               + (rounded_height - (char_height * ch)));
+                + (rounded_height - (char_height * ch)));
 
   /* This is kind of sleazy, but I can't see how else to tell it to
      make it mark the WM_SIZE_HINTS size as user specified.
@@ -480,7 +328,7 @@ update_wm_hints (EmacsFrame ew)
 void
 widget_update_wm_size_hints (Widget widget)
 {
-  EmacsFrame ew = (EmacsFrame)widget;
+  EmacsFrame ew = (EmacsFrame) widget;
   update_wm_hints (ew);
 }
 
@@ -489,16 +337,6 @@ update_various_frame_slots (EmacsFrame ew)
 {
   struct frame *f = ew->emacs_frame.frame;
 
-  /* Don't do that: It confuses the check in change_frame_size_1 whether
-     the pixel size of the frame changed due to a change of the internal
-     border width.  Bug#16736.  */
-  if (false)
-    {
-      struct x_output *x = f->output_data.x;
-      FRAME_PIXEL_HEIGHT (f) = ew->core.height + x->menubar_height;
-      FRAME_PIXEL_WIDTH (f) = ew->core.width;
-    }
-
   f->internal_border_width = ew->emacs_frame.internal_border_width;
 }
 
@@ -507,6 +345,7 @@ update_from_various_frame_slots (EmacsFrame ew)
 {
   struct frame *f = ew->emacs_frame.frame;
   struct x_output *x = f->output_data.x;
+
   ew->core.height = FRAME_PIXEL_HEIGHT (f) - x->menubar_height;
   ew->core.width = FRAME_PIXEL_WIDTH (f);
   ew->core.background_pixel = FRAME_BACKGROUND_PIXEL (f);
@@ -519,7 +358,7 @@ update_from_various_frame_slots (EmacsFrame ew)
 static void
 EmacsFrameInitialize (Widget request, Widget new, ArgList dum1, Cardinal *dum2)
 {
-  EmacsFrame ew = (EmacsFrame)new;
+  EmacsFrame ew = (EmacsFrame) new;
 
   if (!ew->emacs_frame.frame)
     {
@@ -545,7 +384,7 @@ resize_cb (Widget widget,
 static void
 EmacsFrameRealize (Widget widget, XtValueMask *mask, XSetWindowAttributes *attrs)
 {
-  EmacsFrame ew = (EmacsFrame)widget;
+  EmacsFrame ew = (EmacsFrame) widget;
 
   /* This used to contain SubstructureRedirectMask, but this turns out
      to be a problem with XIM on Solaris, and events from that mask
@@ -554,7 +393,7 @@ EmacsFrameRealize (Widget widget, XtValueMask *mask, XSetWindowAttributes *attrs
                       | PropertyChangeMask
                       | SubstructureNotifyMask);
   *mask |= CWEventMask;
-  XtCreateWindow (widget, InputOutput, (Visual *)CopyFromParent, *mask,
+  XtCreateWindow (widget, InputOutput, (Visual *) CopyFromParent, *mask,
                  attrs);
   /* Some ConfigureNotify events does not end up in EmacsFrameResize so
      make sure we get them all.  Seen with xfcwm4 for example.  */
@@ -571,58 +410,43 @@ EmacsFrameDestroy (Widget widget)
 static void
 EmacsFrameResize (Widget widget)
 {
-  EmacsFrame ew = (EmacsFrame)widget;
+  EmacsFrame ew = (EmacsFrame) widget;
   struct frame *f = ew->emacs_frame.frame;
+  int width, height;
 
-  /* Always process resize requests pixelwise.  Frame maximizing
-     should work even when frame_resize_pixelwise is nil.  */
-  if (true || frame_resize_pixelwise)
-    {
-      int width, height;
+  pixel_to_text_size (ew, ew->core.width, ew->core.height, &width, &height);
 
-      pixel_to_text_size (ew, ew->core.width, ew->core.height, &width, &height);
-      change_frame_size (f, width, height, 0, 1, 0, 1);
+  frame_size_history_add
+    (f, QEmacsFrameResize, width, height,
+     list5 (make_number (ew->core.width), make_number (ew->core.height),
+           make_number (FRAME_TOP_MARGIN_HEIGHT (f)),
+           make_number (FRAME_SCROLL_BAR_AREA_HEIGHT (f)),
+           make_number (2 * FRAME_INTERNAL_BORDER_WIDTH (f))));
 
-      update_wm_hints (ew);
-      update_various_frame_slots (ew);
+  change_frame_size (f, width, height, 0, 1, 0, 1);
 
-      cancel_mouse_face (f);
-    }
-  else
-    {
-      struct x_output *x = f->output_data.x;
-      int columns, rows;
-
-      pixel_to_char_size (ew, ew->core.width, ew->core.height, &columns, &rows);
-      if (columns != FRAME_COLS (f)
-         || rows != FRAME_LINES (f)
-         || ew->core.width != FRAME_PIXEL_WIDTH (f)
-         || ew->core.height + x->menubar_height != FRAME_PIXEL_HEIGHT (f))
-       {
-         change_frame_size (f, columns, rows, 0, 1, 0, 0);
-         update_wm_hints (ew);
-         update_various_frame_slots (ew);
+  update_wm_hints (ew);
+  update_various_frame_slots (ew);
 
-         cancel_mouse_face (f);
-       }
-    }
+  cancel_mouse_face (f);
 }
 
 static XtGeometryResult
 EmacsFrameQueryGeometry (Widget widget, XtWidgetGeometry *request, XtWidgetGeometry *result)
 {
-  EmacsFrame ew = (EmacsFrame)widget;
+  EmacsFrame ew = (EmacsFrame) widget;
 
   int mask = request->request_mode;
   Dimension ok_width, ok_height;
 
   if (mask & (CWWidth | CWHeight))
     {
-      round_size_to_char (ew,
-                         (mask & CWWidth) ? request->width : ew->core.width,
-                         ((mask & CWHeight) ? request->height
-                          : ew->core.height),
-                         &ok_width, &ok_height);
+      if (!frame_resize_pixelwise)
+       round_size_to_char (ew,
+                           (mask & CWWidth) ? request->width : ew->core.width,
+                           ((mask & CWHeight) ? request->height
+                            : ew->core.height),
+                           &ok_width, &ok_height);
       if ((mask & CWWidth) && (ok_width != request->width))
        {
          result->request_mode |= CWWidth;