From b77a6a7f9c876223da0152752da6b441ad7dc3ce Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jan=20Dj=C3=A4rv?= Date: Sun, 30 Oct 2011 18:17:48 +0100 Subject: [PATCH] Fix hang after C-z in gnome-shell. * xterm.c: Declare x_handle_net_wm_state to return int. (handle_one_xevent): Check if we are iconified but don't have _NET_WM_STATE_HIDDEN. If do, treat as deiconify. (get_current_wm_state): Return non-zero if not hidden, check for _NET_WM_STATE_HIDDEN (Bug#9893). (do_ewmh_fullscreen): Ignore return value from get_current_wm_state. (x_handle_net_wm_state): Return what get_current_wm_state returns. (x_term_init): Initialize dpyinfo->Xatom_net_wm_state_hidden. * xterm.h (x_display_info): Add Xatom_net_wm_state_hidden (Bug#9893). --- src/ChangeLog | 13 +++++++++++++ src/xterm.c | 42 +++++++++++++++++++++++++++++++----------- src/xterm.h | 3 ++- 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/src/ChangeLog b/src/ChangeLog index c3bdda401d3..d19cadef984 100644 --- a/src/ChangeLog +++ b/src/ChangeLog @@ -1,3 +1,16 @@ +2011-10-30 Jan Djärv + + * xterm.h (x_display_info): Add Xatom_net_wm_state_hidden (Bug#9893). + + * xterm.c: Declare x_handle_net_wm_state to return int. + (handle_one_xevent): Check if we are iconified but don't have + _NET_WM_STATE_HIDDEN. If do, treat as deiconify (Bug#9893). + (get_current_wm_state): Return non-zero if not hidden, + check for _NET_WM_STATE_HIDDEN (Bug#9893). + (do_ewmh_fullscreen): Ignore return value from get_current_wm_state. + (x_handle_net_wm_state): Return what get_current_wm_state returns. + (x_term_init): Initialize dpyinfo->Xatom_net_wm_state_hidden. + 2011-10-29 Paul Eggert * alloc.c (which_symbols): Declare EXTERNALLY_VISIBLE, diff --git a/src/xterm.c b/src/xterm.c index 333132b92cb..2275e5b6a73 100644 --- a/src/xterm.c +++ b/src/xterm.c @@ -343,7 +343,7 @@ static void x_scroll_bar_report_motion (struct frame **, Lisp_Object *, enum scroll_bar_part *, Lisp_Object *, Lisp_Object *, Time *); -static void x_handle_net_wm_state (struct frame *, XPropertyEvent *); +static int x_handle_net_wm_state (struct frame *, XPropertyEvent *); static void x_check_fullscreen (struct frame *); static void x_check_expected_move (struct frame *, int, int); static void x_sync_with_move (struct frame *, int, int, int); @@ -6113,7 +6113,19 @@ handle_one_xevent (struct x_display_info *dpyinfo, XEvent *eventptr, last_user_time = event.xproperty.time; f = x_top_window_to_frame (dpyinfo, event.xproperty.window); if (f && event.xproperty.atom == dpyinfo->Xatom_net_wm_state) - x_handle_net_wm_state (f, &event.xproperty); + if (x_handle_net_wm_state (f, &event.xproperty) && f->iconified) + { + /* Gnome shell does not iconify us when C-z is pressed. It hides + the frame. So if our state says we aren't hidden anymore, + treat is as deiconfied. */ + if (! f->async_iconified) + SET_FRAME_GARBAGED (f); + f->async_visible = 1; + f->async_iconified = 0; + f->output_data.x->has_been_visible = 1; + inev.ie.kind = DEICONIFY_EVENT; + XSETFRAME (inev.ie.frame_or_window, f); + } x_handle_property_notify (&event.xproperty); xft_settings_event (dpyinfo, &event); @@ -8415,9 +8427,11 @@ x_set_sticky (struct frame *f, Lisp_Object new_value, Lisp_Object old_value) /* 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. */ + STICKY is set to 1 if the sticky state is set, 0 if not. -static void + Return non-zero if we are not hidden, zero if we are. */ + +static int get_current_wm_state (struct frame *f, Window window, int *size_state, @@ -8425,7 +8439,7 @@ get_current_wm_state (struct frame *f, { Atom actual_type; unsigned long actual_size, bytes_remaining; - int i, rc, actual_format; + int i, rc, actual_format, is_hidden = 0; struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f); long max_len = 65536; Display *dpy = FRAME_X_DISPLAY (f); @@ -8447,7 +8461,7 @@ get_current_wm_state (struct frame *f, if (tmp_data) XFree (tmp_data); x_uncatch_errors (); UNBLOCK_INPUT; - return; + return ! f->iconified; } x_uncatch_errors (); @@ -8455,7 +8469,9 @@ get_current_wm_state (struct frame *f, for (i = 0; i < actual_size; ++i) { Atom a = ((Atom*)tmp_data)[i]; - if (a == dpyinfo->Xatom_net_wm_state_maximized_horz) + if (a == dpyinfo->Xatom_net_wm_state_hidden) + is_hidden = 1; + else if (a == dpyinfo->Xatom_net_wm_state_maximized_horz) { if (*size_state == FULLSCREEN_HEIGHT) *size_state = FULLSCREEN_MAXIMIZED; @@ -8477,6 +8493,7 @@ get_current_wm_state (struct frame *f, if (tmp_data) XFree (tmp_data); UNBLOCK_INPUT; + return ! is_hidden; } /* Do fullscreen as specified in extended window manager hints */ @@ -8488,7 +8505,7 @@ do_ewmh_fullscreen (struct frame *f) int have_net_atom = wm_supports (f, dpyinfo->Xatom_net_wm_state); int cur, dummy; - get_current_wm_state (f, FRAME_OUTER_WINDOW (f), &cur, &dummy); + (void)get_current_wm_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. */ @@ -8563,14 +8580,14 @@ XTfullscreen_hook (FRAME_PTR f) } -static void +static int x_handle_net_wm_state (struct frame *f, XPropertyEvent *event) { int value = FULLSCREEN_NONE; Lisp_Object lval; int sticky = 0; + int not_hidden = get_current_wm_state (f, event->window, &value, &sticky); - get_current_wm_state (f, event->window, &value, &sticky); lval = Qnil; switch (value) { @@ -8590,6 +8607,8 @@ x_handle_net_wm_state (struct frame *f, XPropertyEvent *event) store_frame_param (f, Qfullscreen, lval); store_frame_param (f, Qsticky, sticky ? Qt : Qnil); + + return not_hidden; } /* Check if we need to resize the frame due to a fullscreen request. @@ -9273,7 +9292,7 @@ x_iconify_frame (struct frame *f) if (!NILP (type)) x_bitmap_icon (f, type); -#ifdef USE_GTK +#if defined (USE_GTK) if (FRAME_GTK_OUTER_WIDGET (f)) { if (! FRAME_VISIBLE_P (f)) @@ -10253,6 +10272,7 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name) { "_NET_WM_STATE_MAXIMIZED_VERT", &dpyinfo->Xatom_net_wm_state_maximized_vert }, { "_NET_WM_STATE_STICKY", &dpyinfo->Xatom_net_wm_state_sticky }, + { "_NET_WM_STATE_HIDDEN", &dpyinfo->Xatom_net_wm_state_hidden }, { "_NET_WM_WINDOW_TYPE", &dpyinfo->Xatom_net_window_type }, { "_NET_WM_WINDOW_TYPE_TOOLTIP", &dpyinfo->Xatom_net_window_type_tooltip }, diff --git a/src/xterm.h b/src/xterm.h index 11d5d50d952..e10a6bc34f0 100644 --- a/src/xterm.h +++ b/src/xterm.h @@ -341,7 +341,8 @@ struct x_display_info /* Atoms dealing with EWMH (i.e. _NET_...) */ Atom Xatom_net_wm_state, Xatom_net_wm_state_fullscreen, Xatom_net_wm_state_maximized_horz, Xatom_net_wm_state_maximized_vert, - Xatom_net_wm_state_sticky, Xatom_net_frame_extents; + Xatom_net_wm_state_sticky, Xatom_net_wm_state_hidden, + Xatom_net_frame_extents; /* XSettings atoms and windows. */ Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr; -- 2.39.5