root/src/emacsgtkfixed.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. G_DEFINE_TYPE
  2. emacs_fixed_class_init
  3. emacs_fixed_init
  4. emacs_fixed_new
  5. emacs_fixed_get_preferred_width
  6. emacs_fixed_get_preferred_height
  7. XSetWMSizeHints
  8. XSetWMNormalHints

     1 /* A Gtk Widget that inherits GtkFixed, but can be shrunk.
     2 This file is only use when compiling with Gtk+ 3.
     3 
     4 Copyright (C) 2011-2023 Free Software Foundation, Inc.
     5 
     6 This file is part of GNU Emacs.
     7 
     8 GNU Emacs is free software: you can redistribute it and/or modify
     9 it under the terms of the GNU General Public License as published by
    10 the Free Software Foundation, either version 3 of the License, or (at
    11 your option) any later version.
    12 
    13 GNU Emacs is distributed in the hope that it will be useful,
    14 but WITHOUT ANY WARRANTY; without even the implied warranty of
    15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16 GNU General Public License for more details.
    17 
    18 You should have received a copy of the GNU General Public License
    19 along with GNU Emacs.  If not, see <https://www.gnu.org/licenses/>.  */
    20 
    21 #include <config.h>
    22 
    23 #include "lisp.h"
    24 #include "frame.h"
    25 #ifdef HAVE_PGTK
    26 #include "pgtkterm.h"
    27 #else
    28 #include "xterm.h"
    29 #endif
    30 #include "emacsgtkfixed.h"
    31 
    32 /* Silence a bogus diagnostic; see GNOME bug 683906.  */
    33 #if GNUC_PREREQ (4, 7, 0) && ! GLIB_CHECK_VERSION (2, 35, 7)
    34 # pragma GCC diagnostic push
    35 # pragma GCC diagnostic ignored "-Wunused-local-typedefs"
    36 #endif
    37 
    38 typedef struct _EmacsFixed EmacsFixed;
    39 typedef struct _EmacsFixedClass EmacsFixedClass;
    40 
    41 struct _EmacsFixedPrivate
    42 {
    43   struct frame *f;
    44 };
    45 
    46 
    47 static void emacs_fixed_get_preferred_width  (GtkWidget *widget,
    48                                               gint      *minimum,
    49                                               gint      *natural);
    50 static void emacs_fixed_get_preferred_height (GtkWidget *widget,
    51                                               gint      *minimum,
    52                                               gint      *natural);
    53 #ifndef HAVE_PGTK
    54 static GType emacs_fixed_get_type (void);
    55 #endif
    56 G_DEFINE_TYPE (EmacsFixed, emacs_fixed, GTK_TYPE_FIXED)
    57 
    58 static EmacsFixed *
    59 EMACS_FIXED (GtkWidget *widget)
    60 {
    61   return G_TYPE_CHECK_INSTANCE_CAST (widget, emacs_fixed_get_type (),
    62                                      EmacsFixed);
    63 }
    64 
    65 static void
    66 emacs_fixed_class_init (EmacsFixedClass *klass)
    67 {
    68   GtkWidgetClass *widget_class;
    69 
    70   widget_class = (GtkWidgetClass *) klass;
    71 
    72   widget_class->get_preferred_width = emacs_fixed_get_preferred_width;
    73   widget_class->get_preferred_height = emacs_fixed_get_preferred_height;
    74   g_type_class_add_private (klass, sizeof (EmacsFixedPrivate));
    75 }
    76 
    77 static void
    78 emacs_fixed_init (EmacsFixed *fixed)
    79 {
    80   fixed->priv = G_TYPE_INSTANCE_GET_PRIVATE (fixed, emacs_fixed_get_type (),
    81                                              EmacsFixedPrivate);
    82   fixed->priv->f = 0;
    83 }
    84 
    85 GtkWidget *
    86 emacs_fixed_new (struct frame *f)
    87 {
    88   EmacsFixed *fixed = g_object_new (emacs_fixed_get_type (), NULL);
    89   EmacsFixedPrivate *priv = fixed->priv;
    90   priv->f = f;
    91   return GTK_WIDGET (fixed);
    92 }
    93 
    94 static void
    95 emacs_fixed_get_preferred_width (GtkWidget *widget,
    96                                  gint      *minimum,
    97                                  gint      *natural)
    98 {
    99   EmacsFixed *fixed = EMACS_FIXED (widget);
   100   EmacsFixedPrivate *priv = fixed->priv;
   101 #ifdef HAVE_PGTK
   102   int w = priv->f->output_data.pgtk->size_hints.min_width;
   103   if (minimum) *minimum = w;
   104   if (natural) *natural = priv->f->output_data.pgtk->preferred_width;
   105 #else
   106   int w = priv->f->output_data.x->size_hints.min_width;
   107   if (minimum) *minimum = w;
   108   if (natural) *natural = w;
   109 #endif
   110 }
   111 
   112 static void
   113 emacs_fixed_get_preferred_height (GtkWidget *widget,
   114                                   gint      *minimum,
   115                                   gint      *natural)
   116 {
   117   EmacsFixed *fixed = EMACS_FIXED (widget);
   118   EmacsFixedPrivate *priv = fixed->priv;
   119 #ifdef HAVE_PGTK
   120   int h = priv->f->output_data.pgtk->size_hints.min_height;
   121   if (minimum) *minimum = h;
   122   if (natural) *natural = priv->f->output_data.pgtk->preferred_height;
   123 #else
   124   int h = priv->f->output_data.x->size_hints.min_height;
   125   if (minimum) *minimum = h;
   126   if (natural) *natural = h;
   127 #endif
   128 }
   129 
   130 
   131 #ifndef HAVE_PGTK
   132 
   133 /* Override the X function so we can intercept Gtk+ 3 calls.
   134    Use our values for min_width/height so that KDE don't freak out
   135    (Bug#8919), and so users can resize our frames as they wish.  */
   136 
   137 void
   138 XSetWMSizeHints (Display *d,
   139                  Window w,
   140                  XSizeHints *hints,
   141                  Atom prop)
   142 {
   143   struct x_display_info *dpyinfo = x_display_info_for_display (d);
   144   struct frame *f = x_top_window_to_frame (dpyinfo, w);
   145   long data[18];
   146   data[0] = hints->flags;
   147   data[1] = hints->x;
   148   data[2] = hints->y;
   149   data[3] = hints->width;
   150   data[4] = hints->height;
   151   data[5] = hints->min_width;
   152   data[6] = hints->min_height;
   153   data[7] = hints->max_width;
   154   data[8] = hints->max_height;
   155   data[9] = hints->width_inc;
   156   data[10] = hints->height_inc;
   157   data[11] = hints->min_aspect.x;
   158   data[12] = hints->min_aspect.y;
   159   data[13] = hints->max_aspect.x;
   160   data[14] = hints->max_aspect.y;
   161   data[15] = hints->base_width;
   162   data[16] = hints->base_height;
   163   data[17] = hints->win_gravity;
   164 
   165   if ((hints->flags & PMinSize) && f)
   166     {
   167       /* Overriding the size hints with our own values of min_width
   168          and min_height used to work, but these days just results in
   169          frames resizing unpredictably and emitting GTK warnings while
   170          Emacs fights with GTK over the size of the frame.  So instead
   171          of doing that, just respect the hints set by GTK, but make
   172          sure they are an integer multiple of the resize increments so
   173          that bug#8919 stays fixed.  */
   174 
   175       /* int w = f->output_data.x->size_hints.min_width;
   176          int h = f->output_data.x->size_hints.min_height;
   177 
   178          data[5] = w;
   179          data[6] = h; */
   180 
   181       /* Make sure min_width and min_height are multiples of width_inc
   182          and height_inc.  */
   183 
   184       if (hints->flags & PResizeInc)
   185         {
   186           /* Some versions of GTK set PResizeInc even if the
   187              increments are at their initial values.  */
   188 
   189           if (hints->width_inc && data[5] % hints->width_inc)
   190             data[5] += (hints->width_inc - (data[5] % hints->width_inc));
   191           if (hints->height_inc && data[6] % hints->height_inc)
   192             data[6] += (hints->height_inc - (data[6] % hints->height_inc));
   193         }
   194     }
   195 
   196   XChangeProperty (d, w, prop, XA_WM_SIZE_HINTS, 32, PropModeReplace,
   197                    (unsigned char *) data, 18);
   198 }
   199 
   200 /* Override this X11 function.
   201    This function is in the same X11 file as the one above.  So we must
   202    provide it also.  */
   203 
   204 void
   205 XSetWMNormalHints (Display *d, Window w, XSizeHints *hints)
   206 {
   207   XSetWMSizeHints (d, w, hints, XA_WM_NORMAL_HINTS);
   208 }
   209 
   210 #endif

/* [<][>][^][v][top][bottom][index][help] */