aboutsummaryrefslogtreecommitdiffstats
path: root/src/xterm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xterm.c')
-rw-r--r--src/xterm.c156
1 files changed, 96 insertions, 60 deletions
diff --git a/src/xterm.c b/src/xterm.c
index 2ebe8a80378..c1d1aada530 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8285,19 +8285,89 @@ x_set_sticky (struct frame *f, Lisp_Object new_value, Lisp_Object old_value)
8285 "_NET_WM_STATE_STICKY", NULL); 8285 "_NET_WM_STATE_STICKY", NULL);
8286} 8286}
8287 8287
8288/* Return the current _NET_WM_STATE.
8289 SIZE_STATE is set to one of the FULLSCREEN_* values.
8290 STICKY is set to 1 if the sticky state is set, 0 if not. */
8291
8292static void
8293get_current_vm_state (struct frame *f,
8294 Window window,
8295 int *size_state,
8296 int *sticky)
8297{
8298 Atom actual_type;
8299 unsigned long actual_size, bytes_remaining;
8300 int i, rc, actual_format;
8301 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8302 long max_len = 65536;
8303 Display *dpy = FRAME_X_DISPLAY (f);
8304 unsigned char *tmp_data = NULL;
8305 Atom target_type = XA_ATOM;
8306
8307 *sticky = 0;
8308 *size_state = FULLSCREEN_NONE;
8309
8310 BLOCK_INPUT;
8311 x_catch_errors (dpy);
8312 rc = XGetWindowProperty (dpy, window, dpyinfo->Xatom_net_wm_state,
8313 0, max_len, False, target_type,
8314 &actual_type, &actual_format, &actual_size,
8315 &bytes_remaining, &tmp_data);
8316
8317 if (rc != Success || actual_type != target_type || x_had_errors_p (dpy))
8318 {
8319 if (tmp_data) XFree (tmp_data);
8320 x_uncatch_errors ();
8321 UNBLOCK_INPUT;
8322 return;
8323 }
8324
8325 x_uncatch_errors ();
8326
8327 for (i = 0; i < actual_size; ++i)
8328 {
8329 Atom a = ((Atom*)tmp_data)[i];
8330 if (a == dpyinfo->Xatom_net_wm_state_maximized_horz)
8331 {
8332 if (*size_state == FULLSCREEN_HEIGHT)
8333 *size_state = FULLSCREEN_MAXIMIZED;
8334 else
8335 *size_state = FULLSCREEN_WIDTH;
8336 }
8337 else if (a == dpyinfo->Xatom_net_wm_state_maximized_vert)
8338 {
8339 if (*size_state == FULLSCREEN_WIDTH)
8340 *size_state = FULLSCREEN_MAXIMIZED;
8341 else
8342 *size_state = FULLSCREEN_HEIGHT;
8343 }
8344 else if (a == dpyinfo->Xatom_net_wm_state_fullscreen_atom)
8345 *size_state = FULLSCREEN_BOTH;
8346 else if (a == dpyinfo->Xatom_net_wm_state_sticky)
8347 *sticky = 1;
8348 }
8349
8350 if (tmp_data) XFree (tmp_data);
8351 UNBLOCK_INPUT;
8352}
8353
8288/* Do fullscreen as specified in extended window manager hints */ 8354/* Do fullscreen as specified in extended window manager hints */
8289 8355
8290static int 8356static int
8291do_ewmh_fullscreen (struct frame *f) 8357do_ewmh_fullscreen (struct frame *f)
8292{ 8358{
8293 int have_net_atom = wm_supports (f, "_NET_WM_STATE"); 8359 int have_net_atom = wm_supports (f, "_NET_WM_STATE");
8360 Lisp_Object lval = get_frame_param (f, Qfullscreen);
8361 int cur, dummy;
8362
8363 get_current_vm_state (f, FRAME_OUTER_WINDOW (f), &cur, &dummy);
8294 8364
8295 /* Some window managers don't say they support _NET_WM_STATE, but they do say 8365 /* Some window managers don't say they support _NET_WM_STATE, but they do say
8296 they support _NET_WM_STATE_FULLSCREEN. Try that also. */ 8366 they support _NET_WM_STATE_FULLSCREEN. Try that also. */
8297 if (!have_net_atom) 8367 if (!have_net_atom)
8298 have_net_atom = wm_supports (f, "_NET_WM_STATE_FULLSCREEN"); 8368 have_net_atom = wm_supports (f, "_NET_WM_STATE_FULLSCREEN");
8299 8369
8300 if (have_net_atom) 8370 if (have_net_atom && cur != f->want_fullscreen)
8301 { 8371 {
8302 Lisp_Object frame; 8372 Lisp_Object frame;
8303 const char *fs = "_NET_WM_STATE_FULLSCREEN"; 8373 const char *fs = "_NET_WM_STATE_FULLSCREEN";
@@ -8306,26 +8376,41 @@ do_ewmh_fullscreen (struct frame *f)
8306 8376
8307 XSETFRAME (frame, f); 8377 XSETFRAME (frame, f);
8308 8378
8309 set_wm_state (frame, 0, fs, NULL); 8379 /* Keep number of calls to set_wm_state as low as possible.
8310 set_wm_state (frame, 0, fh, NULL); 8380 Some window managers, or possible Gtk+, hangs when too many
8311 set_wm_state (frame, 0, fw, NULL); 8381 are sent at once. */
8312
8313 /* If there are _NET_ atoms we assume we have extended window manager
8314 hints. */
8315 switch (f->want_fullscreen) 8382 switch (f->want_fullscreen)
8316 { 8383 {
8317 case FULLSCREEN_BOTH: 8384 case FULLSCREEN_BOTH:
8385 if (cur == FULLSCREEN_WIDTH || cur == FULLSCREEN_MAXIMIZED
8386 || cur == FULLSCREEN_HEIGHT)
8387 set_wm_state (frame, 0, fw, fh);
8318 set_wm_state (frame, 1, fs, NULL); 8388 set_wm_state (frame, 1, fs, NULL);
8319 break; 8389 break;
8320 case FULLSCREEN_WIDTH: 8390 case FULLSCREEN_WIDTH:
8321 set_wm_state (frame, 1, fw, NULL); 8391 if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_HEIGHT
8392 || cur == FULLSCREEN_MAXIMIZED)
8393 set_wm_state (frame, 0, fs, fh);
8394 if (cur != FULLSCREEN_MAXIMIZED)
8395 set_wm_state (frame, 1, fw, NULL);
8322 break; 8396 break;
8323 case FULLSCREEN_HEIGHT: 8397 case FULLSCREEN_HEIGHT:
8324 set_wm_state (frame, 1, fh, NULL); 8398 if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_WIDTH
8399 || cur == FULLSCREEN_MAXIMIZED)
8400 set_wm_state (frame, 0, fs, fw);
8401 if (cur != FULLSCREEN_MAXIMIZED)
8402 set_wm_state (frame, 1, fh, NULL);
8325 break; 8403 break;
8326 case FULLSCREEN_MAXIMIZED: 8404 case FULLSCREEN_MAXIMIZED:
8405 if (cur == FULLSCREEN_BOTH)
8406 set_wm_state (frame, 0, fs, NULL);
8327 set_wm_state (frame, 1, fw, fh); 8407 set_wm_state (frame, 1, fw, fh);
8328 break; 8408 break;
8409 case FULLSCREEN_NONE:
8410 if (cur == FULLSCREEN_BOTH)
8411 set_wm_state (frame, 0, fs, NULL);
8412 else
8413 set_wm_state (frame, 0, fw, fh);
8329 } 8414 }
8330 8415
8331 f->want_fullscreen = FULLSCREEN_NONE; 8416 f->want_fullscreen = FULLSCREEN_NONE;
@@ -8351,57 +8436,11 @@ XTfullscreen_hook (FRAME_PTR f)
8351static void 8436static void
8352x_handle_net_wm_state (struct frame *f, XPropertyEvent *event) 8437x_handle_net_wm_state (struct frame *f, XPropertyEvent *event)
8353{ 8438{
8354 Atom actual_type; 8439 int value = FULLSCREEN_NONE;
8355 unsigned long actual_size, bytes_remaining;
8356 int i, rc, actual_format, value = FULLSCREEN_NONE;
8357 struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8358 long max_len = 65536;
8359 Display *dpy = FRAME_X_DISPLAY (f);
8360 unsigned char *tmp_data = NULL;
8361 Atom target_type = XA_ATOM;
8362 Lisp_Object lval; 8440 Lisp_Object lval;
8363 int sticky = 0; 8441 int sticky = 0;
8364 8442
8365 BLOCK_INPUT; 8443 get_current_vm_state (f, event->window, &value, &sticky);
8366 x_catch_errors (dpy);
8367 rc = XGetWindowProperty (dpy, event->window,
8368 event->atom, 0, max_len, False, target_type,
8369 &actual_type, &actual_format, &actual_size,
8370 &bytes_remaining, &tmp_data);
8371
8372 if (rc != Success || actual_type != target_type || x_had_errors_p (dpy))
8373 {
8374 if (tmp_data) XFree (tmp_data);
8375 x_uncatch_errors ();
8376 UNBLOCK_INPUT;
8377 return;
8378 }
8379
8380 x_uncatch_errors ();
8381
8382 for (i = 0; i < actual_size; ++i)
8383 {
8384 Atom a = ((Atom*)tmp_data)[i];
8385 if (a == dpyinfo->Xatom_net_wm_state_maximized_horz)
8386 {
8387 if (value == FULLSCREEN_HEIGHT)
8388 value = FULLSCREEN_MAXIMIZED;
8389 else
8390 value = FULLSCREEN_WIDTH;
8391 }
8392 else if (a == dpyinfo->Xatom_net_wm_state_maximized_vert)
8393 {
8394 if (value == FULLSCREEN_WIDTH)
8395 value = FULLSCREEN_MAXIMIZED;
8396 else
8397 value = FULLSCREEN_HEIGHT;
8398 }
8399 else if (a == dpyinfo->Xatom_net_wm_state_fullscreen_atom)
8400 value = FULLSCREEN_BOTH;
8401 else if (a == dpyinfo->Xatom_net_wm_state_sticky)
8402 sticky = 1;
8403 }
8404
8405 lval = Qnil; 8444 lval = Qnil;
8406 switch (value) 8445 switch (value)
8407 { 8446 {
@@ -8421,9 +8460,6 @@ x_handle_net_wm_state (struct frame *f, XPropertyEvent *event)
8421 8460
8422 store_frame_param (f, Qfullscreen, lval); 8461 store_frame_param (f, Qfullscreen, lval);
8423 store_frame_param (f, Qsticky, sticky ? Qt : Qnil); 8462 store_frame_param (f, Qsticky, sticky ? Qt : Qnil);
8424
8425 if (tmp_data) XFree (tmp_data);
8426 UNBLOCK_INPUT;
8427} 8463}
8428 8464
8429/* Check if we need to resize the frame due to a fullscreen request. 8465/* Check if we need to resize the frame due to a fullscreen request.