aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJan Djärv2010-01-15 18:04:14 +0100
committerJan Djärv2010-01-15 18:04:14 +0100
commitf0d138880a572e2b064d5af2668cd3a54a1d0a1e (patch)
tree2937eecd09b8c970643b7bf275c3fda028e7e6d6 /src
parent6554a5df3a807911922673bc46b1b74fb16c6087 (diff)
downloademacs-f0d138880a572e2b064d5af2668cd3a54a1d0a1e.tar.gz
emacs-f0d138880a572e2b064d5af2668cd3a54a1d0a1e.zip
Take desktop panels into account when sizing frames so they fit on the screen.
xfns.c (x_get_current_desktop, x_get_desktop_workarea): New functions. (Fx_create_frame): Call x_get_current_desktop and x_get_desktop_workarea to find out usable size of the desktop. Don't make frames larger than this. Bug #3643.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog7
-rw-r--r--src/xfns.c100
2 files changed, 106 insertions, 1 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 72552a34d30..98489e1d71d 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,10 @@
12010-01-15 Jan Djärv <jan.h.d@swipnet.se>
2
3 * xfns.c (x_get_current_desktop, x_get_desktop_workarea): New functions.
4 (Fx_create_frame): Call x_get_current_desktop and x_get_desktop_workarea
5 to find out usable size of the desktop. Don't make frames larger than
6 this. Bug #3643.
7
12010-01-15 Kenichi Handa <handa@m17n.org> 82010-01-15 Kenichi Handa <handa@m17n.org>
2 9
3 * xdisp.c (CHAR_COMPOSED_P): New arg END_CHARPOS. Callers changed. 10 * xdisp.c (CHAR_COMPOSED_P): New arg END_CHARPOS. Callers changed.
diff --git a/src/xfns.c b/src/xfns.c
index c24e38d9f3b..6f18e4e813a 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -3145,6 +3145,91 @@ If FRAME is nil, use the selected frame. */)
3145 return Qnil; 3145 return Qnil;
3146} 3146}
3147 3147
3148/* Return current desktop index for the display where frame F is.
3149 If we can't find out the current desktop, return 0. */
3150
3151static int
3152x_get_current_desktop (f)
3153 struct frame *f;
3154{
3155 Atom actual_type;
3156 unsigned long actual_size, bytes_remaining;
3157 int rc, actual_format;
3158 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3159 long max_len = 10;
3160 Display *dpy = FRAME_X_DISPLAY (f);
3161 long *data = NULL;
3162 int current_desktop;
3163
3164 BLOCK_INPUT;
3165 x_catch_errors (dpy);
3166 rc = XGetWindowProperty (dpy, dpyinfo->root_window,
3167 XInternAtom (dpy, "_NET_CURRENT_DESKTOP", False),
3168 0, max_len, False, XA_CARDINAL,
3169 &actual_type, &actual_format, &actual_size,
3170 &bytes_remaining, (unsigned char **)&data);
3171
3172 if (rc != Success || actual_type != XA_CARDINAL || x_had_errors_p (dpy)
3173 || actual_size == 0 || actual_format != 32)
3174 current_desktop = 0;
3175 else
3176 current_desktop = (int)*data;
3177
3178 if (data) XFree (data);
3179 x_uncatch_errors ();
3180 UNBLOCK_INPUT;
3181 return current_desktop;
3182}
3183
3184/* Return current size for DESKTOP_INDEX on the display where frame F is.
3185 If we can't find out the size, return 0, otherwise 1. */
3186
3187static int
3188x_get_desktop_workarea (f, desktop_index, deskw, deskh)
3189 struct frame *f;
3190 int desktop_index;
3191 int *deskw, *deskh;
3192{
3193 Atom actual_type;
3194 unsigned long actual_size, bytes_remaining;
3195 int rc, actual_format;
3196 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
3197 long max_len = 1000; /* This handles 250 desktops, who has that many? */
3198 Display *dpy = FRAME_X_DISPLAY (f);
3199 long *data = NULL;
3200 int retval;
3201
3202 BLOCK_INPUT;
3203 x_catch_errors (dpy);
3204 rc = XGetWindowProperty (dpy, dpyinfo->root_window,
3205 XInternAtom (dpy, "_NET_WORKAREA", False),
3206 0, max_len, False, XA_CARDINAL,
3207 &actual_type, &actual_format, &actual_size,
3208 &bytes_remaining, (unsigned char **)&data);
3209
3210 if (rc != Success || actual_type != XA_CARDINAL || x_had_errors_p (dpy)
3211 || actual_size < 3 || actual_format != 32)
3212 retval = 0;
3213 else
3214 {
3215 int idx;
3216
3217 if (actual_size == 4 /* Only one info for all desktops. */
3218 || desktop_index*4 > actual_size) /* destop_index out of range. */
3219 desktop_index = 0;
3220
3221 idx = desktop_index*4;
3222 *deskw = data[idx+2] - data[idx];
3223 *deskh = data[idx+3] - data[idx+1];
3224 retval = 1;
3225 }
3226
3227 if (data) XFree (data);
3228 x_uncatch_errors ();
3229 UNBLOCK_INPUT;
3230 return retval;
3231}
3232
3148DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame, 3233DEFUN ("x-create-frame", Fx_create_frame, Sx_create_frame,
3149 1, 1, 0, 3234 1, 1, 0,
3150 doc: /* Make a new X window, which is called a "frame" in Emacs terms. 3235 doc: /* Make a new X window, which is called a "frame" in Emacs terms.
@@ -3164,7 +3249,7 @@ This function is an internal primitive--use `make-frame' instead. */)
3164 Lisp_Object name; 3249 Lisp_Object name;
3165 int minibuffer_only = 0; 3250 int minibuffer_only = 0;
3166 long window_prompting = 0; 3251 long window_prompting = 0;
3167 int width, height; 3252 int width, height, deskw = -1, deskh = -1, current_desktop = -1;
3168 int count = SPECPDL_INDEX (); 3253 int count = SPECPDL_INDEX ();
3169 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; 3254 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
3170 Lisp_Object display; 3255 Lisp_Object display;
@@ -3440,6 +3525,12 @@ This function is an internal primitive--use `make-frame' instead. */)
3440 { 3525 {
3441 int ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f)); 3526 int ph = FRAME_TEXT_LINES_TO_PIXEL_HEIGHT (f, FRAME_LINES (f));
3442 int dph = DisplayHeight (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f)); 3527 int dph = DisplayHeight (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f));
3528 /* Some desktops have fixed menus above and/or panels below. Try to
3529 figure out the usable size we have for emacs. */
3530 current_desktop = x_get_current_desktop (f);
3531 x_get_desktop_workarea (f, current_desktop, &deskw, &deskh);
3532 if (deskh > 0 && deskh < dph) dph = deskh;
3533
3443 if (ph > dph) 3534 if (ph > dph)
3444 { 3535 {
3445 height = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, dph) - 3536 height = FRAME_PIXEL_HEIGHT_TO_TEXT_LINES (f, dph) -
@@ -3459,6 +3550,13 @@ This function is an internal primitive--use `make-frame' instead. */)
3459 { 3550 {
3460 int pw = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, FRAME_COLS (f)); 3551 int pw = FRAME_TEXT_COLS_TO_PIXEL_WIDTH (f, FRAME_COLS (f));
3461 int dpw = DisplayWidth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f)); 3552 int dpw = DisplayWidth (FRAME_X_DISPLAY (f), FRAME_X_SCREEN_NUMBER (f));
3553 if (deskw == -1)
3554 {
3555 current_desktop = x_get_current_desktop (f);
3556 x_get_desktop_workarea (f, current_desktop, &deskw, &deskh);
3557 }
3558 if (deskw > 0 && deskw < dpw) dpw = deskw;
3559
3462 if (pw > dpw) 3560 if (pw > dpw)
3463 width = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, dpw); 3561 width = FRAME_PIXEL_WIDTH_TO_TEXT_COLS (f, dpw);
3464 } 3562 }