/* Functions for the X window system.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
- 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
+ 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
Free Software Foundation, Inc.
This file is part of GNU Emacs.
/* The below are defined in frame.c. */
+extern Lisp_Object Qtooltip;
+
#if GLYPH_DEBUG
int image_cache_refcount, dpyinfo_refcount;
#endif
/* Likewise, but consider only the menu bar widget. */
struct frame *
-x_menubar_window_to_frame (dpyinfo, wdesc)
+x_menubar_window_to_frame (dpyinfo, event)
struct x_display_info *dpyinfo;
- int wdesc;
+ XEvent *event;
{
+ Window wdesc = event->xany.window;
Lisp_Object tail, frame;
struct frame *f;
struct x_output *x;
if (!FRAME_X_P (f) || FRAME_X_DISPLAY_INFO (f) != dpyinfo)
continue;
x = f->output_data.x;
- /* Match if the window is this frame's menubar. */
#ifdef USE_GTK
- if (x->menubar_widget)
- {
- GtkWidget *gwdesc = xg_win_to_widget (dpyinfo->display, wdesc);
-
- /* This gives false positives, but the rectangle check in xterm.c
- where this is called takes care of that. */
- if (gwdesc != 0
- && (gwdesc == x->menubar_widget
- || gtk_widget_is_ancestor (x->menubar_widget, gwdesc)
- || gtk_widget_is_ancestor (gwdesc, x->menubar_widget)))
- return f;
- }
+ if (x->menubar_widget && xg_event_is_for_menubar (f, event))
+ return f;
#else
+ /* Match if the window is this frame's menubar. */
if (x->menubar_widget
&& lw_window_is_in_menubar (wdesc, x->menubar_widget))
return f;
int real_x = 0, real_y = 0;
int had_errors = 0;
Window win = f->output_data.x->parent_desc;
+ Atom actual_type;
+ unsigned long actual_size, bytes_remaining;
+ int i, rc, actual_format;
+ struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ long max_len = 400;
+ Display *dpy = FRAME_X_DISPLAY (f);
+ unsigned char *tmp_data = NULL;
+ Atom target_type = XA_CARDINAL;
BLOCK_INPUT;
- x_catch_errors (FRAME_X_DISPLAY (f));
+ x_catch_errors (dpy);
- if (win == FRAME_X_DISPLAY_INFO (f)->root_window)
+ if (win == dpyinfo->root_window)
win = FRAME_OUTER_WINDOW (f);
/* This loop traverses up the containment tree until we hit the root
had_errors = x_had_errors_p (FRAME_X_DISPLAY (f));
}
+
+ if (dpyinfo->root_window == f->output_data.x->parent_desc)
+ {
+ /* Try _NET_FRAME_EXTENTS if our parent is the root window. */
+ rc = XGetWindowProperty (dpy, win, dpyinfo->Xatom_net_frame_extents,
+ 0, max_len, False, target_type,
+ &actual_type, &actual_format, &actual_size,
+ &bytes_remaining, &tmp_data);
+
+ if (rc == Success && actual_type == target_type && !x_had_errors_p (dpy)
+ && actual_size == 4 && actual_format == 32)
+ {
+ int ign;
+ Window rootw;
+ long *fe = (long *)tmp_data;
+
+ XGetGeometry (FRAME_X_DISPLAY (f), win,
+ &rootw, &real_x, &real_y, &ign, &ign, &ign, &ign);
+ outer_x = -fe[0];
+ outer_y = -fe[2];
+ real_x -= fe[0];
+ real_y -= fe[2];
+ }
+ }
+
+ if (tmp_data) XFree (tmp_data);
+
x_uncatch_errors ();
UNBLOCK_INPUT;
if (FRAME_X_DISPLAY_INFO (f)->invisible_cursor == 0)
FRAME_X_DISPLAY_INFO (f)->invisible_cursor = make_invisible_cursor (f);
-
+
if (cursor != x->text_cursor
&& x->text_cursor != 0)
XFreeCursor (dpy, x->text_cursor);
if (system_font) font_param = make_string (system_font,
strlen (system_font));
}
-
+
font = !NILP (font_param) ? font_param
: x_get_arg (dpyinfo, parms, Qfont, "font", "Font", RES_TYPE_STRING);
= {
#ifdef HAVE_XFT
/* This will find the normal Xft font. */
- "monospace-12",
+ "monospace-10",
#endif
"-adobe-courier-medium-r-*-*-*-120-*-*-*-*-iso8859-1",
"-misc-fixed-medium-r-normal-*-*-140-*-*-c-*-iso8859-1",
return Qnil;
}
-/* Return current desktop index for the display where frame F is.
- If we can't find out the current desktop, return 0. */
-
-static int
-x_get_current_desktop (f)
- struct frame *f;
-{
- Atom actual_type;
- unsigned long actual_size, bytes_remaining;
- int rc, actual_format;
- struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
- long max_len = 10;
- Display *dpy = FRAME_X_DISPLAY (f);
- long *data = NULL;
- int current_desktop;
-
- BLOCK_INPUT;
- x_catch_errors (dpy);
- rc = XGetWindowProperty (dpy, dpyinfo->root_window,
- XInternAtom (dpy, "_NET_CURRENT_DESKTOP", False),
- 0, max_len, False, XA_CARDINAL,
- &actual_type, &actual_format, &actual_size,
- &bytes_remaining, (unsigned char **)&data);
-
- if (rc != Success || actual_type != XA_CARDINAL || x_had_errors_p (dpy)
- || actual_size == 0 || actual_format != 32)
- current_desktop = 0;
- else
- current_desktop = (int)*data;
-
- if (data) XFree (data);
- x_uncatch_errors ();
- UNBLOCK_INPUT;
- return current_desktop;
-}
-
-/* Return current size for DESKTOP_INDEX on the display where frame F is.
- If we can't find out the size, return 0, otherwise 1. */
-
-static int
-x_get_desktop_workarea (f, desktop_index, deskw, deskh)
- struct frame *f;
- int desktop_index;
- int *deskw, *deskh;
-{
- Atom actual_type;
- unsigned long actual_size, bytes_remaining;
- int rc, actual_format;
- struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
- long max_len = 1000; /* This handles 250 desktops, who has that many? */
- Display *dpy = FRAME_X_DISPLAY (f);
- long *data = NULL;
- int retval;
-
- BLOCK_INPUT;
- x_catch_errors (dpy);
- rc = XGetWindowProperty (dpy, dpyinfo->root_window,
- XInternAtom (dpy, "_NET_WORKAREA", False),
- 0, max_len, False, XA_CARDINAL,
- &actual_type, &actual_format, &actual_size,
- &bytes_remaining, (unsigned char **)&data);
-
- if (rc != Success || actual_type != XA_CARDINAL || x_had_errors_p (dpy)
- || actual_size < 3 || actual_format != 32)
- retval = 0;
- else
- {
- int idx;
-
- if (actual_size == 4 /* Only one info for all desktops. */
- || desktop_index*4 > actual_size) /* destop_index out of range. */
- desktop_index = 0;
-
- idx = desktop_index*4;
- *deskw = data[idx+2] - data[idx];
- *deskh = data[idx+3] - data[idx+1];
- retval = 1;
- }
-
- if (data) XFree (data);
- x_uncatch_errors ();
- UNBLOCK_INPUT;
- return retval;
-}
-
DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
1, 1, 0,
doc: /* Make a new X window, which is called a "frame" in Emacs terms.
Lisp_Object name;
int minibuffer_only = 0;
long window_prompting = 0;
- int width, height, deskw = -1, deskh = -1, current_desktop = -1;
+ int width, height;
int count = SPECPDL_INDEX ();
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
Lisp_Object display;
#ifdef USE_LUCID
/* Prevent lwlib/xlwmenu.c from crashing because of a bug
whereby it fails to get any font. */
+ BLOCK_INPUT;
xlwmenu_default_font = XLoadQueryFont (FRAME_X_DISPLAY (f), "fixed");
+ UNBLOCK_INPUT;
#endif
/* Frame contents get displaced if an embedded X window has a border. */
init_frame_faces (f);
x_default_parameter (f, parms, Qmenu_bar_lines, make_number (1),
- "menuBar", "MenuBar", RES_TYPE_NUMBER);
+ "menuBar", "MenuBar", RES_TYPE_BOOLEAN_NUMBER);
x_default_parameter (f, parms, Qtool_bar_lines, make_number (1),
"toolBar", "ToolBar", RES_TYPE_NUMBER);
x_default_parameter (f, parms, Qbuffer_predicate, Qnil,
/* Compute the size of the X window. */
window_prompting = x_figure_window_size (f, parms, 1);
- /* Don't make height higher than display height unless the user asked
- for it. Try sizes 24 and 10 if current is too large. */
- height = FRAME_LINES (f);
- tem = x_get_arg (dpyinfo, parms, Qheight, 0, 0, RES_TYPE_NUMBER);
- if (EQ (tem, Qunbound))
- {
- int h = FRAME_LINES (f) + FRAME_TOOL_BAR_LINES (f)
- + FRAME_MENU_BAR_LINES (f) + 2;
- int ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, h);
- int dph = DisplayHeight (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f));
- static int tryheight[] = { 24, 10, 0 } ;
- int i;
-
- ph += (FRAME_EXTERNAL_TOOL_BAR (f) ? 32 : 0) /* Gtk toolbar size */
- + (FRAME_EXTERNAL_MENU_BAR (f) ? 24 : 0); /* Arbitrary */
-
- /* Some desktops have fixed menus above and/or panels below. Try to
- figure out the usable size we have for emacs. */
- current_desktop = x_get_current_desktop (f);
- x_get_desktop_workarea (f, current_desktop, &deskw, &deskh);
- if (deskh > 0 && deskh < dph) dph = deskh;
-
- /* Allow 40 pixels for manager decorations. */
- for (i = 0; ph+40 > dph && tryheight[i] != 0; ++i)
- {
- height = tryheight[i];
- h = height + FRAME_TOOL_BAR_LINES (f) + FRAME_MENU_BAR_LINES (f) + 2;
- ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, h)
- + (FRAME_EXTERNAL_TOOL_BAR (f) ? 32 : 0)
- + (FRAME_EXTERNAL_MENU_BAR (f) ? 24 : 0);
- }
- }
-
- /* Don't make width wider than display width unless the user asked
- for it. */
- width = FRAME_COLS (f);
- tem = x_get_arg (dpyinfo, parms, Qwidth, 0, 0, RES_TYPE_NUMBER);
- if (EQ (tem, Qunbound))
- {
- int pw = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, FRAME_COLS (f));
- int dpw = DisplayWidth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f));
- if (deskw == -1)
- {
- current_desktop = x_get_current_desktop (f);
- x_get_desktop_workarea (f, current_desktop, &deskw, &deskh);
- }
- if (deskw > 0 && deskw < dpw) dpw = deskw;
-
- if (pw > dpw)
- width = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, dpw);
- }
-
- if (height != FRAME_LINES (f) || width != FRAME_COLS (f))
- {
- check_frame_size (f, &height, &width);
- FRAME_LINES (f) = height;
- SET_FRAME_COLS (f, width);
- }
-
-
tem = x_get_arg (dpyinfo, parms, Qunsplittable, 0, 0, RES_TYPE_BOOLEAN);
f->no_split = minibuffer_only || EQ (tem, Qt);
change_frame_size (f, height, width, 1, 0, 0);
/* Add `tooltip' frame parameter's default value. */
- if (NILP (Fframe_parameter (frame, intern ("tooltip"))))
- Fmodify_frame_parameters (frame, Fcons (Fcons (intern ("tooltip"), Qt),
- Qnil));
+ if (NILP (Fframe_parameter (frame, Qtooltip)))
+ Fmodify_frame_parameters (frame, Fcons (Fcons (Qtooltip, Qt), Qnil));
/* FIXME - can this be done in a similar way to normal frames?
http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00641.html */
clear_glyph_matrix (w->desired_matrix);
clear_glyph_matrix (w->current_matrix);
SET_TEXT_POS (pos, BEGV, BEGV_BYTE);
- try_window (FRAME_ROOT_WINDOW (f), pos, 0);
+ try_window (FRAME_ROOT_WINDOW (f), pos, TRY_WINDOW_IGNORE_FONTS_CHANGE);
/* Compute width and height of the tooltip. */
width = height = 0;
font_param = Ffont_get (font, intern (":name"));
if (STRINGP (font_param))
default_name = xstrdup (SDATA (font_param));
- else
+ else
{
font_param = Fframe_parameter (frame, Qfont_param);
if (STRINGP (font_param))
default_name = xstrdup (x_last_font_name);
/* Convert fontconfig names to Gtk names, i.e. remove - before number */
- if (default_name)
+ if (default_name)
{
char *p = strrchr (default_name, '-');
if (p)
Vx_cursor_fore_pixel = Qnil;
DEFVAR_LISP ("x-max-tooltip-size", &Vx_max_tooltip_size,
- doc: /* Maximum size for tooltips. Value is a pair (COLUMNS . ROWS).
-Text larger than this is clipped. */);
+ doc: /* Maximum size for tooltips.
+Value is a pair (COLUMNS . ROWS). Text larger than this is clipped. */);
Vx_max_tooltip_size = Fcons (make_number (80), make_number (40));
DEFVAR_LISP ("x-no-window-manager", &Vx_no_window_manager,