Bug #68802 'Close SQL Tab' save-prompt/modal dialog can fall behind WB window
Submitted: 28 Mar 2013 13:14 Modified: 12 Feb 2014 2:58
Reporter: Craig Fowler Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Workbench: SQL Editor Severity:S3 (Non-critical)
Version:6.0.2 OS:Linux (kwin Window Manager)
Assigned to: CPU Architecture:Any
Tags: gtk, kde, kwin, UI

[28 Mar 2013 13:14] Craig Fowler
Description:
When closing a script tab that carries unsaved changes in the SQL editor, a modal dialog appears prompting the user to save the script first.

This modal dialog is not properly associated with the Workbench main window, so it can 'fall behind' the main WB window by accident, leading to a potentially confusing scenario.

Because it is possible to (perhaps accidentally) raise the Workbench window above the prompt, users might not see the prompt or realise that it is there.

Whilst the prompt exists, the main Workbench window is unresponsive (as would usually be the case when a Modal dialog is waiting for user input) but some of the other normal behaviour of a modal window is not implemented.

How to repeat:
1. Connect to a database with the SQL editor and create/execute a script of some sort (any query will do).

2. Close that SQL script tab without saving - a "Close SQL Tab" prompt will appear.

3. Click the main Workbench window behind that prompt (this could occur instantly if accidentally triple-clicking to close the SQL tab, for example)

The Workbench window is raised above the prompt in the window order.  The prompt window (probably rightly) has no presence on the task/window list, although it can be reached by alt-tab.  The only other way to reach it is to realise that the main WB window can be minimised, and to find the dialog window that way.

Suggested fix:
Make better use of the UI framework's built-in modal dialog functionality, so that the prompt dialog cannot be lowered below the main Workbench window.

It would appear that in Workbench/Linux a roll-your-own solution has been used in order to implement these types of modal windows.  Whilst I'm not too familiar with GTK I'm aware that there is built-in modal window functionality which triggers a number of window behaviours (perhaps it is an underlying part of the X window system, not just GTK?):

* The main window is unresponsive whilst a modal is waiting for input

* The modal dialog cannot fall behind/below the main window in the window manager

* (because my window manager is set up accordingly) the main application window is dimmed out whilst it has a modal window waiting for user input.  This dimming-out is not functionality built into the individual application though.  It is functionality of my window manager - it occurs only because applications are using the built-in modal-window functionality.

Using the framework's modal window functionality might be a better solution to using a roll-your-own modal window solution?
[16 Apr 2013 14:59] MySQL Verification Team
Thank you for the bug report.
[2 Jul 2013 12:08] Craig Fowler
Following a conversation on IRC - it occurred to me that I could use the xprop utility to compare a "good" modal window with the modal prompt that Workbench shows.

Following are two outputs from xprop (the icon information stripped away for brevity).  The first is Workbench's modal, the second is from a Kate "Open File" dialog (which behaves properly).

As far as I can tell from a quick look - the important difference is that in Kate's open file dialog, the WM_TRANSIENT_FOR property is set to the ID of the parent window.  Perhaps this is what triggers the "cannot fall behind" functionality?

http://tronche.com/gui/x/icccm/sec-4.html#WM_TRANSIENT_FOR

---

_NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_MOVE, _NET_WM_ACTION_MINIMIZE, _NET_WM_ACTION_SHADE, _NET_WM_ACTION_CHANGE_DESKTOP, _NET_WM_ACTION_CLOSE
_KDE_NET_WM_TAB_GROUP(CARDINAL) = 9
_NET_WM_DESKTOP(CARDINAL) = 0
_KDE_NET_WM_FRAME_STRUT(CARDINAL) = 2, 2, 23, 4
_NET_FRAME_EXTENTS(CARDINAL) = 2, 2, 23, 4
WM_STATE(WM_STATE):
    window state: Normal
    icon window: 0x0
_NET_WM_STATE(ATOM) = _NET_WM_STATE_MODAL, _NET_WM_STATE_SKIP_TASKBAR
WM_HINTS(WM_HINTS):
    Client accepts input or input focus: True
    Initial state is Normal State.
    bitmap id # to use for icon: 0x540002a
    bitmap id # of mask for icon: 0x540002b
    window id # of group leader: 0x5400001
_NET_WM_SYNC_REQUEST_COUNTER(CARDINAL) = 88081329
_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_DIALOG
_KDE_NET_WM_USER_CREATION_TIME(CARDINAL) = 13238713
_NET_WM_USER_TIME(CARDINAL) = 13238713
_NET_WM_USER_TIME_WINDOW(WINDOW): window id # 0x54003b0
WM_CLIENT_LEADER(WINDOW): window id # 0x5400001
_NET_WM_PID(CARDINAL) = 9013
WM_LOCALE_NAME(STRING) = "en_GB.UTF-8"
WM_CLIENT_MACHINE(STRING) = "craig-laptop"
WM_NORMAL_HINTS(WM_SIZE_HINTS):
    program specified minimum size: 343 by 143
    program specified maximum size: 343 by 143
    window gravity: NorthWest
WM_PROTOCOLS(ATOM): protocols  WM_DELETE_WINDOW, WM_TAKE_FOCUS, _NET_WM_PING, _NET_WM_SYNC_REQUEST
WM_CLASS(STRING) = "mysql-workbench-bin", "Mysql-workbench-bin"
WM_ICON_NAME(STRING) = 
_NET_WM_ICON_NAME(UTF8_STRING) = 
WM_NAME(STRING) = 
_NET_WM_NAME(UTF8_STRING) = 

---

_NET_WM_ALLOWED_ACTIONS(ATOM) = _NET_WM_ACTION_MOVE, _NET_WM_ACTION_RESIZE, _NET_WM_ACTION_MINIMIZE, _NET_WM_ACTION_SHADE, _NET_WM_ACTION_MAXIMIZE_VERT, _NET_WM_ACTION_MAXIMIZE_HORZ, _NET_WM_ACTION_CHANGE_DESKTOP, _NET_WM_ACTION_CLOSE
_KDE_NET_WM_TAB_GROUP(CARDINAL) = 12
_NET_WM_DESKTOP(CARDINAL) = 0
_KDE_NET_WM_ACTIVITIES(STRING) = "1601d3c0-eeef-4e47-bf87-5e28e58edb2e"
_KDE_NET_WM_FRAME_STRUT(CARDINAL) = 2, 2, 23, 4
_NET_FRAME_EXTENTS(CARDINAL) = 2, 2, 23, 4
WM_STATE(WM_STATE):
    window state: Normal
    icon window: 0x0
_NET_WM_SYNC_REQUEST_COUNTER(CARDINAL) = 92275005
_NET_WM_USER_TIME(CARDINAL) = 13500117
_NET_WM_STATE(ATOM) = _NET_WM_STATE_MODAL
WM_TRANSIENT_FOR(WINDOW): window id # 0x5800012
_KDE_OXYGEN_BACKGROUND_PIXMAP(CARDINAL) = 0
_KDE_OXYGEN_BACKGROUND_GRADIENT(CARDINAL) = 1
_NET_STARTUP_ID(UTF8_STRING) = "0"
_KDE_NET_WM_USER_CREATION_TIME(CARDINAL) = 13500205

XdndAware(ATOM) = BITMAP
_MOTIF_DRAG_RECEIVER_INFO(_MOTIF_DRAG_RECEIVER_INFO) = 0x6c, 0x0, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0
_NET_WM_NAME(UTF8_STRING) = "Open File – Kate"
WM_CLIENT_LEADER(WINDOW): window id # 0x5800004
_NET_WM_PID(CARDINAL) = 9098
_NET_WM_WINDOW_TYPE(ATOM) = _NET_WM_WINDOW_TYPE_DIALOG, _NET_WM_WINDOW_TYPE_NORMAL
_MOTIF_WM_HINTS(_MOTIF_WM_HINTS) = 0x7, 0x26, 0x1e, 0x3, 0x0
WM_PROTOCOLS(ATOM): protocols  WM_DELETE_WINDOW, WM_TAKE_FOCUS, _NET_WM_PING, _NET_WM_SYNC_REQUEST, _NET_WM_CONTEXT_HELP
WM_NAME(COMPOUND_TEXT) = "Open File – Kate"
WM_LOCALE_NAME(STRING) = "en_GB.UTF-8"
WM_CLASS(STRING) = "kate", "Kate"
WM_HINTS(WM_HINTS):
    Client accepts input or input focus: True
    Initial state is Normal State.
    bitmap id # to use for icon: 0x58000d8
    window id # of group leader: 0x5800004
WM_NORMAL_HINTS(WM_SIZE_HINTS):
    user specified size: 1046 by 523
    program specified size: 1046 by 523
    program specified minimum size: 408 by 207
    window gravity: NorthWest
WM_CLIENT_MACHINE(STRING) = "craig-laptop"
WM_COMMAND(STRING) = { "/usr/bin/kate" }
[2 Jul 2013 13:02] Craig Fowler
Another update.  This issue appears to be somewhat specific to KDE & the kwin Window Manager.

I have discovered a (slightly imperfect) workaround that may be used.  It relies on KWin's "window rules" functionality.

With a 'save prompt' dialog window open, click the window icon (far left of the titlebar in my case) and choose "Configure Window Behavior".  From the KDE Control Module that appears, choose the "Window Rules" category and add a new rule.

Give the new rule a human-readable description (example "Workaround for MySQL Workbench dialogs") and choose an "Exact Match" for the Window class (application).  The match value is "mysql-workbench-bin mysql-workbench-bin" with "Match whole window class" selected.  In the Window types list, choose "Dialog Window", leave all other selections on this pane set at "Unimportant".  In the "Arrangement and Access" tab, tick the "Keep above" setting and choose "Force": "Yes".

Upon saving the new rule and choosing "OK" or "Apply" from the main rules dialog, all Workbench dialog windows will be "Always on top" of all other windows.  This is not a perfect workaround as it means that they will also be on top of other windows (that are not related to Workbench) but it means that they cannot fall behind the main Workbench window.  It is probably better than the current behavior.
[8 Jul 2013 14:42] Craig Fowler
I have just installed 6.0.2 beta and can still reproduce this issue.  Additionally I have come across an interesting test case.  In at least one place Workbench "gets modal window creation right".

When a modal window is opened to prompt for a database connection password (when connecting to a stored database instance) the modal window is created the correct way, and triggers the correct window functionality (which in my case also includes the "dim out the parent window" functionality present in kwin).  The save prompt when closing a SQL tab does not though.

I will upload two screenshots to illustrate what I mean.  It might make this issue easier to diagnose to compare the differences between how the "prompt for password" modal and the "prompt to save SQL tab" moal are created?
[8 Jul 2013 14:43] Craig Fowler
Modal created with 'correct' window behaviour.  The modal window is always-on-top of the parent Workbench window.

Attachment: Correct_modal_behaviour.png (image/png, text), 105.54 KiB.

[8 Jul 2013 14:44] Craig Fowler
Screenshot of modal created with incorrect behaviour. For example, it does not trigger kwin's "dim out parent window" function

Attachment: Incorrect_modal_behaviour.png (image/png, text), 66.82 KiB.

[12 Feb 2014 2:58] Philip Olson
Fixed as of the upcoming MySQL Workbench 6.1.2 release, and here's the changelog entry:

On Linux, when closing a script tab that carried unsaved changes in the
SQL editor, the model dialog that prompted to "save the script first"
could become hidden behind the main MySQL Workbench window.

Thank you for the bug report.