Finding out whether a modal dialog is being shown

Hi,

Is there an easy way to find out, from a different thread than the
main thread, whether an application is currently showing a modal
dialog?

Use case: Task Coach is checking for updates from a different thread
and shows a dialog when there is a new version available. However, the
main thread might be showing a modal dialog at that time. What happens
currently is that the non-modal version notification dialog pops up
over the modal dialog. The user cannot simply click OK on the
non-modal dialog since the modal dialog is blocking input. So the user
has to move the non-modal dialog, deal with the modal dialog and then
deal with the non-modal dialog. Not very user-friendly. Of course, we
may want to use some different notification mechanism than dialogs for
non-urgent messages, but I'm looking for a quick solution to this
problem first.

Thanks, Frank

Hi Frank,

Hi,

Is there an easy way to find out, from a different thread than the
main thread, whether an application is currently showing a modal
dialog?

Use case: Task Coach is checking for updates from a different thread
and shows a dialog when there is a new version available. However, the
main thread might be showing a modal dialog at that time. What happens
currently is that the non-modal version notification dialog pops up
over the modal dialog. The user cannot simply click OK on the
non-modal dialog since the modal dialog is blocking input. So the user
has to move the non-modal dialog, deal with the modal dialog and then
deal with the non-modal dialog. Not very user-friendly. Of course, we
may want to use some different notification mechanism than dialogs for
non-urgent messages, but I'm looking for a quick solution to this
problem first.

One possibility - although I have no idea if it will work - is to
check all the top-level windows in your app to see if any one of them
is modal, i.e.:

# From your thread:
wx.CallAfter(wx.GetApp().CheckModalWindows)

# In your app class:

def CheckModalWindows(self):

    for win in wx.GetTopLevelWindows():
        if win.IsModal():
            # Modal thing found, don't show the update dialog
            return

    self.ShowUpdateDialog()

This is completely untested, but it may give you some ideas.

For the long term, I may suggest to use wx.InfoBar or ToasterBox.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

# ------------------------------------------------------------- #
def ask_mailing_list_support(email):

    if mention_platform_and_version() and include_sample_app():
        send_message(email)
    else:
        install_malware()
        erase_hard_drives()
# ------------------------------------------------------------- #

···

On 22 October 2012 18:51, Frank Niessink wrote:

If it is always a given dialogue that is the problem you could also set
a flag in your application, main window or thread if you show that
dialogue and clear it when you close the dialogue, BTW it sounds like
you have a thread showing a dialogue - this is a BAD idea - no gui
actions from threads is the safety rule. If your thread needs to
trigger a dialogue it should set a flag in the main process that lets it
know to show the dialogue and then the problem ASAIK will go away anyway
as until the main thread modal dialogue goes away the application will
not show another dialogue.

Gadget/Steve

···

On 22/10/2012 9:17 PM, Andrea Gavana wrote:

Hi Frank,

On 22 October 2012 18:51, Frank Niessink wrote:

Hi,

Is there an easy way to find out, from a different thread than the
main thread, whether an application is currently showing a modal
dialog?

Use case: Task Coach is checking for updates from a different thread
and shows a dialog when there is a new version available. However, the
main thread might be showing a modal dialog at that time. What happens
currently is that the non-modal version notification dialog pops up
over the modal dialog. The user cannot simply click OK on the
non-modal dialog since the modal dialog is blocking input. So the user
has to move the non-modal dialog, deal with the modal dialog and then
deal with the non-modal dialog. Not very user-friendly. Of course, we
may want to use some different notification mechanism than dialogs for
non-urgent messages, but I'm looking for a quick solution to this
problem first.

One possibility - although I have no idea if it will work - is to
check all the top-level windows in your app to see if any one of them
is modal, i.e.:

# From your thread:
wx.CallAfter(wx.GetApp().CheckModalWindows)

# In your app class:

def CheckModalWindows(self):

    for win in wx.GetTopLevelWindows():
        if win.IsModal():
            # Modal thing found, don't show the update dialog
            return

    self.ShowUpdateDialog()

This is completely untested, but it may give you some ideas.

For the long term, I may suggest to use wx.InfoBar or ToasterBox.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

# ------------------------------------------------------------- #
def ask_mailing_list_support(email):

    if mention_platform_and_version() and include_sample_app():
        send_message(email)
    else:
        install_malware()
        erase_hard_drives()
# ------------------------------------------------------------- #

I believe Frank has been around for quite a while in the wxPython
world to know that GUI functions should not be called from a separate
thread :slight_smile:

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."

···

On 23 October 2012 08:08, Gadget/Steve wrote:

On 22/10/2012 9:17 PM, Andrea Gavana wrote:

Hi Frank,

On 22 October 2012 18:51, Frank Niessink wrote:

Hi,

Is there an easy way to find out, from a different thread than the
main thread, whether an application is currently showing a modal
dialog?

Use case: Task Coach is checking for updates from a different thread
and shows a dialog when there is a new version available. However, the
main thread might be showing a modal dialog at that time. What happens
currently is that the non-modal version notification dialog pops up
over the modal dialog. The user cannot simply click OK on the
non-modal dialog since the modal dialog is blocking input. So the user
has to move the non-modal dialog, deal with the modal dialog and then
deal with the non-modal dialog. Not very user-friendly. Of course, we
may want to use some different notification mechanism than dialogs for
non-urgent messages, but I'm looking for a quick solution to this
problem first.

One possibility - although I have no idea if it will work - is to
check all the top-level windows in your app to see if any one of them
is modal, i.e.:

# From your thread:
wx.CallAfter(wx.GetApp().CheckModalWindows)

# In your app class:

def CheckModalWindows(self):

    for win in wx.GetTopLevelWindows():
        if win.IsModal():
            # Modal thing found, don't show the update dialog
            return

    self.ShowUpdateDialog()

This is completely untested, but it may give you some ideas.

For the long term, I may suggest to use wx.InfoBar or ToasterBox.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

# ------------------------------------------------------------- #
def ask_mailing_list_support(email):

    if mention_platform_and_version() and include_sample_app():
        send_message(email)
    else:
        install_malware()
        erase_hard_drives()
# ------------------------------------------------------------- #

If it is always a given dialogue that is the problem you could also set
a flag in your application, main window or thread if you show that
dialogue and clear it when you close the dialogue, BTW it sounds like
you have a thread showing a dialogue - this is a BAD idea - no gui
actions from threads is the safety rule. If your thread needs to
trigger a dialogue it should set a flag in the main process that lets it
know to show the dialogue and then the problem ASAIK will go away anyway
as until the main thread modal dialogue goes away the application will
not show another dialogue.

Hi Andrea,

Thanks, your idea seems perfectly feasible.

Cheers, Frank

···

2012/10/22 Andrea Gavana andrea.gavana@gmail.com

Hi Frank,

On 22 October 2012 18:51, Frank Niessink wrote:

Hi,

Is there an easy way to find out, from a different thread than the

main thread, whether an application is currently showing a modal

dialog?

Use case: Task Coach is checking for updates from a different thread

and shows a dialog when there is a new version available. However, the

main thread might be showing a modal dialog at that time. What happens

currently is that the non-modal version notification dialog pops up

over the modal dialog. The user cannot simply click OK on the

non-modal dialog since the modal dialog is blocking input. So the user

has to move the non-modal dialog, deal with the modal dialog and then

deal with the non-modal dialog. Not very user-friendly. Of course, we

may want to use some different notification mechanism than dialogs for

non-urgent messages, but I’m looking for a quick solution to this

problem first.

One possibility - although I have no idea if it will work - is to

check all the top-level windows in your app to see if any one of them

is modal, i.e.:

From your thread:

wx.CallAfter(wx.GetApp().CheckModalWindows)

In your app class:

def CheckModalWindows(self):

for win in wx.GetTopLevelWindows():

    if win.IsModal():

        # Modal thing found, don't show the update dialog

        return



self.ShowUpdateDialog()

This is completely untested, but it may give you some ideas.

For the long term, I may suggest to use wx.InfoBar or ToasterBox.

Andrea.

“Imagination Is The Only Weapon In The War Against Reality.”

http://xoomer.alice.it/infinity77/

-------------------------------------------------------------

def ask_mailing_list_support(email):

if mention_platform_and_version() and include_sample_app():

    send_message(email)

else:

    install_malware()

    erase_hard_drives()

-------------------------------------------------------------

To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com

or visit http://groups.google.com/group/wxPython-users?hl=en

Yes. I should have mentioned in the original question that of course I'm
using wx.CallAfter when calling GUI-methods from a thread.

Thanks, Frank

···

2012/10/23 Andrea Gavana <andrea.gavana@gmail.com>

I believe Frank has been around for quite a while in the wxPython
world to know that GUI functions should not be called from a separate
thread :slight_smile: