aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan D <[email protected]>2010-09-12 15:23:59 +0200
committerJan D <[email protected]>2010-09-12 15:23:59 +0200
commit5f61a25c8a76b1bd2fc16872f4160956c3bd0cb5 (patch)
treef5a8763c9e7e73e9dea40fecc9f4a41686f82b9e
parent65c92e318dc297f65e2819664a22ab505be43274 (diff)
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.
-rw-r--r--src/ChangeLog8
-rw-r--r--src/xterm.c156
2 files changed, 104 insertions, 60 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index 442fc9f561..d6e3151b1f 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,11 @@
+2010-09-12 Jan Djärv <[email protected]>
+
+ * 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.
+
2010-09-11 Courtney Bane <[email protected]> (tiny change)
* term.c (tty_set_terminal_modes): Don't initialize twice (bug#7002).
diff --git a/src/xterm.c b/src/xterm.c
index 0652de165e..1fee90754f 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -8572,6 +8572,72 @@ x_set_sticky (f, new_value, old_value)
"_NET_WM_STATE_STICKY", NULL);
}
+/* Return the current _NET_WM_STATE.
+ SIZE_STATE is set to one of the FULLSCREEN_* values.
+ STICKY is set to 1 if the sticky state is set, 0 if not. */
+
+static void
+get_current_vm_state (struct frame *f,
+ Window window,
+ int *size_state,
+ int *sticky)
+{
+ 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 = 65536;
+ Display *dpy = FRAME_X_DISPLAY (f);
+ unsigned char *tmp_data = NULL;
+ Atom target_type = XA_ATOM;
+
+ *sticky = 0;
+ *size_state = FULLSCREEN_NONE;
+
+ BLOCK_INPUT;
+ x_catch_errors (dpy);
+ rc = XGetWindowProperty (dpy, window, dpyinfo->Xatom_net_wm_state,
+ 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))
+ {
+ if (tmp_data) XFree (tmp_data);
+ x_uncatch_errors ();
+ UNBLOCK_INPUT;
+ return;
+ }
+
+ x_uncatch_errors ();
+
+ for (i = 0; i < actual_size; ++i)
+ {
+ Atom a = ((Atom*)tmp_data)[i];
+ if (a == dpyinfo->Xatom_net_wm_state_maximized_horz)
+ {
+ if (*size_state == FULLSCREEN_HEIGHT)
+ *size_state = FULLSCREEN_MAXIMIZED;
+ else
+ *size_state = FULLSCREEN_WIDTH;
+ }
+ else if (a == dpyinfo->Xatom_net_wm_state_maximized_vert)
+ {
+ if (*size_state == FULLSCREEN_WIDTH)
+ *size_state = FULLSCREEN_MAXIMIZED;
+ else
+ *size_state = FULLSCREEN_HEIGHT;
+ }
+ else if (a == dpyinfo->Xatom_net_wm_state_fullscreen_atom)
+ *size_state = FULLSCREEN_BOTH;
+ else if (a == dpyinfo->Xatom_net_wm_state_sticky)
+ *sticky = 1;
+ }
+
+ if (tmp_data) XFree (tmp_data);
+ UNBLOCK_INPUT;
+}
+
/* Do fullscreen as specified in extended window manager hints */
static int
@@ -8579,13 +8645,17 @@ do_ewmh_fullscreen (f)
struct frame *f;
{
int have_net_atom = wm_supports (f, "_NET_WM_STATE");
+ Lisp_Object lval = get_frame_param (f, Qfullscreen);
+ int cur, dummy;
+
+ get_current_vm_state (f, FRAME_OUTER_WINDOW (f), &cur, &dummy);
/* Some window managers don't say they support _NET_WM_STATE, but they do say
they support _NET_WM_STATE_FULLSCREEN. Try that also. */
if (!have_net_atom)
have_net_atom = wm_supports (f, "_NET_WM_STATE_FULLSCREEN");
- if (have_net_atom)
+ if (have_net_atom && cur != f->want_fullscreen)
{
Lisp_Object frame;
const char *fs = "_NET_WM_STATE_FULLSCREEN";
@@ -8594,26 +8664,41 @@ do_ewmh_fullscreen (f)
XSETFRAME (frame, f);
- set_wm_state (frame, 0, fs, NULL);
- set_wm_state (frame, 0, fh, NULL);
- set_wm_state (frame, 0, fw, NULL);
-
- /* If there are _NET_ atoms we assume we have extended window manager
- hints. */
+ /* Keep number of calls to set_wm_state as low as possible.
+ Some window managers, or possible Gtk+, hangs when too many
+ are sent at once. */
switch (f->want_fullscreen)
{
case FULLSCREEN_BOTH:
+ if (cur == FULLSCREEN_WIDTH || cur == FULLSCREEN_MAXIMIZED
+ || cur == FULLSCREEN_HEIGHT)
+ set_wm_state (frame, 0, fw, fh);
set_wm_state (frame, 1, fs, NULL);
break;
case FULLSCREEN_WIDTH:
- set_wm_state (frame, 1, fw, NULL);
+ if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_HEIGHT
+ || cur == FULLSCREEN_MAXIMIZED)
+ set_wm_state (frame, 0, fs, fh);
+ if (cur != FULLSCREEN_MAXIMIZED)
+ set_wm_state (frame, 1, fw, NULL);
break;
case FULLSCREEN_HEIGHT:
- set_wm_state (frame, 1, fh, NULL);
+ if (cur == FULLSCREEN_BOTH || cur == FULLSCREEN_WIDTH
+ || cur == FULLSCREEN_MAXIMIZED)
+ set_wm_state (frame, 0, fs, fw);
+ if (cur != FULLSCREEN_MAXIMIZED)
+ set_wm_state (frame, 1, fh, NULL);
break;
case FULLSCREEN_MAXIMIZED:
+ if (cur == FULLSCREEN_BOTH)
+ set_wm_state (frame, 0, fs, NULL);
set_wm_state (frame, 1, fw, fh);
break;
+ case FULLSCREEN_NONE:
+ if (cur == FULLSCREEN_BOTH)
+ set_wm_state (frame, 0, fs, NULL);
+ else
+ set_wm_state (frame, 0, fw, fh);
}
f->want_fullscreen = FULLSCREEN_NONE;
@@ -8642,57 +8727,11 @@ x_handle_net_wm_state (f, event)
struct frame *f;
XPropertyEvent *event;
{
- Atom actual_type;
- unsigned long actual_size, bytes_remaining;
- int i, rc, actual_format, value = FULLSCREEN_NONE;
- struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
- long max_len = 65536;
- Display *dpy = FRAME_X_DISPLAY (f);
- unsigned char *tmp_data = NULL;
- Atom target_type = XA_ATOM;
+ int value = FULLSCREEN_NONE;
Lisp_Object lval;
int sticky = 0;
- BLOCK_INPUT;
- x_catch_errors (dpy);
- rc = XGetWindowProperty (dpy, event->window,
- event->atom, 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))
- {
- if (tmp_data) XFree (tmp_data);
- x_uncatch_errors ();
- UNBLOCK_INPUT;
- return;
- }
-
- x_uncatch_errors ();
-
- for (i = 0; i < actual_size; ++i)
- {
- Atom a = ((Atom*)tmp_data)[i];
- if (a == dpyinfo->Xatom_net_wm_state_maximized_horz)
- {
- if (value == FULLSCREEN_HEIGHT)
- value = FULLSCREEN_MAXIMIZED;
- else
- value = FULLSCREEN_WIDTH;
- }
- else if (a == dpyinfo->Xatom_net_wm_state_maximized_vert)
- {
- if (value == FULLSCREEN_WIDTH)
- value = FULLSCREEN_MAXIMIZED;
- else
- value = FULLSCREEN_HEIGHT;
- }
- else if (a == dpyinfo->Xatom_net_wm_state_fullscreen_atom)
- value = FULLSCREEN_BOTH;
- else if (a == dpyinfo->Xatom_net_wm_state_sticky)
- sticky = 1;
- }
-
+ get_current_vm_state (f, event->window, &value, &sticky);
lval = Qnil;
switch (value)
{
@@ -8712,9 +8751,6 @@ x_handle_net_wm_state (f, event)
store_frame_param (f, Qfullscreen, lval);
store_frame_param (f, Qsticky, sticky ? Qt : Qnil);
-
- if (tmp_data) XFree (tmp_data);
- UNBLOCK_INPUT;
}
/* Check if we need to resize the frame due to a fullscreen request.