TaskBarIcon/TopLevelWindow GetPosition() inconsistancy

Hello everyone,

I am trying to obtain the position of my TaskBarIcon, I wrote this hack that finds the top-level window and returns the position:

    def GetIconPosition(self):
        """
        Hack to find the TaskBarIcon's position
        """
        for handle in wx.GetTopLevelWindows():
            if(type(handle) == wx.TopLevelWindow):
                #handle = handle.GetHandle()
                print "handle : %s, %s" % (str(handle), str(handle.GetPosition()))
                return handle.GetPosition()

The problem is that sometimes the position is set, and sometimes not, as illustrated below :

$ python prg/wxPythonTaskBarTest3.py
handle : <wx._windows.TopLevelWindow; proxy of <Swig Object of type 'wxTopLevelWindow *' at 0x92b2630> >, (1145, 1)
handle : <wx._windows.TopLevelWindow; proxy of <Swig Object of type 'wxTopLevelWindow *' at 0x92b2630> >, (1145, 1)
$ python prg/wxPythonTaskBarTest3.py
handle : <wx._windows.TopLevelWindow; proxy of <Swig Object of type 'wxTopLevelWindow *' at 0x91ec2d0> >, (0, 0)
handle : <wx._windows.TopLevelWindow; proxy of <Swig Object of type 'wxTopLevelWindow *' at 0x91ec2d0> >, (0, 0)

I then tired to use the new event inspection tool, I clicked on find and then clicked on the taskbar icon: it is a TopLevelWindow object and it's pos is sometimes set and sometimes not.. Does anyone have an idea as of why this non-constant behavior is being observed? Does anyone have a better idea on how to get the TaskBarIcon's position?

Thank you,
Gabriel Rossetti

Gabriel Rossetti wrote:

Hello everyone,

I am trying to obtain the position of my TaskBarIcon, I wrote this hack that finds the top-level window and returns the position:

   def GetIconPosition(self):
       """
       Hack to find the TaskBarIcon's position
       """
       for handle in wx.GetTopLevelWindows():
           if(type(handle) == wx.TopLevelWindow):
               #handle = handle.GetHandle()
               print "handle : %s, %s" % (str(handle), str(handle.GetPosition()))
               return handle.GetPosition()

The problem is that sometimes the position is set, and sometimes not, as illustrated below :

$ python prg/wxPythonTaskBarTest3.py
handle : <wx._windows.TopLevelWindow; proxy of <Swig Object of type 'wxTopLevelWindow *' at 0x92b2630> >, (1145, 1)
handle : <wx._windows.TopLevelWindow; proxy of <Swig Object of type 'wxTopLevelWindow *' at 0x92b2630> >, (1145, 1)
$ python prg/wxPythonTaskBarTest3.py
handle : <wx._windows.TopLevelWindow; proxy of <Swig Object of type 'wxTopLevelWindow *' at 0x91ec2d0> >, (0, 0)
handle : <wx._windows.TopLevelWindow; proxy of <Swig Object of type 'wxTopLevelWindow *' at 0x91ec2d0> >, (0, 0)

I then tired to use the new event inspection tool, I clicked on find and then clicked on the taskbar icon: it is a TopLevelWindow object and it's pos is sometimes set and sometimes not.. Does anyone have an idea as of why this non-constant behavior is being observed? Does anyone have a better idea on how to get the TaskBarIcon's position?

Thank you,
Gabriel Rossetti

I just found wx.FindWindowAtPointer(), wx.FindWindowAtPointer() returns None when my GetIconPosition() function returns (0, 0) and the correct object (and it's coords when GetPosition() is used) when the GetIconPosition() function returns the TaskBarIcion's coordinates. Does it mean that it doesn't find the window? Does anyone know why this is being happening?

Thanks

Gabriel Rossetti wrote:

Gabriel Rossetti wrote:

Hello everyone,

I am trying to obtain the position of my TaskBarIcon, I wrote this hack that finds the top-level window and returns the position:

   def GetIconPosition(self):
       """
       Hack to find the TaskBarIcon's position
       """
       for handle in wx.GetTopLevelWindows():
           if(type(handle) == wx.TopLevelWindow):
               #handle = handle.GetHandle()
               print "handle : %s, %s" % (str(handle), str(handle.GetPosition()))
               return handle.GetPosition()

The problem is that sometimes the position is set, and sometimes not, as illustrated below :

$ python prg/wxPythonTaskBarTest3.py
handle : <wx._windows.TopLevelWindow; proxy of <Swig Object of type 'wxTopLevelWindow *' at 0x92b2630> >, (1145, 1)
handle : <wx._windows.TopLevelWindow; proxy of <Swig Object of type 'wxTopLevelWindow *' at 0x92b2630> >, (1145, 1)
$ python prg/wxPythonTaskBarTest3.py
handle : <wx._windows.TopLevelWindow; proxy of <Swig Object of type 'wxTopLevelWindow *' at 0x91ec2d0> >, (0, 0)
handle : <wx._windows.TopLevelWindow; proxy of <Swig Object of type 'wxTopLevelWindow *' at 0x91ec2d0> >, (0, 0)

I then tired to use the new event inspection tool, I clicked on find and then clicked on the taskbar icon: it is a TopLevelWindow object and it's pos is sometimes set and sometimes not.. Does anyone have an idea as of why this non-constant behavior is being observed? Does anyone have a better idea on how to get the TaskBarIcon's position?

Thank you,
Gabriel Rossetti

I just found wx.FindWindowAtPointer(), wx.FindWindowAtPointer() returns None when my GetIconPosition() function returns (0, 0) and the correct object (and it's coords when GetPosition() is used) when the GetIconPosition() function returns the TaskBarIcion's coordinates. Does it mean that it doesn't find the window? Does anyone know why this is being happening?

Thanks

I created a ticket with an example : wxTrac has been migrated to GitHub Issues - wxWidgets

Gabriel Rossetti wrote:

Hello everyone,

I am trying to obtain the position of my TaskBarIcon, I wrote this hack that finds the top-level window and returns the position:

   def GetIconPosition(self):
       """
       Hack to find the TaskBarIcon's position
       """
       for handle in wx.GetTopLevelWindows():
           if(type(handle) == wx.TopLevelWindow):
               #handle = handle.GetHandle()
               print "handle : %s, %s" % (str(handle), str(handle.GetPosition()))
               return handle.GetPosition()

The problem is that sometimes the position is set, and sometimes not, as illustrated below :

I then tired to use the new event inspection tool, I clicked on find and then clicked on the taskbar icon: it is a TopLevelWindow object and it's pos is sometimes set and sometimes not.. Does anyone have an idea as of why this non-constant behavior is being observed? Does anyone have a better idea on how to get the TaskBarIcon's position?

As I mentioned in the trac ticket about this the fact that there is a top-level window there is an implementation detail of that platform and it is not intended (nor supported) for it to be used by the application. In other words, it could disappear in any release if the implementation is changed.

It probably is possible for the wx.TaskBarIcon to officially provide its screen position, at least for GTK and Windows. Submit a feature request for it and see if anybody will do it. Or, if you're feeling adventurous you could dive into the code and do it and submit a patch for it.

Why do you need the screen location of the icon?

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Robin Dunn wrote:

Gabriel Rossetti wrote:

Hello everyone,

I am trying to obtain the position of my TaskBarIcon, I wrote this hack that finds the top-level window and returns the position:

   def GetIconPosition(self):
       """
       Hack to find the TaskBarIcon's position
       """
       for handle in wx.GetTopLevelWindows():
           if(type(handle) == wx.TopLevelWindow):
               #handle = handle.GetHandle()
               print "handle : %s, %s" % (str(handle), str(handle.GetPosition()))
               return handle.GetPosition()

The problem is that sometimes the position is set, and sometimes not, as illustrated below :

I then tired to use the new event inspection tool, I clicked on find and then clicked on the taskbar icon: it is a TopLevelWindow object and it's pos is sometimes set and sometimes not.. Does anyone have an idea as of why this non-constant behavior is being observed? Does anyone have a better idea on how to get the TaskBarIcon's position?

As I mentioned in the trac ticket about this the fact that there is a top-level window there is an implementation detail of that platform and it is not intended (nor supported) for it to be used by the application. In other words, it could disappear in any release if the implementation is changed.

It probably is possible for the wx.TaskBarIcon to officially provide its screen position, at least for GTK and Windows. Submit a feature request for it and see if anybody will do it. Or, if you're feeling adventurous you could dive into the code and do it and submit a patch for it.

Why do you need the screen location of the icon?

I need them to create a borderless wx.Frame on left-click that contains "normal" widgets, like a wx.Slider to change the volume. Since wx.Menu only accepts wx.MenuItems my idea was to obtain the TaskBarIcon's position and create a borderless wx.Frame containing the wanted widget. This way I can associate a normal menu with configuration options/actions to the right-click and my volume control to the left click.

From: wxpython-users-bounces@lists.wxwidgets.org
[mailto:wxpython-users-bounces@lists.wxwidgets.org] On Behalf
Of Gabriel Rossetti
Sent: 03 March 2009 09:19
To: wxpython-users@lists.wxwidgets.org
Subject: Re: [wxpython-users]TaskBarIcon/TopLevelWindow
GetPosition() inconsistancy

[SNIP]

>
> Why do you need the screen location of the icon?
>
I need them to create a borderless wx.Frame on left-click
that contains
"normal" widgets, like a wx.Slider to change the volume.
Since wx.Menu
only accepts wx.MenuItems my idea was to obtain the TaskBarIcon's
position and create a borderless wx.Frame containing the
wanted widget.
This way I can associate a normal menu with configuration
options/actions to the right-click and my volume control to
the left click.

Could you use the mouse position instead? I think that's fairly normal
behaviour for popup menus and similar windows.

Simon

···

-----Original Message-----

King Simon-NFHD78 wrote:

···

-----Original Message-----
From: wxpython-users-bounces@lists.wxwidgets.org [mailto:wxpython-users-bounces@lists.wxwidgets.org] On Behalf Of Gabriel Rossetti
Sent: 03 March 2009 09:19
To: wxpython-users@lists.wxwidgets.org
Subject: Re: [wxpython-users]TaskBarIcon/TopLevelWindow GetPosition() inconsistancy

[SNIP]

Why do you need the screen location of the icon?

I need them to create a borderless wx.Frame on left-click that contains "normal" widgets, like a wx.Slider to change the volume. Since wx.Menu only accepts wx.MenuItems my idea was to obtain the TaskBarIcon's position and create a borderless wx.Frame containing the wanted widget. This way I can associate a normal menu with configuration options/actions to the right-click and my volume control to the left click.
    
Could you use the mouse position instead? I think that's fairly normal
behaviour for popup menus and similar windows.

Simon
  

Well, this is what I currently do, but it makes it move round some if I click on the icon with an offset from the last click.

Gabriel

Gabriel Rossetti wrote:

King Simon-NFHD78 wrote:

From: wxpython-users-bounces@lists.wxwidgets.org [mailto:wxpython-users-bounces@lists.wxwidgets.org] On Behalf Of Gabriel Rossetti
Sent: 03 March 2009 09:19
To: wxpython-users@lists.wxwidgets.org
Subject: Re: [wxpython-users]TaskBarIcon/TopLevelWindow GetPosition() inconsistancy

[SNIP]

Why do you need the screen location of the icon?

I need them to create a borderless wx.Frame on left-click that contains "normal" widgets, like a wx.Slider to change the volume. Since wx.Menu only accepts wx.MenuItems my idea was to obtain the TaskBarIcon's position and create a borderless wx.Frame containing the wanted widget. This way I can associate a normal menu with configuration options/actions to the right-click and my volume control to the left click.
    
Could you use the mouse position instead? I think that's fairly normal
behaviour for popup menus and similar windows.

Simon
  

Well, this is what I currently do, but it makes it move round some if I click on the icon with an offset from the last click.

Gabriel

If I understand you correctly, you should be able to do this by manipulating the frame's style flags. This blog explains the flags pretty well:

http://wx-python-blog.cleanscript.com/customize-wxpython-wxframe-frame-style/

I tried to create a demo for you, but the stupid thing wouldn't refresh correctly for me, so this may or may not work...

···

-----Original Message-----

-------------------
Mike Driscoll

Blog: http://blog.pythonlibrary.org
Python Extension Building Network: http://www.pythonlibrary.org

Mike Driscoll wrote:

Gabriel Rossetti wrote:

King Simon-NFHD78 wrote:

From: wxpython-users-bounces@lists.wxwidgets.org [mailto:wxpython-users-bounces@lists.wxwidgets.org] On Behalf Of Gabriel Rossetti
Sent: 03 March 2009 09:19
To: wxpython-users@lists.wxwidgets.org
Subject: Re: [wxpython-users]TaskBarIcon/TopLevelWindow GetPosition() inconsistancy

[SNIP]

Why do you need the screen location of the icon?

I need them to create a borderless wx.Frame on left-click that contains "normal" widgets, like a wx.Slider to change the volume. Since wx.Menu only accepts wx.MenuItems my idea was to obtain the TaskBarIcon's position and create a borderless wx.Frame containing the wanted widget. This way I can associate a normal menu with configuration options/actions to the right-click and my volume control to the left click.
    
Could you use the mouse position instead? I think that's fairly normal
behaviour for popup menus and similar windows.

Simon
  

Well, this is what I currently do, but it makes it move round some if I click on the icon with an offset from the last click.

Gabriel

If I understand you correctly, you should be able to do this by manipulating the frame's style flags. This blog explains the flags pretty well:

http://wx-python-blog.cleanscript.com/customize-wxpython-wxframe-frame-style/

I tried to create a demo for you, but the stupid thing wouldn't refresh correctly for me, so this may or may not work...

-------------------
Mike Driscoll

Hello Mike,

thanks for your answer, yes, I already removed the border, I added the frame to a left click event on the menu, it opens up correctly, but since I get the mouse position, it moves around some, that is the menu is not always exactly in the same spot. Also, I can't get it to close if I click outside of my "volume control menu" like the regular menu does.

Gabriel

···

-----Original Message-----

Gabriel Rossetti wrote:

Mike Driscoll wrote:

Gabriel Rossetti wrote:

King Simon-NFHD78 wrote:

From: wxpython-users-bounces@lists.wxwidgets.org [mailto:wxpython-users-bounces@lists.wxwidgets.org] On Behalf Of Gabriel Rossetti
Sent: 03 March 2009 09:19
To: wxpython-users@lists.wxwidgets.org
Subject: Re: [wxpython-users]TaskBarIcon/TopLevelWindow GetPosition() inconsistancy

[SNIP]

Why do you need the screen location of the icon?

I need them to create a borderless wx.Frame on left-click that contains "normal" widgets, like a wx.Slider to change the volume. Since wx.Menu only accepts wx.MenuItems my idea was to obtain the TaskBarIcon's position and create a borderless wx.Frame containing the wanted widget. This way I can associate a normal menu with configuration options/actions to the right-click and my volume control to the left click.
    
Could you use the mouse position instead? I think that's fairly normal
behaviour for popup menus and similar windows.

Simon
  

Well, this is what I currently do, but it makes it move round some if I click on the icon with an offset from the last click.

Gabriel

If I understand you correctly, you should be able to do this by manipulating the frame's style flags. This blog explains the flags pretty well:

http://wx-python-blog.cleanscript.com/customize-wxpython-wxframe-frame-style/

I tried to create a demo for you, but the stupid thing wouldn't refresh correctly for me, so this may or may not work...

-------------------
Mike Driscoll

Hello Mike,

thanks for your answer, yes, I already removed the border, I added the frame to a left click event on the menu, it opens up correctly, but since I get the mouse position, it moves around some, that is the menu is not always exactly in the same spot. Also, I can't get it to close if I click outside of my "volume control menu" like the regular menu does.

Gabriel

Well, if you always want it in the same location, use the frame's SetPosition method:

myFrame.SetPosition((x,y))

Notice that it's a tuple of x/y coordinates. As for getting it to close when you click outside it, try binding the frame to EVT_KILL_FOCUS and in the handler, just call the frame's close method.

···

-----Original Message-----

-------------------
Mike Driscoll

Blog: http://blog.pythonlibrary.org
Python Extension Building Network: http://www.pythonlibrary.org

Mike Driscoll wrote:

Gabriel Rossetti wrote:

Mike Driscoll wrote:

Gabriel Rossetti wrote:

King Simon-NFHD78 wrote:

From: wxpython-users-bounces@lists.wxwidgets.org [mailto:wxpython-users-bounces@lists.wxwidgets.org] On Behalf Of Gabriel Rossetti
Sent: 03 March 2009 09:19
To: wxpython-users@lists.wxwidgets.org
Subject: Re: [wxpython-users]TaskBarIcon/TopLevelWindow GetPosition() inconsistancy

[SNIP]

Why do you need the screen location of the icon?

I need them to create a borderless wx.Frame on left-click that contains "normal" widgets, like a wx.Slider to change the volume. Since wx.Menu only accepts wx.MenuItems my idea was to obtain the TaskBarIcon's position and create a borderless wx.Frame containing the wanted widget. This way I can associate a normal menu with configuration options/actions to the right-click and my volume control to the left click.
    
Could you use the mouse position instead? I think that's fairly normal
behaviour for popup menus and similar windows.

Simon
  

Well, this is what I currently do, but it makes it move round some if I click on the icon with an offset from the last click.

Gabriel

If I understand you correctly, you should be able to do this by manipulating the frame's style flags. This blog explains the flags pretty well:

http://wx-python-blog.cleanscript.com/customize-wxpython-wxframe-frame-style/

I tried to create a demo for you, but the stupid thing wouldn't refresh correctly for me, so this may or may not work...

-------------------
Mike Driscoll

Hello Mike,

thanks for your answer, yes, I already removed the border, I added the frame to a left click event on the menu, it opens up correctly, but since I get the mouse position, it moves around some, that is the menu is not always exactly in the same spot. Also, I can't get it to close if I click outside of my "volume control menu" like the regular menu does.

Gabriel

Well, if you always want it in the same location, use the frame's SetPosition method:

myFrame.SetPosition((x,y))

Notice that it's a tuple of x/y coordinates. As for getting it to close when you click outside it, try binding the frame to EVT_KILL_FOCUS and in the handler, just call the frame's close method.

-------------------
Mike Driscoll

yes, that is my problem, I don't know how to get the TaskBarIcon's coordinates so that I may open the Frame right under it :-). As for the EVT_KILL_FOCUS, it doesn't work. The thing is that I have this borderless frame open, I can get events while my mouse is inside, but as soon as it exits the frame no more events are sent (this sounds logical, I know). I need to know when the user clicks outside of the frame so that I may close it, like a task bar menu closes when you click somewhere outside of it.

Gabriel

···

-----Original Message-----

Gabriel Rossetti wrote:

Mike Driscoll wrote:

Gabriel Rossetti wrote:

Mike Driscoll wrote:

Gabriel Rossetti wrote:

King Simon-NFHD78 wrote:

From: wxpython-users-bounces@lists.wxwidgets.org [mailto:wxpython-users-bounces@lists.wxwidgets.org] On Behalf Of Gabriel Rossetti
Sent: 03 March 2009 09:19
To: wxpython-users@lists.wxwidgets.org
Subject: Re: [wxpython-users]TaskBarIcon/TopLevelWindow GetPosition() inconsistancy

[SNIP]

Why do you need the screen location of the icon?

I need them to create a borderless wx.Frame on left-click that contains "normal" widgets, like a wx.Slider to change the volume. Since wx.Menu only accepts wx.MenuItems my idea was to obtain the TaskBarIcon's position and create a borderless wx.Frame containing the wanted widget. This way I can associate a normal menu with configuration options/actions to the right-click and my volume control to the left click.
    
Could you use the mouse position instead? I think that's fairly normal
behaviour for popup menus and similar windows.

Simon
  

Well, this is what I currently do, but it makes it move round some if I click on the icon with an offset from the last click.

Gabriel

If I understand you correctly, you should be able to do this by manipulating the frame's style flags. This blog explains the flags pretty well:

http://wx-python-blog.cleanscript.com/customize-wxpython-wxframe-frame-style/

I tried to create a demo for you, but the stupid thing wouldn't refresh correctly for me, so this may or may not work...

-------------------
Mike Driscoll

Hello Mike,

thanks for your answer, yes, I already removed the border, I added the frame to a left click event on the menu, it opens up correctly, but since I get the mouse position, it moves around some, that is the menu is not always exactly in the same spot. Also, I can't get it to close if I click outside of my "volume control menu" like the regular menu does.

Gabriel

Well, if you always want it in the same location, use the frame's SetPosition method:

myFrame.SetPosition((x,y))

Notice that it's a tuple of x/y coordinates. As for getting it to close when you click outside it, try binding the frame to EVT_KILL_FOCUS and in the handler, just call the frame's close method.

-------------------
Mike Driscoll

yes, that is my problem, I don't know how to get the TaskBarIcon's coordinates so that I may open the Frame right under it :-). As for the EVT_KILL_FOCUS, it doesn't work. The thing is that I have this borderless frame open, I can get events while my mouse is inside, but as soon as it exits the frame no more events are sent (this sounds logical, I know). I need to know when the user clicks outside of the frame so that I may close it, like a task bar menu closes when you click somewhere outside of it.

Gabriel

Ummm...on Windows, I used win32api to get the size of my screen using its GetSystemMetrics method. Then I basically subtract the size of my frame from the x,y coordinates to position a popup right above my system tray. I think wxPython has a better cross-platform way to grab the size (maybe wx.Display?) so you might go looking for that if you want to distribute beyond Windows.

Hopefully the guys who responded to your other thread on killing the app have the right solution...

Mike

···

-----Original Message-----