diff options
| author | Jan D | 2010-09-12 15:23:59 +0200 |
|---|---|---|
| committer | Jan D | 2010-09-12 15:23:59 +0200 |
| commit | 5f61a25c8a76b1bd2fc16872f4160956c3bd0cb5 (patch) | |
| tree | f5a8763c9e7e73e9dea40fecc9f4a41686f82b9e /src | |
| parent | 65c92e318dc297f65e2819664a22ab505be43274 (diff) | |
| download | emacs-5f61a25c8a76b1bd2fc16872f4160956c3bd0cb5.tar.gz emacs-5f61a25c8a76b1bd2fc16872f4160956c3bd0cb5.zip | |
Fix bug 7013, only do send event if wanted state != current state.
* xterm.c (get_current_vm_state): New function.
(do_ewmh_fullscreen): Call get_current_vm_state and compare with
want_fullscreen so set_wm_state calls are few (Bug#7013).
(x_handle_net_wm_state): Move code to get_current_vm_state and
call that function.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 8 | ||||
| -rw-r--r-- | src/xterm.c | 156 |
2 files changed, 104 insertions, 60 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 442fc9f561e..d6e3151b1f5 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2010-09-12 Jan Djärv <jan.h.d@swipnet.se> | ||
| 2 | |||
| 3 | * xterm.c (get_current_vm_state): New function. | ||
| 4 | (do_ewmh_fullscreen): Call get_current_vm_state and compare with | ||
| 5 | want_fullscreen so set_wm_state calls are few (Bug#7013). | ||
| 6 | (x_handle_net_wm_state): Move code to get_current_vm_state and | ||
| 7 | call that function. | ||
| 8 | |||
| 1 | 2010-09-11 Courtney Bane <emacs-bugs-7626@cbane.org> (tiny change) | 9 | 2010-09-11 Courtney Bane <emacs-bugs-7626@cbane.org> (tiny change) |
| 2 | 10 | ||
| 3 | * term.c (tty_set_terminal_modes): Don't initialize twice (bug#7002). | 11 | * term.c (tty_set_terminal_modes): Don't initialize twice (bug#7002). |
diff --git a/src/xterm.c b/src/xterm.c index 0652de165ef..1fee90754fc 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -8572,6 +8572,72 @@ x_set_sticky (f, new_value, old_value) | |||
| 8572 | "_NET_WM_STATE_STICKY", NULL); | 8572 | "_NET_WM_STATE_STICKY", NULL); |
| 8573 | } | 8573 | } |
| 8574 | 8574 | ||
| 8575 | /* Return the current _NET_WM_STATE. | ||
| 8576 | SIZE_STATE is set to one of the FULLSCREEN_* values. | ||
| 8577 | STICKY is set to 1 if the sticky state is set, 0 if not. */ | ||
| 8578 | |||
| 8579 | static void | ||
| 8580 | get_current_vm_state (struct frame *f, | ||
| 8581 | Window window, | ||
| 8582 | int *size_state, | ||
| 8583 | int *sticky) | ||
| 8584 | { | ||
| 8585 | Atom actual_type; | ||
| 8586 | unsigned long actual_size, bytes_remaining; | ||
| 8587 | int i, rc, actual_format; | ||
| 8588 | struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); | ||
| 8589 | long max_len = 65536; | ||
| 8590 | Display *dpy = FRAME_X_DISPLAY (f); | ||
| 8591 | unsigned char *tmp_data = NULL; | ||
| 8592 | Atom target_type = XA_ATOM; | ||
| 8593 | |||
| 8594 | *sticky = 0; | ||
| 8595 | *size_state = FULLSCREEN_NONE; | ||
| 8596 | |||
| 8597 | BLOCK_INPUT; | ||
| 8598 | x_catch_errors (dpy); | ||
| 8599 | rc = XGetWindowProperty (dpy, window, dpyinfo->Xatom_net_wm_state, | ||
| 8600 | 0, max_len, False, target_type, | ||
| 8601 | &actual_type, &actual_format, &actual_size, | ||
| 8602 | &bytes_remaining, &tmp_data); | ||
| 8603 | |||
| 8604 | if (rc != Success || actual_type != target_type || x_had_errors_p (dpy)) | ||
| 8605 | { | ||
| 8606 | if (tmp_data) XFree (tmp_data); | ||
| 8607 | x_uncatch_errors (); | ||
| 8608 | UNBLOCK_INPUT; | ||
| 8609 | return; | ||
| 8610 | } | ||
| 8611 | |||
| 8612 | x_uncatch_errors (); | ||
| 8613 | |||
| 8614 | for (i = 0; i < actual_size; ++i) | ||
| 8615 | { | ||
| 8616 | Atom a = ((Atom*)tmp_data)[i]; | ||
| 8617 | if (a == dpyinfo->Xatom_net_wm_state_maximized_horz) | ||
| 8618 | { | ||
| 8619 | if (*size_state == FULLSCREEN_HEIGHT) | ||
| 8620 | *size_state = FULLSCREEN_MAXIMIZED; | ||
| 8621 | else | ||
| 8622 | *size_state = FULLSCREEN_WIDTH; | ||
| 8623 | } | ||
| 8624 | else if (a == dpyinfo->Xatom_net_wm_state_maximized_vert) | ||
| 8625 | { | ||
| 8626 | if (*size_state == FULLSCREEN_WIDTH) | ||
| 8627 | *size_state = FULLSCREEN_MAXIMIZED; | ||
| 8628 | else | ||
| 8629 | *size_state = FULLSCREEN_HEIGHT; | ||
| 8630 | } | ||
| 8631 | else if (a == dpyinfo->Xatom_net_wm_state_fullscreen_atom) | ||
| 8632 | *size_state = FULLSCREEN_BOTH; | ||
| 8633 | else if (a == dpyinfo->Xatom_net_wm_state_sticky) | ||
| 8634 | *sticky = 1; | ||
| 8635 | } | ||
| 8636 | |||
| 8637 | if (tmp_data) XFree (tmp_data); | ||
| 8638 | UNBLOCK_INPUT; | ||
| 8639 | } | ||
| 8640 | |||
| 8575 | /* Do fullscreen as specified in extended window manager hints */ | 8641 | /* Do fullscreen as specified in extended window manager hints */ |
| 8576 | 8642 | ||
| 8577 | static int | 8643 | static int |
| @@ -8579,13 +8645,17 @@ do_ewmh_fullscreen (f) | |||
| 8579 | struct frame *f; | 8645 | struct frame *f; |
| 8580 | { | 8646 | { |
| 8581 | int have_net_atom = wm_supports (f, "_NET_WM_STATE"); | 8647 | int have_net_atom = wm_supports (f, "_NET_WM_STATE"); |
| 8648 | Lisp_Object lval = get_frame_param (f, Qfullscreen); | ||
| 8649 | int cur, dummy; | ||
| 8650 | |||
| 8651 | get_current_vm_state (f, FRAME_OUTER_WINDOW (f), &cur, &dummy); | ||
| 8582 | 8652 | ||
| 8583 | /* Some window managers don't say they support _NET_WM_STATE, but they do say | 8653 | /* Some window managers don't say they support _NET_WM_STATE, but they do say |
| 8584 | they support _NET_WM_STATE_FULLSCREEN. Try that also. */ | 8654 | they support _NET_WM_STATE_FULLSCREEN. Try that also. */ |
| 8585 | if (!have_net_atom) | 8655 | if (!have_net_atom) |
| 8586 | have_net_atom = wm_supports (f, "_NET_WM_STATE_FULLSCREEN"); | 8656 | have_net_atom = wm_supports (f, "_NET_WM_STATE_FULLSCREEN"); |
| 8587 | 8657 | ||
| 8588 | if (have_net_atom) | 8658 | if (have_net_atom && cur != f->want_fullscreen) |
| 8589 | { | 8659 | { |
| 8590 | Lisp_Object frame; | 8660 | Lisp_Object frame; |
| 8591 | const char *fs = "_NET_WM_STATE_FULLSCREEN"; | 8661 | const char *fs = "_NET_WM_STATE_FULLSCREEN"; |
| @@ -8594,26 +8664,41 @@ do_ewmh_fullscreen (f) | |||
| 8594 | 8664 | ||
| 8595 | XSETFRAME (frame, f); | 8665 | XSETFRAME (frame, f); |
| 8596 | 8666 | ||
| 8597 | set_wm_state (frame, 0, fs, NULL); | 8667 | /* Keep number of calls to set_wm_state as low as possible. |
| 8598 | set_wm_state (frame, 0, fh, NULL); | 8668 | Some window managers, or possible Gtk+, hangs when too many |
| 8599 | set_wm_state (frame, 0, fw, NULL); | 8669 | are sent at once. */ |
| 8600 | |||
| 8601 | /* If there are _NET_ atoms we assume we have extended window manager | ||
| 8602 | hints. */ | ||
| 8603 | switch (f->want_fullscreen) | 8670 | switch (f->want_fullscreen) |
| 8604 | { | 8671 | { |
| 8605 | case FULLSCREEN_BOTH: | 8672 | case FULLSCREEN_BOTH: |
| 8673 | if (cur == FULLSCREEN_WIDTH || cur == FULLSCREEN_MAXIMIZED | ||
| 8674 | || cur == FULLSCREEN_HEIGHT) | ||
| 8675 | set_wm_state (frame, 0, fw, fh); | ||
| 8606 | set_wm_state (frame, 1, fs, NULL); | 8676 | set_wm_state (frame, 1, fs, NULL); |
| 8607 | break; | 8677 | break; |
| 8608 | case FULLSCREEN_WIDTH: | 8678 | case FULLSCREEN_WIDTH: |
| 8609 | set_wm_state (frame, 1, fw, NULL); | 8679 | if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_HEIGHT |
| 8680 | || cur == FULLSCREEN_MAXIMIZED) | ||
| 8681 | set_wm_state (frame, 0, fs, fh); | ||
| 8682 | if (cur != FULLSCREEN_MAXIMIZED) | ||
| 8683 | set_wm_state (frame, 1, fw, NULL); | ||
| 8610 | break; | 8684 | break; |
| 8611 | case FULLSCREEN_HEIGHT: | 8685 | case FULLSCREEN_HEIGHT: |
| 8612 | set_wm_state (frame, 1, fh, NULL); | 8686 | if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_WIDTH |
| 8687 | || cur == FULLSCREEN_MAXIMIZED) | ||
| 8688 | set_wm_state (frame, 0, fs, fw); | ||
| 8689 | if (cur != FULLSCREEN_MAXIMIZED) | ||
| 8690 | set_wm_state (frame, 1, fh, NULL); | ||
| 8613 | break; | 8691 | break; |
| 8614 | case FULLSCREEN_MAXIMIZED: | 8692 | case FULLSCREEN_MAXIMIZED: |
| 8693 | if (cur == FULLSCREEN_BOTH) | ||
| 8694 | set_wm_state (frame, 0, fs, NULL); | ||
| 8615 | set_wm_state (frame, 1, fw, fh); | 8695 | set_wm_state (frame, 1, fw, fh); |
| 8616 | break; | 8696 | break; |
| 8697 | case FULLSCREEN_NONE: | ||
| 8698 | if (cur == FULLSCREEN_BOTH) | ||
| 8699 | set_wm_state (frame, 0, fs, NULL); | ||
| 8700 | else | ||
| 8701 | set_wm_state (frame, 0, fw, fh); | ||
| 8617 | } | 8702 | } |
| 8618 | 8703 | ||
| 8619 | f->want_fullscreen = FULLSCREEN_NONE; | 8704 | f->want_fullscreen = FULLSCREEN_NONE; |
| @@ -8642,57 +8727,11 @@ x_handle_net_wm_state (f, event) | |||
| 8642 | struct frame *f; | 8727 | struct frame *f; |
| 8643 | XPropertyEvent *event; | 8728 | XPropertyEvent *event; |
| 8644 | { | 8729 | { |
| 8645 | Atom actual_type; | 8730 | int value = FULLSCREEN_NONE; |
| 8646 | unsigned long actual_size, bytes_remaining; | ||
| 8647 | int i, rc, actual_format, value = FULLSCREEN_NONE; | ||
| 8648 | struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); | ||
| 8649 | long max_len = 65536; | ||
| 8650 | Display *dpy = FRAME_X_DISPLAY (f); | ||
| 8651 | unsigned char *tmp_data = NULL; | ||
| 8652 | Atom target_type = XA_ATOM; | ||
| 8653 | Lisp_Object lval; | 8731 | Lisp_Object lval; |
| 8654 | int sticky = 0; | 8732 | int sticky = 0; |
| 8655 | 8733 | ||
| 8656 | BLOCK_INPUT; | 8734 | get_current_vm_state (f, event->window, &value, &sticky); |
| 8657 | x_catch_errors (dpy); | ||
| 8658 | rc = XGetWindowProperty (dpy, event->window, | ||
| 8659 | event->atom, 0, max_len, False, target_type, | ||
| 8660 | &actual_type, &actual_format, &actual_size, | ||
| 8661 | &bytes_remaining, &tmp_data); | ||
| 8662 | |||
| 8663 | if (rc != Success || actual_type != target_type || x_had_errors_p (dpy)) | ||
| 8664 | { | ||
| 8665 | if (tmp_data) XFree (tmp_data); | ||
| 8666 | x_uncatch_errors (); | ||
| 8667 | UNBLOCK_INPUT; | ||
| 8668 | return; | ||
| 8669 | } | ||
| 8670 | |||
| 8671 | x_uncatch_errors (); | ||
| 8672 | |||
| 8673 | for (i = 0; i < actual_size; ++i) | ||
| 8674 | { | ||
| 8675 | Atom a = ((Atom*)tmp_data)[i]; | ||
| 8676 | if (a == dpyinfo->Xatom_net_wm_state_maximized_horz) | ||
| 8677 | { | ||
| 8678 | if (value == FULLSCREEN_HEIGHT) | ||
| 8679 | value = FULLSCREEN_MAXIMIZED; | ||
| 8680 | else | ||
| 8681 | value = FULLSCREEN_WIDTH; | ||
| 8682 | } | ||
| 8683 | else if (a == dpyinfo->Xatom_net_wm_state_maximized_vert) | ||
| 8684 | { | ||
| 8685 | if (value == FULLSCREEN_WIDTH) | ||
| 8686 | value = FULLSCREEN_MAXIMIZED; | ||
| 8687 | else | ||
| 8688 | value = FULLSCREEN_HEIGHT; | ||
| 8689 | } | ||
| 8690 | else if (a == dpyinfo->Xatom_net_wm_state_fullscreen_atom) | ||
| 8691 | value = FULLSCREEN_BOTH; | ||
| 8692 | else if (a == dpyinfo->Xatom_net_wm_state_sticky) | ||
| 8693 | sticky = 1; | ||
| 8694 | } | ||
| 8695 | |||
| 8696 | lval = Qnil; | 8735 | lval = Qnil; |
| 8697 | switch (value) | 8736 | switch (value) |
| 8698 | { | 8737 | { |
| @@ -8712,9 +8751,6 @@ x_handle_net_wm_state (f, event) | |||
| 8712 | 8751 | ||
| 8713 | store_frame_param (f, Qfullscreen, lval); | 8752 | store_frame_param (f, Qfullscreen, lval); |
| 8714 | store_frame_param (f, Qsticky, sticky ? Qt : Qnil); | 8753 | store_frame_param (f, Qsticky, sticky ? Qt : Qnil); |
| 8715 | |||
| 8716 | if (tmp_data) XFree (tmp_data); | ||
| 8717 | UNBLOCK_INPUT; | ||
| 8718 | } | 8754 | } |
| 8719 | 8755 | ||
| 8720 | /* Check if we need to resize the frame due to a fullscreen request. | 8756 | /* Check if we need to resize the frame due to a fullscreen request. |