Mercurial > hg > xemacs-beta
annotate src/frame-gtk.c @ 5090:0ca81354c4c7
Further frame-geometry cleanups
-------------------- ChangeLog entries follow: --------------------
man/ChangeLog addition:
2010-03-03 Ben Wing <ben@xemacs.org>
* internals/internals.texi (Intro to Window and Frame Geometry):
* internals/internals.texi (The Paned Area):
* internals/internals.texi (The Displayable Area):
Update to make note of e.g. the fact that the bottom gutter is
actually above the minibuffer.
src/ChangeLog addition:
2010-03-03 Ben Wing <ben@xemacs.org>
* emacs.c:
* emacs.c (assert_equal_failed):
* lisp.h:
* lisp.h (assert_equal):
New fun assert_equal, asserting that two values == each other, and
printing out both values upon failure.
* frame-gtk.c (gtk_initialize_frame_size):
* frame-impl.h:
* frame-impl.h (FRAME_TOP_INTERNAL_BORDER_START):
* frame-impl.h (FRAME_BOTTOM_INTERNAL_BORDER_START):
* frame-impl.h (FRAME_LEFT_INTERNAL_BORDER_START):
* frame-impl.h (FRAME_PANED_TOP_EDGE):
* frame-impl.h (FRAME_NONPANED_SIZE):
* frame-x.c (x_initialize_frame_size):
* frame.c:
* gutter.c (get_gutter_coords):
* gutter.c (calculate_gutter_size):
* gutter.h:
* gutter.h (WINDOW_REAL_TOP_GUTTER_BOUNDS):
* gutter.h (FRAME_TOP_GUTTER_BOUNDS):
* input-method-xlib.c:
* input-method-xlib.c (XIM_SetGeometry):
* redisplay-output.c (clear_left_border):
* redisplay-output.c (clear_right_border):
* redisplay-output.c (redisplay_output_pixmap):
* redisplay-output.c (redisplay_clear_region):
* redisplay-output.c (redisplay_clear_top_of_window):
* redisplay-output.c (redisplay_clear_to_window_end):
* redisplay-xlike-inc.c (XLIKE_clear_frame):
* redisplay.c:
* redisplay.c (UPDATE_CACHE_RETURN):
* redisplay.c (pixel_to_glyph_translation):
* toolbar.c (update_frame_toolbars_geometry):
* window.c (Fwindow_pixel_edges):
Get rid of some redundant macros. Consistently use the
FRAME_TOP_*_START, FRAME_RIGHT_*_END, etc. format. Rename
FRAME_*_BORDER_* to FRAME_*_INTERNAL_BORDER_*. Comment out
FRAME_BOTTOM_* for gutters and the paned area due to the
uncertainty over where the paned area actually begins. (Eventually
we should probably move the gutters outside the minibuffer so that
the paned area is contiguous.) Use FRAME_PANED_* more often in the
code to make things clearer.
Update the diagram to show that the bottom gutter is inside the
minibuffer (!) and that there are "junk boxes" when you have left
and/or right gutters (dead boxes that are mistakenly left uncleared,
unlike the corresponding scrollbar dead boxes). Update the text
appropriately to cover the bottom gutter position, etc.
Rewrite gutter-geometry code to use the FRAME_*_GUTTER_* in place of
equivalent expressions referencing other frame elements, to make the
code more portable in case we move around the gutter location.
Cleanup FRAME_*_GUTTER_BOUNDS() in gutter.h.
Add some #### GEOM! comments where I think code is incorrect --
typically, it wasn't fixed up properly when the gutter was added.
Some cosmetic changes.
author | Ben Wing <ben@xemacs.org> |
---|---|
date | Wed, 03 Mar 2010 05:07:47 -0600 |
parents | 07dcc7000bbf |
children | 7be849cb8828 |
rev | line source |
---|---|
2168 | 1 /* Functions for the GTK toolkit. |
462 | 2 Copyright (C) 1989, 1992-5, 1997 Free Software Foundation, Inc. |
5043 | 3 Copyright (C) 1995, 1996, 2002, 2003, 2010 Ben Wing. |
462 | 4 |
5 This file is part of XEmacs. | |
6 | |
7 XEmacs is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 2, or (at your option) any | |
10 later version. | |
11 | |
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with XEmacs; see the file COPYING. If not, write to | |
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
20 Boston, MA 02111-1307, USA. */ | |
21 | |
22 /* Synched up with: Not synched with FSF. */ | |
23 | |
24 /* Substantially rewritten for XEmacs. */ | |
25 /* Revamped to use Gdk/Gtk by William Perry */ | |
26 | |
27 #include <config.h> | |
28 #include "lisp.h" | |
29 | |
872 | 30 #include "buffer.h" |
31 #include "device-impl.h" | |
32 #include "events.h" | |
33 #include "extents.h" | |
34 #include "faces.h" | |
35 #include "frame-impl.h" | |
36 #include "window.h" | |
37 | |
38 #ifdef HAVE_DRAGNDROP | |
39 #include "dragdrop.h" | |
40 #endif | |
41 | |
2168 | 42 #include "elhash.h" |
872 | 43 #include "console-gtk-impl.h" |
462 | 44 #include "glyphs-gtk.h" |
872 | 45 #include "objects-gtk-impl.h" |
462 | 46 #include "scrollbar-gtk.h" |
872 | 47 #include "ui-gtk.h" |
462 | 48 |
49 #include "gtk-xemacs.h" | |
50 | |
51 #ifdef HAVE_GNOME | |
52 #include <libgnomeui/libgnomeui.h> | |
53 #endif | |
54 | |
55 #define BORDER_WIDTH 0 | |
56 #define INTERNAL_BORDER_WIDTH 0 | |
57 | |
58 #define TRANSIENT_DATA_IDENTIFIER "xemacs::transient_for" | |
59 #define UNMAPPED_DATA_IDENTIFIER "xemacs::initially_unmapped" | |
60 | |
61 #define STUPID_X_SPECIFIC_GTK_STUFF | |
62 | |
63 #ifdef STUPID_X_SPECIFIC_GTK_STUFF | |
4908
b3ce27ca7647
various fixes related to gtk, redisplay-xlike-inc.c
Ben Wing <ben@xemacs.org>
parents:
4906
diff
changeset
|
64 #include "sysgdkx.h" |
462 | 65 #endif |
66 | |
67 /* Default properties to use when creating frames. */ | |
68 Lisp_Object Vdefault_gtk_frame_plist; | |
69 | |
70 Lisp_Object Qdetachable_menubar; | |
71 Lisp_Object Qtext_widget; | |
72 Lisp_Object Qcontainer_widget; | |
73 Lisp_Object Qshell_widget; | |
74 | |
75 #ifdef STUPID_X_SPECIFIC_GTK_STUFF | |
76 EXFUN (Fgtk_window_id, 1); | |
77 #endif | |
78 | |
79 #ifdef HAVE_DRAGNDROP | |
80 enum { | |
81 TARGET_TYPE_STRING, | |
82 TARGET_TYPE_URI_LIST, | |
83 }; | |
84 | |
85 static GtkTargetEntry dnd_target_table[] = { | |
86 { "STRING", 0, TARGET_TYPE_STRING }, | |
87 { "text/plain", 0, TARGET_TYPE_STRING }, | |
88 { "text/uri-list", 0, TARGET_TYPE_URI_LIST }, | |
89 { "_NETSCAPE_URL", 0, TARGET_TYPE_STRING } | |
90 }; | |
91 | |
92 static guint dnd_n_targets = sizeof(dnd_target_table) / sizeof(dnd_target_table[0]); | |
93 | |
94 #endif | |
95 | |
1204 | 96 static const struct memory_description gtk_frame_data_description_1 [] = { |
97 { XD_LISP_OBJECT, offsetof (struct gtk_frame, icon_pixmap) }, | |
98 { XD_LISP_OBJECT, offsetof (struct gtk_frame, icon_pixmap_mask) }, | |
99 { XD_LISP_OBJECT_ARRAY, offsetof (struct gtk_frame, lisp_visible_widgets), | |
100 3 }, | |
1346 | 101 { XD_LISP_OBJECT, offsetof (struct gtk_frame, menubar_data) }, |
1204 | 102 { XD_END } |
103 }; | |
104 | |
3092 | 105 #ifdef NEW_GC |
106 DEFINE_LRECORD_IMPLEMENTATION ("gtk-frame", gtk_frame, | |
107 1, /*dumpable-flag*/ | |
108 0, 0, 0, 0, 0, | |
109 gtk_frame_data_description_1, | |
110 Lisp_Gtk_Frame); | |
111 #else /* not NEW_GC */ | |
1204 | 112 extern const struct sized_memory_description gtk_frame_data_description; |
113 | |
114 const struct sized_memory_description gtk_frame_data_description = { | |
115 sizeof (struct gtk_frame), gtk_frame_data_description_1 | |
116 }; | |
3092 | 117 #endif /* not NEW_GC */ |
1204 | 118 |
462 | 119 |
120 /************************************************************************/ | |
121 /* helper functions */ | |
122 /************************************************************************/ | |
123 | |
2168 | 124 /* Return the Emacs frame-object which contains the given widget. */ |
125 struct frame * | |
126 gtk_widget_to_frame (GtkWidget *w) | |
127 { | |
128 struct frame *f = NULL; | |
129 | |
130 for (; w; w = w->parent) | |
131 { | |
132 if ((f = (struct frame *) gtk_object_get_data (GTK_OBJECT (w), | |
133 GTK_DATA_FRAME_IDENTIFIER))) | |
134 return (f); | |
135 } | |
136 | |
137 return (selected_frame()); | |
138 } | |
139 | |
140 | |
462 | 141 /* Return the Emacs frame-object corresponding to an X window */ |
142 struct frame * | |
143 gtk_window_to_frame (struct device *d, GdkWindow *wdesc) | |
144 { | |
145 Lisp_Object tail, frame; | |
146 struct frame *f; | |
147 | |
148 /* This function was previously written to accept only a window argument | |
149 (and to loop over all devices looking for a matching window), but | |
150 that is incorrect because window ID's are not unique across displays. */ | |
151 | |
152 for (tail = DEVICE_FRAME_LIST (d); CONSP (tail); tail = XCDR (tail)) | |
153 { | |
154 frame = XCAR (tail); | |
155 if (!FRAMEP (frame)) | |
156 continue; | |
157 f = XFRAME (frame); | |
158 if (FRAME_GTK_P (f) && GET_GTK_WIDGET_WINDOW (FRAME_GTK_TEXT_WIDGET (f)) == wdesc) | |
159 return f; | |
160 } | |
161 return 0; | |
162 } | |
163 | |
164 /* Like gtk_window_to_frame but also compares the window with the widget's | |
165 windows */ | |
166 struct frame * | |
167 gtk_any_window_to_frame (struct device *d, GdkWindow *w) | |
168 { | |
169 do | |
170 { | |
171 Lisp_Object frmcons; | |
172 | |
173 DEVICE_FRAME_LOOP (frmcons, d) | |
174 { | |
175 struct frame *fr = XFRAME (XCAR (frmcons)); | |
176 if ((w == GET_GTK_WIDGET_WINDOW (FRAME_GTK_SHELL_WIDGET (fr))) || | |
177 (w == GET_GTK_WIDGET_WINDOW (FRAME_GTK_CONTAINER_WIDGET (fr))) || | |
178 #ifdef HAVE_MENUBARS | |
179 (w == GET_GTK_WIDGET_WINDOW (FRAME_GTK_MENUBAR_WIDGET (fr))) || | |
180 #endif | |
181 (w == GET_GTK_WIDGET_WINDOW (FRAME_GTK_TEXT_WIDGET (fr)))) | |
182 { | |
183 return (fr); | |
184 } | |
185 } | |
186 w = gdk_window_get_parent (w); | |
187 } while (w); | |
188 | |
189 return (0); | |
190 } | |
191 | |
192 struct frame * | |
193 gtk_any_widget_or_parent_to_frame (struct device *d, GtkWidget *widget) | |
194 { | |
195 return (gtk_any_window_to_frame (d, GET_GTK_WIDGET_WINDOW (widget))); | |
196 } | |
197 | |
198 struct device * | |
199 gtk_any_window_to_device (GdkWindow *w) | |
200 { | |
201 struct device *d = NULL; | |
202 Lisp_Object devcons, concons; | |
203 | |
204 DEVICE_LOOP_NO_BREAK (devcons, concons) | |
205 { | |
206 d = XDEVICE (XCAR (devcons)); | |
207 if (!DEVICE_GTK_P (d)) continue; | |
208 if (gtk_any_window_to_frame (d, w)) | |
209 return (d); | |
210 } | |
211 return (NULL); | |
212 } | |
213 | |
214 struct frame * | |
215 decode_gtk_frame (Lisp_Object frame) | |
216 { | |
217 if (NILP (frame)) | |
793 | 218 frame = wrap_frame (selected_frame ()); |
462 | 219 CHECK_LIVE_FRAME (frame); |
220 /* this will also catch dead frames, but putting in the above check | |
221 results in a more useful error */ | |
222 CHECK_GTK_FRAME (frame); | |
223 return XFRAME (frame); | |
224 } | |
225 | |
226 | |
227 /************************************************************************/ | |
228 /* window-manager interactions */ | |
229 /************************************************************************/ | |
230 static int | |
231 gtk_frame_iconified_p (struct frame *f) | |
232 { | |
233 return (f->iconified); | |
234 } | |
235 | |
236 | |
237 /************************************************************************/ | |
238 /* frame properties */ | |
239 /************************************************************************/ | |
240 | |
241 static Lisp_Object | |
242 gtk_frame_property (struct frame *f, Lisp_Object property) | |
243 { | |
244 GtkWidget *shell = FRAME_GTK_SHELL_WIDGET (f); | |
245 | |
246 if (EQ (Qleft, property) || EQ (Qtop, property)) | |
247 { | |
248 gint x, y; | |
249 if (!GET_GTK_WIDGET_WINDOW(shell)) | |
250 return Qzero; | |
251 gdk_window_get_deskrelative_origin (GET_GTK_WIDGET_WINDOW (shell), &x, &y); | |
252 if (EQ (Qleft, property)) return make_int (x); | |
253 if (EQ (Qtop, property)) return make_int (y); | |
254 } | |
255 if (EQ (Qshell_widget, property)) | |
256 { | |
257 return (FRAME_GTK_LISP_WIDGETS (f)[0]); | |
258 } | |
259 if (EQ (Qcontainer_widget, property)) | |
260 { | |
261 return (FRAME_GTK_LISP_WIDGETS (f)[1]); | |
262 } | |
263 if (EQ (Qtext_widget, property)) | |
264 { | |
265 return (FRAME_GTK_LISP_WIDGETS (f)[2]); | |
266 } | |
267 #ifdef STUPID_X_SPECIFIC_GTK_STUFF | |
268 if (EQ (Qwindow_id, property)) | |
771 | 269 return Fgtk_window_id (wrap_frame (f)); |
462 | 270 #endif |
271 | |
272 return Qunbound; | |
273 } | |
274 | |
275 static int | |
3087 | 276 gtk_internal_frame_property_p (struct frame *UNUSED(f), Lisp_Object property) |
462 | 277 { |
278 return EQ (property, Qleft) | |
279 || EQ (property, Qtop) | |
280 || EQ (Qshell_widget, property) | |
281 || EQ (Qcontainer_widget, property) | |
282 || EQ (Qtext_widget, property) | |
283 || EQ (property, Qwindow_id) | |
284 || STRINGP (property); | |
285 } | |
286 | |
287 static Lisp_Object | |
288 gtk_frame_properties (struct frame *f) | |
289 { | |
290 Lisp_Object props = Qnil; | |
291 GtkWidget *shell = FRAME_GTK_SHELL_WIDGET (f); | |
292 gint x, y; | |
293 | |
294 props = cons3 (Qshell_widget, FRAME_GTK_LISP_WIDGETS (f)[0], props); | |
295 props = cons3 (Qcontainer_widget, FRAME_GTK_LISP_WIDGETS (f)[1], props); | |
296 props = cons3 (Qtext_widget, FRAME_GTK_LISP_WIDGETS (f)[2], props); | |
297 | |
298 #ifdef STUPID_X_SPECIFIC_GTK_STUFF | |
771 | 299 props = cons3 (Qwindow_id, Fgtk_window_id (wrap_frame (f)), props); |
462 | 300 #endif |
301 | |
302 if (!GET_GTK_WIDGET_WINDOW (shell)) | |
303 x = y = 0; | |
304 else | |
305 gdk_window_get_deskrelative_origin (GET_GTK_WIDGET_WINDOW (shell), &x, &y); | |
306 | |
307 props = cons3 (Qtop, make_int (y), props); | |
308 props = cons3 (Qleft, make_int (x), props); | |
309 | |
310 return props; | |
311 } | |
312 | |
313 | |
314 /* Functions called only from `gtk_set_frame_properties' to set | |
315 individual properties. */ | |
316 | |
317 static void | |
2286 | 318 gtk_set_frame_text_value (struct frame *UNUSED (f), Ibyte *value, |
462 | 319 void (*func) (gpointer, gchar *), |
320 gpointer arg) | |
321 { | |
322 gchar *the_text = (gchar *) value; | |
323 | |
324 /* Programmer fuckup or window is not realized yet. */ | |
325 if (!func || !arg) return; | |
326 | |
327 #ifdef MULE | |
328 { | |
867 | 329 Ibyte *ptr; |
462 | 330 |
331 /* Optimize for common ASCII case */ | |
332 for (ptr = value; *ptr; ptr++) | |
826 | 333 if (!byte_ascii_p (*ptr)) |
462 | 334 { |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
335 char *tmp = ITEXT_TO_EXTERNAL (value, Qctext); |
462 | 336 the_text = tmp; |
337 break; | |
338 } | |
339 } | |
340 #endif /* MULE */ | |
341 | |
342 (*func) (arg, (gchar *) the_text); | |
343 } | |
344 | |
345 static void | |
867 | 346 gtk_set_title_from_ibyte (struct frame *f, Ibyte *name) |
462 | 347 { |
348 if (GTK_IS_WINDOW (FRAME_GTK_SHELL_WIDGET (f))) | |
349 gtk_set_frame_text_value (f, name, | |
350 (void (*)(gpointer, gchar *)) | |
351 gtk_window_set_title, FRAME_GTK_SHELL_WIDGET (f)); | |
352 } | |
353 | |
354 static void | |
867 | 355 gtk_set_icon_name_from_ibyte (struct frame *f, Ibyte *name) |
462 | 356 { |
357 gtk_set_frame_text_value (f, name, | |
358 (void (*)(gpointer, gchar *)) | |
359 gdk_window_set_icon_name, FRAME_GTK_SHELL_WIDGET (f)->window); | |
360 } | |
361 | |
362 /* Set the initial frame size as specified. This function is used | |
363 when the frame's widgets have not yet been realized. | |
364 */ | |
365 static void | |
366 gtk_set_initial_frame_size (struct frame *f, int x, int y, | |
367 unsigned int w, unsigned int h) | |
368 { | |
369 GtkWidget *shell = FRAME_GTK_SHELL_WIDGET (f); | |
370 GdkGeometry geometry; | |
371 | |
372 if (GTK_IS_WINDOW (shell)) | |
373 { | |
2054 | 374 GdkWindowHints geometry_mask = GDK_HINT_RESIZE_INC; |
462 | 375 /* Deal with the cell size */ |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
376 default_face_width_and_height (wrap_frame (f), &geometry.width_inc, &geometry.height_inc); |
462 | 377 |
378 gtk_window_set_geometry_hints (GTK_WINDOW (shell), | |
379 FRAME_GTK_TEXT_WIDGET (f), &geometry, geometry_mask); | |
380 gdk_window_set_hints (GET_GTK_WIDGET_WINDOW (shell), x, y, 0, 0, 0, 0, GDK_HINT_POS); | |
381 gtk_window_set_policy (GTK_WINDOW (shell), TRUE, TRUE, FALSE); | |
382 } | |
383 | |
384 FRAME_HEIGHT (f) = h; | |
385 FRAME_WIDTH (f) = w; | |
386 | |
5043 | 387 change_frame_size (f, w, h, 0); |
462 | 388 { |
389 GtkRequisition req; | |
390 | |
391 gtk_widget_size_request (FRAME_GTK_SHELL_WIDGET (f), &req); | |
392 gtk_widget_set_usize (FRAME_GTK_SHELL_WIDGET (f), req.width, req.height); | |
393 } | |
394 } | |
395 | |
396 /* Report that a frame property of frame S is being set or changed. | |
397 If the property is not specially recognized, do nothing. | |
398 */ | |
399 | |
400 static void | |
401 gtk_set_frame_properties (struct frame *f, Lisp_Object plist) | |
402 { | |
403 gint x, y; | |
404 gint width = 0, height = 0; | |
405 gboolean width_specified_p = FALSE; | |
406 gboolean height_specified_p = FALSE; | |
407 gboolean x_position_specified_p = FALSE; | |
408 gboolean y_position_specified_p = FALSE; | |
409 Lisp_Object tail; | |
410 | |
411 for (tail = plist; !NILP (tail); tail = Fcdr (Fcdr (tail))) | |
412 { | |
413 Lisp_Object prop = Fcar (tail); | |
414 Lisp_Object val = Fcar (Fcdr (tail)); | |
415 | |
416 if (SYMBOLP (prop)) | |
417 { | |
418 if (EQ (prop, Qfont)) | |
419 { | |
420 /* If the value is not a string we silently ignore it. */ | |
421 if (STRINGP (val)) | |
422 { | |
423 Lisp_Object frm, font_spec; | |
424 | |
793 | 425 frm = wrap_frame (f); |
462 | 426 font_spec = Fget (Fget_face (Qdefault), Qfont, Qnil); |
427 | |
428 Fadd_spec_to_specifier (font_spec, val, frm, Qnil, Qnil); | |
429 update_frame_face_values (f); | |
430 } | |
431 continue; | |
432 } | |
433 else if (EQ (prop, Qwidth)) | |
434 { | |
435 CHECK_INT (val); | |
436 width = XINT (val); | |
437 width_specified_p = TRUE; | |
438 continue; | |
439 } | |
440 else if (EQ (prop, Qheight)) | |
441 { | |
442 CHECK_INT (val); | |
443 height = XINT (val); | |
444 height_specified_p = TRUE; | |
445 continue; | |
446 } | |
447 /* Further kludge the x/y. */ | |
448 else if (EQ (prop, Qx)) | |
449 { | |
450 CHECK_INT (val); | |
451 x = (gint) XINT (val); | |
452 x_position_specified_p = TRUE; | |
453 continue; | |
454 } | |
455 else if (EQ (prop, Qy)) | |
456 { | |
457 CHECK_INT (val); | |
458 y = (gint) XINT (val); | |
459 y_position_specified_p = TRUE; | |
460 continue; | |
461 } | |
462 } | |
463 } | |
464 | |
465 /* Kludge kludge kludge. We need to deal with the size and position | |
466 specially. */ | |
467 { | |
468 int size_specified_p = width_specified_p || height_specified_p; | |
469 int position_specified_p = x_position_specified_p || y_position_specified_p; | |
470 | |
471 if (!width_specified_p) | |
472 width = 80; | |
473 if (!height_specified_p) | |
474 height = 30; | |
475 | |
476 /* Kludge kludge kludge kludge. */ | |
477 if (position_specified_p && | |
478 (!x_position_specified_p || !y_position_specified_p)) | |
479 { | |
480 gint dummy; | |
481 GtkWidget *shell = FRAME_GTK_SHELL_WIDGET (f); | |
482 gdk_window_get_deskrelative_origin (GET_GTK_WIDGET_WINDOW (shell), | |
483 (x_position_specified_p ? &dummy : &x), | |
484 (y_position_specified_p ? &dummy : &y)); | |
485 } | |
486 | |
487 if (!f->init_finished) | |
488 { | |
489 if (size_specified_p || position_specified_p) | |
490 gtk_set_initial_frame_size (f, x, y, width, height); | |
491 } | |
492 else | |
493 { | |
494 if (size_specified_p) | |
495 { | |
793 | 496 Lisp_Object frame = wrap_frame (f); |
497 | |
462 | 498 Fset_frame_size (frame, make_int (width), make_int (height), Qnil); |
499 } | |
500 if (position_specified_p) | |
501 { | |
793 | 502 Lisp_Object frame = wrap_frame (f); |
503 | |
462 | 504 Fset_frame_position (frame, make_int (x), make_int (y)); |
505 } | |
506 } | |
507 } | |
508 } | |
509 | |
510 | |
511 /************************************************************************/ | |
512 /* widget creation */ | |
513 /************************************************************************/ | |
514 /* Figure out what size the shell widget should initially be, | |
515 and set it. Should be called after the default font has been | |
516 determined but before the widget has been realized. */ | |
517 | |
518 extern Lisp_Object Vgtk_initial_geometry; | |
519 | |
520 #ifndef HAVE_GNOME | |
521 static int | |
522 get_number (const char **geometry) | |
523 { | |
524 int value = 0; | |
525 int mult = 1; | |
526 | |
527 if (**geometry == '-'){ | |
528 mult = -1; | |
529 (*geometry)++; | |
530 } | |
531 while (**geometry && isdigit (**geometry)){ | |
532 value = value * 10 + (**geometry - '0'); | |
533 (*geometry)++; | |
534 } | |
535 return value * mult; | |
536 } | |
537 | |
538 /* | |
539 */ | |
540 | |
541 /** | |
542 * gnome_parse_geometry | |
543 * @geometry: geometry string to be parsed | |
544 * @xpos: X position geometry component | |
545 * @ypos: Y position geometry component | |
546 * @width: pixel width geometry component | |
547 * @height: pixel height geometry component | |
548 * | |
549 * Description: | |
550 * Parses the geometry string passed in @geometry, and fills | |
551 * @xpos, @ypos, @width, and @height with | |
552 * the corresponding values upon completion of the parse. | |
553 * If the parse fails, it should be assumed that @xpos, @ypos, @width, | |
554 * and @height contain undefined values. | |
555 * | |
556 * Returns: | |
557 * %TRUE if the geometry was successfully parsed, %FALSE otherwise. | |
558 **/ | |
559 | |
560 static gboolean | |
561 gnome_parse_geometry (const gchar *geometry, gint *xpos, | |
562 gint *ypos, gint *width, gint *height) | |
563 { | |
564 int subtract; | |
565 | |
566 g_return_val_if_fail (xpos != NULL, FALSE); | |
567 g_return_val_if_fail (ypos != NULL, FALSE); | |
568 g_return_val_if_fail (width != NULL, FALSE); | |
569 g_return_val_if_fail (height != NULL, FALSE); | |
570 | |
571 *xpos = *ypos = *width = *height = -1; | |
572 | |
573 if (!geometry) | |
574 return FALSE; | |
575 | |
576 if (*geometry == '=') | |
577 geometry++; | |
578 if (!*geometry) | |
579 return FALSE; | |
580 if (isdigit (*geometry)) | |
581 *width = get_number (&geometry); | |
582 if (!*geometry) | |
583 return TRUE; | |
584 if (*geometry == 'x' || *geometry == 'X'){ | |
585 geometry++; | |
586 *height = get_number (&geometry); | |
587 } | |
588 if (!*geometry) | |
589 return 1; | |
590 if (*geometry == '+'){ | |
591 subtract = 0; | |
592 geometry++; | |
593 } else if (*geometry == '-'){ | |
594 subtract = gdk_screen_width (); | |
595 geometry++; | |
596 } else | |
597 return FALSE; | |
598 *xpos = get_number (&geometry); | |
599 if (subtract) | |
600 *xpos = subtract - *xpos; | |
601 if (!*geometry) | |
602 return TRUE; | |
603 if (*geometry == '+'){ | |
604 subtract = 0; | |
605 geometry++; | |
606 } else if (*geometry == '-'){ | |
607 subtract = gdk_screen_height (); | |
608 geometry++; | |
609 } else | |
610 return FALSE; | |
611 *ypos = get_number (&geometry); | |
612 if (subtract) | |
613 *ypos = subtract - *ypos; | |
614 return TRUE; | |
615 } | |
616 #endif | |
617 | |
618 static void | |
619 gtk_initialize_frame_size (struct frame *f) | |
620 { | |
621 gint x = 10, y = 10, w = 80, h = 30; | |
622 | |
623 if (STRINGP (Vgtk_initial_geometry)) | |
624 { | |
2054 | 625 if (!gnome_parse_geometry ((char*) XSTRING_DATA (Vgtk_initial_geometry), &x,&y,&w,&h)) |
462 | 626 { |
627 x = y = 10; | |
628 w = 80; | |
629 h = 30; | |
630 } | |
631 } | |
632 | |
633 /* set the position of the frame's root window now. When the | |
634 frame was created, the position was initialized to (0,0). */ | |
635 { | |
636 struct window *win = XWINDOW (f->root_window); | |
637 | |
5090 | 638 WINDOW_LEFT (win) = FRAME_PANED_LEFT_EDGE (f); |
639 WINDOW_TOP (win) = FRAME_PANED_TOP_EDGE (f); | |
462 | 640 |
641 if (!NILP (f->minibuffer_window)) | |
642 { | |
643 win = XWINDOW (f->minibuffer_window); | |
5090 | 644 WINDOW_LEFT (win) = FRAME_PANED_LEFT_EDGE (f); |
462 | 645 } |
646 } | |
647 | |
648 gtk_set_initial_frame_size (f, x, y, w, h); | |
649 } | |
650 | |
651 static gboolean | |
2286 | 652 resize_event_cb (GtkWidget *UNUSED (w), GtkAllocation *allocation, |
653 gpointer user_data) | |
462 | 654 { |
655 struct frame *f = (struct frame *) user_data; | |
656 | |
657 f->pixwidth = allocation->width; | |
658 f->pixheight = allocation->height; | |
659 | |
660 if (FRAME_GTK_TEXT_WIDGET (f)->window) | |
661 { | |
793 | 662 Lisp_Object frame = wrap_frame (f); |
663 | |
462 | 664 Fredraw_frame (frame, Qt); |
665 } | |
666 | |
667 return (FALSE); | |
668 } | |
669 | |
670 static gboolean | |
2286 | 671 delete_event_cb (GtkWidget *UNUSED (w), GdkEvent *UNUSED (ev), |
672 gpointer user_data) | |
462 | 673 { |
674 struct frame *f = (struct frame *) user_data; | |
793 | 675 Lisp_Object frame = wrap_frame (f); |
462 | 676 |
677 enqueue_misc_user_event (frame, Qeval, list3 (Qdelete_frame, frame, Qt)); | |
678 | |
679 /* See if tickling the event queue helps us with our delays when | |
680 clicking 'close' */ | |
681 signal_fake_event (); | |
682 | |
683 return (TRUE); | |
684 } | |
685 | |
686 extern gboolean emacs_shell_event_handler (GtkWidget *wid, GdkEvent *event, gpointer closure); | |
687 extern Lisp_Object build_gtk_object (GtkObject *obj); | |
688 | |
689 #ifndef GNOME_IS_APP | |
690 #define GNOME_IS_APP(x) 0 | |
691 #define gnome_app_set_contents(x,y) 0 | |
692 #endif | |
693 | |
694 static void | |
695 cleanup_deleted_frame (gpointer data) | |
696 { | |
697 struct frame *f = (struct frame *) data; | |
793 | 698 Lisp_Object frame = wrap_frame (f); |
462 | 699 |
700 Fdelete_frame (frame, Qt); | |
701 } | |
702 | |
703 #ifdef HAVE_DRAGNDROP | |
704 extern void | |
705 dragndrop_data_received (GtkWidget *widget, | |
706 GdkDragContext *context, | |
707 gint x, | |
708 gint y, | |
709 GtkSelectionData *data, | |
710 guint info, | |
711 guint time); | |
712 | |
713 extern gboolean | |
714 dragndrop_dropped (GtkWidget *widget, | |
715 GdkDragContext *drag_context, | |
716 gint x, | |
717 gint y, | |
718 guint time, | |
719 gpointer user_data); | |
720 | |
721 Lisp_Object Vcurrent_drag_object; | |
722 | |
723 #define DRAG_SELECTION_DATA_ERROR "Error converting drag data to external format" | |
724 static void | |
2286 | 725 dragndrop_get_drag (GtkWidget *UNUSED (widget), |
726 GdkDragContext *UNUSED (drag_context), | |
462 | 727 GtkSelectionData *data, |
728 guint info, | |
2286 | 729 guint UNUSED (time), |
730 gpointer UNUSED (user_data)) | |
462 | 731 { |
732 gtk_selection_data_set (data, GDK_SELECTION_TYPE_STRING, 8, | |
733 DRAG_SELECTION_DATA_ERROR, | |
734 strlen (DRAG_SELECTION_DATA_ERROR)); | |
735 | |
736 switch (info) | |
737 { | |
738 case TARGET_TYPE_STRING: | |
739 { | |
740 Lisp_Object string = Vcurrent_drag_object; | |
741 | |
742 if (!STRINGP (Vcurrent_drag_object)) | |
743 { | |
744 string = Fprin1_to_string (string, Qnil); | |
745 /* Convert to a string */ | |
746 } | |
747 | |
748 gtk_selection_data_set (data, GDK_SELECTION_TYPE_STRING, | |
749 8, XSTRING_DATA (string), XSTRING_LENGTH (string)); | |
750 } | |
751 break; | |
752 case TARGET_TYPE_URI_LIST: | |
753 break; | |
754 default: | |
755 break; | |
756 } | |
757 Vcurrent_drag_object = Qnil; | |
758 } | |
759 | |
760 DEFUN ("gtk-start-drag-internal", Fgtk_start_drag_internal, 2, 3, 0, /* | |
761 Start a GTK drag from a buffer. | |
762 First arg is the event that started the drag, | |
763 second arg should be some string, and the third | |
764 is the type of the data (this should be a MIME type as a string (ie: text/plain)). | |
765 The type defaults to text/plain. | |
766 */ | |
767 (event, data, dtyp)) | |
768 { | |
769 if (EVENTP(event)) | |
770 { | |
771 struct frame *f = decode_gtk_frame (Fselected_frame (Qnil)); | |
772 GtkWidget *wid = FRAME_GTK_TEXT_WIDGET (f); | |
773 struct Lisp_Event *lisp_event = XEVENT(event); | |
774 GdkAtom dnd_typ; | |
775 GtkTargetList *tl = gtk_target_list_new (dnd_target_table, dnd_n_targets); | |
776 | |
777 /* only drag if this is really a press */ | |
778 if (EVENT_TYPE(lisp_event) != button_press_event) | |
779 return Qnil; | |
780 | |
781 /* get the desired type */ | |
782 if (!NILP (dtyp) && STRINGP (dtyp)) | |
783 dnd_typ = gdk_atom_intern (XSTRING_DATA (dtyp), FALSE); | |
784 | |
1204 | 785 gtk_drag_begin (wid, tl, GDK_ACTION_COPY, |
786 EVENT_BUTTON_BUTTON (lisp_event), NULL); | |
462 | 787 |
788 Vcurrent_drag_object = data; | |
789 | |
790 gtk_target_list_unref (tl); | |
791 } | |
792 return Qnil; | |
793 } | |
794 #endif | |
795 | |
796 /* Creates the widgets for a frame. | |
797 lisp_window_id is a Lisp description of an X window or Xt | |
798 widget to parse. | |
799 | |
800 This function does not map the windows. (That is | |
801 done by gtk_popup_frame().) | |
802 */ | |
803 static void | |
804 gtk_create_widgets (struct frame *f, Lisp_Object lisp_window_id, Lisp_Object parent) | |
805 { | |
806 const char *name; | |
807 GtkWidget *text, *container, *shell; | |
808 gboolean embedded_p = !NILP (lisp_window_id); | |
809 #ifdef HAVE_MENUBARS | |
810 int menubar_visible; | |
811 #endif | |
812 | |
813 if (STRINGP (f->name)) | |
4981
4aebb0131297
Cleanups/renaming of EXTERNAL_TO_C_STRING and friends
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
814 name = LISP_STRING_TO_EXTERNAL (f->name, Qctext); |
462 | 815 else |
816 name = "emacs"; | |
817 | |
818 FRAME_GTK_TOP_LEVEL_FRAME_P (f) = 1; | |
819 | |
820 if (embedded_p) | |
821 { | |
822 CHECK_GTK_OBJECT (lisp_window_id); | |
823 | |
824 if (!GTK_IS_CONTAINER (XGTK_OBJECT (lisp_window_id)->object)) | |
825 { | |
563 | 826 invalid_argument ("Window ID must be a GtkContainer subclass", lisp_window_id); |
462 | 827 } |
828 | |
829 shell = gtk_vbox_new (FALSE, 0); | |
830 | |
831 gtk_object_weakref (GTK_OBJECT (shell), cleanup_deleted_frame, f); | |
832 gtk_container_add (GTK_CONTAINER (XGTK_OBJECT (lisp_window_id)->object), shell); | |
833 } | |
834 else | |
835 { | |
836 #ifdef HAVE_GNOME | |
837 shell = GTK_WIDGET (gnome_app_new ("XEmacs", "XEmacs/GNOME")); | |
838 #else | |
839 shell = GTK_WIDGET (gtk_window_new (GTK_WINDOW_TOPLEVEL)); | |
840 #endif | |
841 } | |
842 | |
843 if (!NILP (parent)) | |
844 { | |
845 /* If this is a transient window, keep the parent info around */ | |
846 GtkWidget *parentwid = FRAME_GTK_SHELL_WIDGET (XFRAME (parent)); | |
847 gtk_object_set_data (GTK_OBJECT (shell), TRANSIENT_DATA_IDENTIFIER, parentwid); | |
848 gtk_window_set_transient_for (GTK_WINDOW (shell), GTK_WINDOW (parentwid)); | |
849 } | |
850 | |
851 gtk_container_set_border_width (GTK_CONTAINER (shell), 0); | |
852 | |
2168 | 853 /* Add a mapping from widget to frame to help widget callbacks quickly find |
854 their corresponding frame. */ | |
855 gtk_object_set_data (GTK_OBJECT (shell), GTK_DATA_FRAME_IDENTIFIER, f); | |
462 | 856 |
857 FRAME_GTK_SHELL_WIDGET (f) = shell; | |
858 | |
859 text = GTK_WIDGET (gtk_xemacs_new (f)); | |
860 | |
861 if (!GNOME_IS_APP (shell)) | |
862 container = GTK_WIDGET (gtk_vbox_new (FALSE, INTERNAL_BORDER_WIDTH)); | |
863 else | |
864 container = shell; | |
865 | |
866 FRAME_GTK_CONTAINER_WIDGET (f) = container; | |
867 FRAME_GTK_TEXT_WIDGET (f) = text; | |
868 | |
869 #ifdef HAVE_DRAGNDROP | |
870 gtk_drag_dest_set (text, GTK_DEST_DEFAULT_MOTION | GTK_DEST_DEFAULT_HIGHLIGHT, | |
871 dnd_target_table, dnd_n_targets, | |
872 GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_ASK); | |
873 gtk_signal_connect (GTK_OBJECT (text), "drag_drop", | |
874 GTK_SIGNAL_FUNC (dragndrop_dropped), text); | |
875 gtk_signal_connect (GTK_OBJECT (text), "drag_data_received", | |
876 GTK_SIGNAL_FUNC (dragndrop_data_received), text); | |
877 gtk_signal_connect (GTK_OBJECT (text), "drag_data_get", | |
878 GTK_SIGNAL_FUNC (dragndrop_get_drag), NULL); | |
879 #endif | |
880 | |
881 #ifdef HAVE_MENUBARS | |
882 /* Create the initial menubar widget. */ | |
883 menubar_visible = gtk_initialize_frame_menubar (f); | |
884 | |
885 if (menubar_visible) | |
886 { | |
887 gtk_widget_show_all (FRAME_GTK_MENUBAR_WIDGET (f)); | |
888 } | |
889 #endif /* HAVE_MENUBARS */ | |
890 | |
891 if (GNOME_IS_APP (shell)) | |
892 gnome_app_set_contents (GNOME_APP (shell), text); | |
893 else | |
894 /* Now comes the drawing area, which should fill the rest of the | |
895 ** frame completely. | |
896 */ | |
897 gtk_box_pack_end (GTK_BOX (container), text, TRUE, TRUE, 0); | |
898 | |
899 /* Connect main event handler */ | |
900 gtk_signal_connect (GTK_OBJECT (shell), "delete-event", GTK_SIGNAL_FUNC (delete_event_cb), f); | |
901 | |
902 { | |
903 static char *events_to_frob[] = { "focus-in-event", | |
904 "focus-out-event", | |
905 "enter-notify-event", | |
906 "leave-notify-event", | |
907 "map-event", | |
908 "unmap-event", | |
909 "property-notify-event", | |
910 "selection-clear-event", | |
911 "selection-request-event", | |
912 "selection-notify-event", | |
913 "client-event", | |
914 /* "configure-event", */ | |
915 "visibility-notify-event", | |
916 NULL }; | |
917 int i; | |
918 | |
919 for (i = 0; events_to_frob[i]; i++) | |
920 { | |
921 gtk_signal_connect (GTK_OBJECT (shell), events_to_frob[i], | |
922 GTK_SIGNAL_FUNC (emacs_shell_event_handler), f); | |
923 } | |
924 } | |
925 | |
926 gtk_signal_connect (GTK_OBJECT (shell), "size-allocate", GTK_SIGNAL_FUNC (resize_event_cb), f); | |
927 | |
928 /* This might be safe to call now... */ | |
929 /* gtk_signal_connect (GTK_OBJECT (shell), "event", GTK_SIGNAL_FUNC (emacs_shell_event_handler), f); */ | |
930 | |
931 /* Let's make sure we get all the events we can */ | |
932 gtk_widget_set_events (text, GDK_ALL_EVENTS_MASK); | |
933 | |
934 if (shell != container) | |
935 gtk_container_add (GTK_CONTAINER (shell), container); | |
936 | |
937 gtk_widget_set_name (shell, "XEmacs::shell"); | |
938 gtk_widget_set_name (container, "XEmacs::container"); | |
939 gtk_widget_set_name (text, "XEmacs::text"); | |
940 | |
941 FRAME_GTK_LISP_WIDGETS(f)[0] = build_gtk_object (GTK_OBJECT (shell)); | |
942 FRAME_GTK_LISP_WIDGETS(f)[1] = build_gtk_object (GTK_OBJECT (container)); | |
943 FRAME_GTK_LISP_WIDGETS(f)[2] = build_gtk_object (GTK_OBJECT (text)); | |
944 | |
945 gtk_widget_realize (shell); | |
946 } | |
947 | |
948 /* create the windows for the specified frame and display them. | |
949 Note that the widgets have already been created, and any | |
950 necessary geometry calculations have already been done. */ | |
951 static void | |
952 gtk_popup_frame (struct frame *f) | |
953 { | |
954 /* */ | |
955 | |
956 if (gtk_object_get_data (GTK_OBJECT (FRAME_GTK_SHELL_WIDGET (f)), UNMAPPED_DATA_IDENTIFIER)) | |
957 { | |
958 FRAME_GTK_TOTALLY_VISIBLE_P (f) = 0; | |
959 f->visible = 0; | |
960 gtk_widget_realize (FRAME_GTK_SHELL_WIDGET (f)); | |
961 gtk_widget_realize (FRAME_GTK_TEXT_WIDGET (f)); | |
962 gtk_widget_hide_all (FRAME_GTK_SHELL_WIDGET (f)); | |
963 } | |
964 else | |
965 { | |
966 gtk_widget_show_all (FRAME_GTK_SHELL_WIDGET (f)); | |
967 } | |
968 } | |
969 | |
970 static void | |
971 allocate_gtk_frame_struct (struct frame *f) | |
972 { | |
1346 | 973 int i; |
974 | |
462 | 975 /* zero out all slots. */ |
3092 | 976 #ifdef NEW_GC |
977 f->frame_data = alloc_lrecord_type (struct gtk_frame, &lrecord_gtk_frame); | |
978 #else /* not NEW_GC */ | |
462 | 979 f->frame_data = xnew_and_zero (struct gtk_frame); |
3092 | 980 #endif /* not NEW_GC */ |
462 | 981 |
982 /* yeah, except the lisp ones */ | |
983 FRAME_GTK_ICON_PIXMAP (f) = Qnil; | |
984 FRAME_GTK_ICON_PIXMAP_MASK (f) = Qnil; | |
1346 | 985 FRAME_GTK_MENUBAR_DATA (f) = Qnil; |
986 for (i = 0; i < 3; i++) | |
987 FRAME_GTK_LISP_WIDGETS (f)[i] = Qnil; | |
2168 | 988 |
989 /* | |
4906
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
990 Hashtables of callback data for glyphs on the frame. [[ Make them EQ |
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
991 because we only use ints as keys. Otherwise we run into stickiness in |
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
992 redisplay because internal_equal() can QUIT. See |
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
993 enter_redisplay_critical_section() ]] -- probably not true any more, |
6ef8256a020a
implement equalp in C, fix case-folding, add equal() method for keymaps
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
994 now that we have internal_equal_trapping_problems(). --ben |
2168 | 995 */ |
996 FRAME_GTK_WIDGET_INSTANCE_HASH_TABLE (f) = | |
997 make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQ); | |
998 FRAME_GTK_WIDGET_CALLBACK_HASH_TABLE (f) = | |
999 make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQ); | |
1000 FRAME_GTK_WIDGET_CALLBACK_EX_HASH_TABLE (f) = | |
1001 make_lisp_hash_table (50, HASH_TABLE_VALUE_WEAK, HASH_TABLE_EQ); | |
462 | 1002 } |
1003 | |
1004 | |
1005 /************************************************************************/ | |
1006 /* Lisp functions */ | |
1007 /************************************************************************/ | |
1008 | |
1009 static void | |
771 | 1010 gtk_init_frame_1 (struct frame *f, Lisp_Object props, |
2286 | 1011 int UNUSED (frame_name_is_defaulted)) |
462 | 1012 { |
1013 /* This function can GC */ | |
1014 Lisp_Object initially_unmapped; | |
1015 Lisp_Object device = FRAME_DEVICE (f); | |
1016 Lisp_Object lisp_window_id = Fplist_get (props, Qwindow_id, Qnil); | |
1017 Lisp_Object popup = Fplist_get (props, Qpopup, Qnil); | |
1018 | |
1019 if (!NILP (popup)) | |
1020 { | |
1021 if (EQ (popup, Qt)) | |
1022 popup = Fselected_frame (device); | |
1023 CHECK_LIVE_FRAME (popup); | |
1024 if (!EQ (device, FRAME_DEVICE (XFRAME (popup)))) | |
563 | 1025 invalid_argument_2 ("Parent must be on same device as frame", |
1026 device, popup); | |
462 | 1027 } |
1028 | |
1029 initially_unmapped = Fplist_get (props, Qinitially_unmapped, Qnil); | |
1030 | |
1031 /* | |
1032 * Previously we set this only if NILP (DEVICE_SELECTED_FRAME (d)) | |
1033 * to make sure that messages were displayed as soon as possible | |
1034 * if we're creating the first frame on a device. But it is | |
1035 * better to just set this all the time, so that when a new frame | |
1036 * is created that covers the selected frame, echo area status | |
1037 * messages can still be seen. f->visible is reset later if the | |
1038 * initially-unmapped property is found to be non-nil in the | |
1039 * frame properties. | |
1040 */ | |
1041 f->visible = 1; | |
1042 | |
1043 allocate_gtk_frame_struct (f); | |
1044 gtk_create_widgets (f, lisp_window_id, popup); | |
1045 | |
1046 if (!NILP (initially_unmapped)) | |
1047 { | |
1048 gtk_object_set_data (GTK_OBJECT (FRAME_GTK_SHELL_WIDGET (f)), | |
1049 UNMAPPED_DATA_IDENTIFIER, (gpointer) 1); | |
1050 } | |
1051 } | |
1052 | |
1053 static void | |
2286 | 1054 gtk_init_frame_2 (struct frame *f, Lisp_Object UNUSED (props)) |
462 | 1055 { |
1056 /* Set up the values of the widget/frame. A case could be made for putting | |
1057 this inside of the widget's initialize method. */ | |
1058 | |
1059 update_frame_face_values (f); | |
1060 gtk_initialize_frame_size (f); | |
1061 /* Kyle: | |
1062 * update_frame_title() can't be done here, because some of the | |
1063 * modeline specs depend on the frame's device having a selected | |
1064 * frame, and that may not have been set up yet. The redisplay | |
1065 * will update the frame title anyway, so nothing is lost. | |
1066 * JV: | |
1067 * It turns out it gives problems with FVWMs name based mapping. | |
1068 * We'll just need to be carefull in the modeline specs. | |
1069 */ | |
1070 update_frame_title (f); | |
1071 } | |
1072 | |
1073 static void | |
1074 gtk_init_frame_3 (struct frame *f) | |
1075 { | |
1076 /* Pop up the frame. */ | |
1077 gtk_popup_frame (f); | |
1078 } | |
1079 | |
1080 static void | |
1081 gtk_mark_frame (struct frame *f) | |
1082 { | |
1083 mark_object (FRAME_GTK_ICON_PIXMAP (f)); | |
1084 mark_object (FRAME_GTK_ICON_PIXMAP_MASK (f)); | |
1346 | 1085 mark_object (FRAME_GTK_MENUBAR_DATA (f)); |
462 | 1086 mark_object (FRAME_GTK_LISP_WIDGETS (f)[0]); |
1087 mark_object (FRAME_GTK_LISP_WIDGETS (f)[1]); | |
1088 mark_object (FRAME_GTK_LISP_WIDGETS (f)[2]); | |
2168 | 1089 mark_object (FRAME_GTK_WIDGET_INSTANCE_HASH_TABLE (f)); |
1090 mark_object (FRAME_GTK_WIDGET_CALLBACK_HASH_TABLE (f)); | |
1091 mark_object (FRAME_GTK_WIDGET_CALLBACK_EX_HASH_TABLE (f)); | |
462 | 1092 } |
1093 | |
1094 static void | |
1095 gtk_set_frame_icon (struct frame *f) | |
1096 { | |
1097 GdkPixmap *gtk_pixmap = NULL, *gtk_mask = NULL; | |
1098 | |
1099 if (IMAGE_INSTANCEP (f->icon) | |
1100 && IMAGE_INSTANCE_PIXMAP_TYPE_P (XIMAGE_INSTANCE (f->icon))) | |
1101 { | |
1102 gtk_pixmap = XIMAGE_INSTANCE_GTK_PIXMAP (f->icon); | |
1103 gtk_mask = XIMAGE_INSTANCE_GTK_MASK (f->icon); | |
1104 } | |
1105 else | |
1106 { | |
1107 gtk_pixmap = 0; | |
1108 gtk_mask = 0; | |
1109 } | |
1110 | |
1111 gdk_window_set_icon (GET_GTK_WIDGET_WINDOW (FRAME_GTK_SHELL_WIDGET (f)), NULL, gtk_pixmap, gtk_mask); | |
1112 } | |
1113 | |
1114 static void | |
1115 gtk_set_frame_pointer (struct frame *f) | |
1116 { | |
1117 GtkWidget *w = FRAME_GTK_TEXT_WIDGET (f); | |
1118 GdkCursor *c = XIMAGE_INSTANCE_GTK_CURSOR (f->pointer); | |
1119 | |
1120 if (POINTER_IMAGE_INSTANCEP (f->pointer)) | |
1121 { | |
1122 gdk_window_set_cursor (GET_GTK_WIDGET_WINDOW (w), c); | |
1123 gdk_flush (); | |
1124 } | |
1125 else | |
1126 { | |
2500 | 1127 /* ABORT()? */ |
462 | 1128 stderr_out ("POINTER_IMAGE_INSTANCEP (f->pointer) failed!\n"); |
1129 } | |
1130 } | |
1131 | |
1132 static Lisp_Object | |
1133 gtk_get_frame_parent (struct frame *f) | |
1134 { | |
2054 | 1135 GtkWidget *parentwid = (GtkWidget*) gtk_object_get_data (GTK_OBJECT (FRAME_GTK_SHELL_WIDGET (f)), |
1136 TRANSIENT_DATA_IDENTIFIER); | |
462 | 1137 |
1138 /* find the frame whose wid is parentwid */ | |
1139 if (parentwid) | |
1140 { | |
1141 Lisp_Object frmcons; | |
1142 DEVICE_FRAME_LOOP (frmcons, XDEVICE (FRAME_DEVICE (f))) | |
1143 { | |
1144 Lisp_Object frame = XCAR (frmcons); | |
1145 if (FRAME_GTK_SHELL_WIDGET (XFRAME (frame)) == parentwid) | |
1146 return frame; | |
1147 } | |
1148 } | |
1149 return Qnil; | |
1150 } | |
1151 | |
1152 #ifdef STUPID_X_SPECIFIC_GTK_STUFF | |
1153 DEFUN ("gtk-window-id", Fgtk_window_id, 0, 1, 0, /* | |
1154 Get the ID of the Gtk window. | |
1155 This gives us a chance to manipulate the Emacs window from within a | |
1156 different program. Since the ID is an unsigned long, we return it as | |
1157 a string. | |
1158 */ | |
1159 (frame)) | |
1160 { | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
1161 Ascbyte str[255]; |
462 | 1162 struct frame *f = decode_gtk_frame (frame); |
1163 | |
1164 /* Arrrrggghhh... this defeats the whole purpose of using Gdk... do we really need this? */ | |
1165 sprintf (str, "%lu", GDK_WINDOW_XWINDOW( GET_GTK_WIDGET_WINDOW (FRAME_GTK_TEXT_WIDGET (f)))); | |
4952
19a72041c5ed
Mule-izing, various fixes related to char * arguments
Ben Wing <ben@xemacs.org>
parents:
4117
diff
changeset
|
1166 return build_ascstring (str); |
462 | 1167 } |
1168 #endif | |
1169 | |
1170 | |
1171 /************************************************************************/ | |
1172 /* manipulating the X window */ | |
1173 /************************************************************************/ | |
1174 | |
1175 static void | |
1176 gtk_set_frame_position (struct frame *f, int xoff, int yoff) | |
1177 { | |
1178 gtk_widget_set_uposition (FRAME_GTK_SHELL_WIDGET (f), xoff, yoff); | |
1179 } | |
1180 | |
1181 /* Call this to change the size of frame S's x-window. */ | |
1182 | |
1183 static void | |
1184 gtk_set_frame_size (struct frame *f, int cols, int rows) | |
1185 { | |
1186 GtkWidget *shell = FRAME_GTK_SHELL_WIDGET (f); | |
1187 GdkGeometry geometry; | |
1188 | |
1189 if (GTK_IS_WINDOW (shell)) | |
1190 { | |
2054 | 1191 GdkWindowHints geometry_mask = GDK_HINT_RESIZE_INC; |
1192 | |
462 | 1193 /* Update the cell size */ |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
1194 default_face_width_and_height (wrap_frame (f), &geometry.width_inc, |
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
1195 &geometry.height_inc); |
462 | 1196 |
1197 gtk_window_set_geometry_hints (GTK_WINDOW (shell), | |
1198 FRAME_GTK_TEXT_WIDGET (f), &geometry, geometry_mask); | |
1199 } | |
1200 | |
5043 | 1201 change_frame_size (f, cols, rows, 0); |
462 | 1202 |
1203 { | |
1204 GtkRequisition req; | |
1205 | |
1206 gtk_widget_size_request (FRAME_GTK_SHELL_WIDGET (f), &req); | |
1207 gtk_widget_set_usize (FRAME_GTK_SHELL_WIDGET (f), req.width, req.height); | |
1208 } | |
1209 } | |
1210 | |
1211 #ifdef STUPID_X_SPECIFIC_GTK_STUFF | |
1212 /* There is NO equivalent to XWarpPointer under Gtk */ | |
1213 static void | |
1214 gtk_set_mouse_position (struct window *w, int x, int y) | |
1215 { | |
1216 struct frame *f = XFRAME (w->frame); | |
1217 Display *display = GDK_DISPLAY (); | |
1218 XWarpPointer (display, None, | |
1219 GDK_WINDOW_XWINDOW (GET_GTK_WIDGET_WINDOW (FRAME_GTK_TEXT_WIDGET (f))), | |
1220 0, 0, 0, 0, w->pixel_left + x, w->pixel_top + y); | |
1221 } | |
1222 #endif /* STUPID_X_SPECIFIC_GTK_STUFF */ | |
1223 | |
1224 static int | |
1225 gtk_get_mouse_position (struct device *d, Lisp_Object *frame, int *x, int *y) | |
1226 { | |
1227 /* Returns the pixel position within the editor text widget */ | |
1228 gint win_x, win_y; | |
1229 GdkWindow *w = gdk_window_at_pointer (&win_x, &win_y); | |
1230 struct frame *f = NULL; | |
1231 | |
1232 if (!w) return (0); | |
1233 | |
1234 /* At this point, w is the innermost GdkWindow containing the | |
1235 ** pointer and win_x and win_y are the coordinates of that window. | |
1236 */ | |
1237 f = gtk_any_window_to_frame (d, w); | |
1238 | |
1239 if (!f) return (0); | |
1240 | |
793 | 1241 *frame = wrap_frame (f); |
462 | 1242 |
1243 gdk_window_get_pointer (GET_GTK_WIDGET_WINDOW (FRAME_GTK_TEXT_WIDGET (f)), | |
1244 &win_x, &win_y, NULL); | |
1245 | |
1246 *x = win_x; | |
1247 *y = win_y; | |
1248 | |
1249 return (1); | |
1250 } | |
1251 | |
2268 | 1252 static DECLARE_DOESNT_RETURN (gtk_cant_notify_wm_error (void)); |
1253 | |
1254 static DOESNT_RETURN | |
1255 gtk_cant_notify_wm_error () | |
462 | 1256 { |
563 | 1257 signal_error (Qgui_error, "Can't notify window manager of iconification", Qunbound); |
462 | 1258 } |
1259 | |
1260 /* Raise frame F. */ | |
1261 static void | |
1262 gtk_raise_frame_1 (struct frame *f, int force) | |
1263 { | |
1264 if (FRAME_VISIBLE_P (f) || force) | |
1265 { | |
1266 GdkWindow *emacs_window = GET_GTK_WIDGET_WINDOW (FRAME_GTK_SHELL_WIDGET (f)); | |
1267 | |
1268 gdk_window_raise (emacs_window); | |
1269 } | |
1270 } | |
1271 | |
1272 static void | |
1273 gtk_raise_frame (struct frame *f) | |
1274 { | |
1275 gtk_raise_frame_1 (f, 1); | |
1276 } | |
1277 | |
1278 /* Lower frame F. */ | |
1279 static void | |
1280 gtk_lower_frame (struct frame *f) | |
1281 { | |
1282 if (FRAME_VISIBLE_P (f)) | |
1283 { | |
1284 gdk_window_lower (GET_GTK_WIDGET_WINDOW (FRAME_GTK_SHELL_WIDGET (f))); | |
1285 } | |
1286 } | |
1287 | |
1288 /* Change from withdrawn state to mapped state. */ | |
1289 static void | |
1290 gtk_make_frame_visible (struct frame *f) | |
1291 { | |
2195 | 1292 gtk_widget_map (FRAME_GTK_SHELL_WIDGET (f)); |
462 | 1293 gtk_raise_frame_1 (f, 0); |
1294 } | |
1295 | |
1296 /* Change from mapped state to withdrawn state. */ | |
1297 static void | |
1298 gtk_make_frame_invisible (struct frame *f) | |
1299 { | |
2195 | 1300 gtk_widget_unmap(FRAME_GTK_SHELL_WIDGET (f)); |
462 | 1301 } |
1302 | |
1303 static int | |
1304 gtk_frame_visible_p (struct frame *f) | |
1305 { | |
1306 GtkWidget *w = FRAME_GTK_SHELL_WIDGET (f); | |
1307 | |
1308 f->visible = (GTK_OBJECT_FLAGS (w) & GTK_VISIBLE); | |
1309 | |
1310 return f->visible; | |
1311 } | |
1312 | |
1313 static int | |
1314 gtk_frame_totally_visible_p (struct frame *f) | |
1315 { | |
1316 return FRAME_GTK_TOTALLY_VISIBLE_P (f); | |
1317 } | |
1318 | |
1319 /* Change window state from mapped to iconified. */ | |
1320 static void | |
1321 gtk_iconify_frame (struct frame *f) | |
1322 { | |
1323 GdkWindow *w = GET_GTK_WIDGET_WINDOW (FRAME_GTK_SHELL_WIDGET (f)); | |
1324 | |
1325 /* There is no equivalent to XIconifyWindow in Gtk/Gdk. */ | |
1326 if (!XIconifyWindow (GDK_WINDOW_XDISPLAY (w), | |
1327 GDK_WINDOW_XWINDOW (w), | |
1328 DefaultScreen (GDK_WINDOW_XDISPLAY (w)))) | |
1329 gtk_cant_notify_wm_error (); | |
1330 | |
1331 f->iconified = 1; | |
1332 } | |
1333 | |
1334 /* Sets the X focus to frame f. */ | |
1335 static void | |
1336 gtk_focus_on_frame (struct frame *f) | |
1337 { | |
1338 GtkWidget *shell_widget; | |
1339 | |
1340 assert (FRAME_GTK_P (f)); | |
1341 | |
1342 shell_widget = FRAME_GTK_SHELL_WIDGET (f); | |
1343 if (!GET_GTK_WIDGET_WINDOW (shell_widget)) | |
1344 return; | |
1345 | |
1346 gtk_widget_grab_focus (shell_widget); | |
1347 } | |
1348 | |
1349 /* Destroy the window of frame S. */ | |
1350 static void | |
1351 gtk_delete_frame (struct frame *f) | |
1352 { | |
1353 GtkWidget *w = FRAME_GTK_SHELL_WIDGET (f); | |
1354 | |
1355 gtk_widget_destroy (w); | |
1356 | |
1357 if (FRAME_GTK_GEOM_FREE_ME_PLEASE (f)) | |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
1358 xfree (FRAME_GTK_GEOM_FREE_ME_PLEASE (f)); |
4117 | 1359 #ifndef NEW_GC |
4976
16112448d484
Rename xfree(FOO, TYPE) -> xfree(FOO)
Ben Wing <ben@xemacs.org>
parents:
4962
diff
changeset
|
1360 xfree (f->frame_data); |
3092 | 1361 #endif /* not NEW_GC */ |
462 | 1362 f->frame_data = 0; |
1363 } | |
1364 | |
1365 static void | |
1366 gtk_recompute_cell_sizes (struct frame *frm) | |
1367 { | |
1368 if (GTK_IS_WINDOW (FRAME_GTK_SHELL_WIDGET (frm))) | |
1369 { | |
1370 GtkWindow *w = GTK_WINDOW (FRAME_GTK_SHELL_WIDGET (frm)); | |
1371 GdkGeometry geometry; | |
1372 GdkWindowHints geometry_mask; | |
1373 gint width_inc = 10; | |
1374 gint height_inc = 10; | |
1375 | |
5047
07dcc7000bbf
put width before height consistently, fix a real bug found in the process
Ben Wing <ben@xemacs.org>
parents:
5043
diff
changeset
|
1376 default_face_width_and_height (wrap_frame (frm), &width_inc, &height_inc); |
462 | 1377 geometry_mask = GDK_HINT_RESIZE_INC; |
1378 geometry.width_inc = width_inc; | |
1379 geometry.height_inc = height_inc; | |
1380 | |
1381 gtk_window_set_geometry_hints (w, FRAME_GTK_TEXT_WIDGET (frm), &geometry, geometry_mask); | |
1382 } | |
1383 } | |
1384 | |
1385 static void | |
1386 gtk_update_frame_external_traits (struct frame* frm, Lisp_Object name) | |
1387 { | |
1388 Lisp_Object frame = Qnil; | |
1389 | |
793 | 1390 frame = wrap_frame (frm); |
462 | 1391 |
1392 if (EQ (name, Qforeground)) | |
1393 { | |
1394 Lisp_Object color = FACE_FOREGROUND (Vdefault_face, frame); | |
1395 GdkColor *fgc; | |
1396 | |
1397 if (!EQ (color, Vthe_null_color_instance)) | |
1398 { | |
1399 fgc = COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (color)); | |
1400 /* #### BILL!!! The X code set the XtNforeground property of | |
1401 the text widget here. Why did they bother? All that type | |
1402 of thing is done down in the guts of the redisplay code, | |
1403 not in the Emacs* widgets. */ | |
1404 } | |
1405 } | |
1406 else if (EQ (name, Qbackground)) | |
1407 { | |
1408 Lisp_Object color = FACE_BACKGROUND (Vdefault_face, frame); | |
1409 GdkColor *bgc; | |
1410 | |
1411 if (!EQ (color, Vthe_null_color_instance)) | |
1412 { | |
1413 bgc = COLOR_INSTANCE_GTK_COLOR (XCOLOR_INSTANCE (color)); | |
1414 if (FRAME_GTK_SHELL_WIDGET (frm)->window) | |
1415 { | |
1416 gdk_window_set_background (FRAME_GTK_SHELL_WIDGET (frm)->window, bgc); | |
1417 } | |
1418 if (FRAME_GTK_TEXT_WIDGET (frm)->window) | |
1419 { | |
1420 gdk_window_set_background (FRAME_GTK_TEXT_WIDGET (frm)->window, bgc); | |
1421 } | |
1422 } | |
1423 | |
1424 /* Really crappy way to force the modeline shadows to be | |
1425 redrawn. But effective. */ | |
1426 MARK_FRAME_WINDOWS_STRUCTURE_CHANGED (frm); | |
1427 MARK_FRAME_CHANGED (frm); | |
1428 } | |
1429 else if (EQ (name, Qfont)) | |
1430 { | |
1431 Lisp_Object font = FACE_FONT (Vdefault_face, frame, Vcharset_ascii); | |
1432 | |
3676 | 1433 /* It may be that instantiating the font has deleted the frame (will |
1434 happen if the user has specified a charset registry for ASCII that | |
1435 isn't available on the server, and our fallback of iso8859-1 isn't | |
1436 available; something vanishingly rare.) In that case, return from | |
1437 this function. */ | |
1438 | |
1439 if (!FRAME_LIVE_P(frm)) | |
1440 { | |
1441 return; | |
1442 } | |
1443 | |
462 | 1444 if (!EQ (font, Vthe_null_font_instance)) |
1445 { | |
1446 /* #### BILL!!! The X code set the XtNfont property of the | |
1447 text widget here. Why did they bother? All that type of | |
1448 thing is done down in the guts of the redisplay code, not | |
1449 in the Emacs* widgets. */ | |
1450 } | |
1451 } | |
1452 else | |
2500 | 1453 ABORT (); |
462 | 1454 |
1455 #ifdef HAVE_TOOLBARS | |
1456 /* Setting the background clears the entire frame area | |
1457 including the toolbar so we force an immediate redraw of | |
1458 it. */ | |
1459 if (EQ (name, Qbackground)) | |
1460 MAYBE_DEVMETH (XDEVICE (frm->device), redraw_frame_toolbars, (frm)); | |
1461 #endif /* HAVE_TOOLBARS */ | |
1462 | |
1463 /* Set window manager resize increment hints according to | |
1464 the new character size */ | |
1465 if (EQ (name, Qfont) && FRAME_GTK_TOP_LEVEL_FRAME_P (frm)) | |
1466 gtk_recompute_cell_sizes (frm); | |
1467 } | |
1468 | |
1469 | |
1470 /************************************************************************/ | |
1471 /* initialization */ | |
1472 /************************************************************************/ | |
1473 | |
1474 void | |
1475 syms_of_frame_gtk (void) | |
1476 { | |
3092 | 1477 #ifdef NEW_GC |
1478 INIT_LRECORD_IMPLEMENTATION (gtk_frame); | |
1479 #endif /* NEW_GC */ | |
1480 | |
563 | 1481 DEFSYMBOL (Qtext_widget); |
1482 DEFSYMBOL (Qcontainer_widget); | |
1483 DEFSYMBOL (Qshell_widget); | |
1484 DEFSYMBOL (Qdetachable_menubar); | |
462 | 1485 |
1486 #ifdef HAVE_DRAGNDROP | |
1487 staticpro (&Vcurrent_drag_object); | |
1488 Vcurrent_drag_object = Qnil; | |
1489 DEFSUBR (Fgtk_start_drag_internal); | |
1490 #endif | |
1491 #ifdef STUPID_X_SPECIFIC_GTK_STUFF | |
1492 DEFSUBR (Fgtk_window_id); | |
1493 #endif | |
1494 } | |
1495 | |
1496 void | |
1497 console_type_create_frame_gtk (void) | |
1498 { | |
1499 /* frame methods */ | |
1500 CONSOLE_HAS_METHOD (gtk, init_frame_1); | |
1501 CONSOLE_HAS_METHOD (gtk, init_frame_2); | |
1502 CONSOLE_HAS_METHOD (gtk, init_frame_3); | |
1503 CONSOLE_HAS_METHOD (gtk, mark_frame); | |
1504 CONSOLE_HAS_METHOD (gtk, focus_on_frame); | |
1505 CONSOLE_HAS_METHOD (gtk, delete_frame); | |
1506 CONSOLE_HAS_METHOD (gtk, get_mouse_position); | |
1507 #ifdef STUPID_X_SPECIFIC_GTK_STUFF | |
1508 CONSOLE_HAS_METHOD (gtk, set_mouse_position); | |
1509 #endif | |
1510 CONSOLE_HAS_METHOD (gtk, raise_frame); | |
1511 CONSOLE_HAS_METHOD (gtk, lower_frame); | |
1512 CONSOLE_HAS_METHOD (gtk, make_frame_visible); | |
1513 CONSOLE_HAS_METHOD (gtk, make_frame_invisible); | |
1514 CONSOLE_HAS_METHOD (gtk, iconify_frame); | |
1515 CONSOLE_HAS_METHOD (gtk, set_frame_size); | |
1516 CONSOLE_HAS_METHOD (gtk, set_frame_position); | |
1517 CONSOLE_HAS_METHOD (gtk, frame_property); | |
1518 CONSOLE_HAS_METHOD (gtk, internal_frame_property_p); | |
1519 CONSOLE_HAS_METHOD (gtk, frame_properties); | |
1520 CONSOLE_HAS_METHOD (gtk, set_frame_properties); | |
867 | 1521 CONSOLE_HAS_METHOD (gtk, set_title_from_ibyte); |
1522 CONSOLE_HAS_METHOD (gtk, set_icon_name_from_ibyte); | |
462 | 1523 CONSOLE_HAS_METHOD (gtk, frame_visible_p); |
1524 CONSOLE_HAS_METHOD (gtk, frame_totally_visible_p); | |
1525 CONSOLE_HAS_METHOD (gtk, frame_iconified_p); | |
1526 CONSOLE_HAS_METHOD (gtk, set_frame_pointer); | |
1527 CONSOLE_HAS_METHOD (gtk, set_frame_icon); | |
1528 CONSOLE_HAS_METHOD (gtk, get_frame_parent); | |
1529 CONSOLE_HAS_METHOD (gtk, update_frame_external_traits); | |
1530 } | |
1531 | |
1532 void | |
1533 vars_of_frame_gtk (void) | |
1534 { | |
1535 DEFVAR_LISP ("default-gtk-frame-plist", &Vdefault_gtk_frame_plist /* | |
1536 Plist of default frame-creation properties for Gtk frames. | |
1537 These override what is specified in the resource database and in | |
1538 `default-frame-plist', but are overridden by the arguments to the | |
1539 particular call to `make-frame'. | |
1540 | |
1541 Note: In many cases, properties of a frame are available as specifiers | |
1542 instead of through the frame-properties mechanism. | |
1543 | |
1544 Here is a list of recognized frame properties, other than those | |
1545 documented in `set-frame-properties' (they can be queried and | |
1546 set at any time, except as otherwise noted): | |
1547 | |
1548 initially-unmapped If non-nil, the frame will not be visible | |
1549 when it is created. In this case, you | |
1550 need to call `make-frame-visible' to make | |
1551 the frame appear. | |
1552 popup If non-nil, it should be a frame, and this | |
1553 frame will be created as a "popup" frame | |
1554 whose parent is the given frame. This | |
1555 will make the window manager treat the | |
1556 frame as a dialog box, which may entail | |
1557 doing different things (e.g. not asking | |
1558 for positioning, and not iconifying | |
1559 separate from its parent). | |
1560 inter-line-space Not currently implemented. | |
1561 toolbar-shadow-thickness Thickness of toolbar shadows. | |
1562 background-toolbar-color Color of toolbar background. | |
1563 bottom-toolbar-shadow-color Color of bottom shadows on toolbars. | |
1564 (*Not* specific to the bottom-toolbar.) | |
1565 top-toolbar-shadow-color Color of top shadows on toolbars. | |
1566 (*Not* specific to the top-toolbar.) | |
1567 internal-border-width Width of internal border around text area. | |
1568 border-width Width of external border around text area. | |
1569 top Y position (in pixels) of the upper-left | |
1570 outermost corner of the frame (i.e. the | |
1571 upper-left of the window-manager | |
1572 decorations). | |
1573 left X position (in pixels) of the upper-left | |
1574 outermost corner of the frame (i.e. the | |
1575 upper-left of the window-manager | |
1576 decorations). | |
1577 border-color Color of external border around text area. | |
1578 cursor-color Color of text cursor. | |
1579 | |
1580 See also `default-frame-plist', which specifies properties which apply | |
1581 to all frames, not just Gtk frames. | |
1582 */ ); | |
1583 Vdefault_gtk_frame_plist = Qnil; | |
1584 | |
1585 gtk_console_methods->device_specific_frame_props = &Vdefault_gtk_frame_plist; | |
1586 } |