update position for widgets in native containers, fixes #15231
[wxWidgets.git] / src / gtk / notifmsg.cpp
1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/notifmsg.cpp
3 // Purpose: wxNotificationMessage for wxGTK using libnotify.
4 // Author: Vadim Zeitlin
5 // Created: 2012-07-25
6 // RCS-ID: $Id$
7 // Copyright: (c) 2012 Vadim Zeitlin <vadim@wxwidgets.org>
8 // Licence: wxWindows licence
9 ///////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 // for compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #if wxUSE_NOTIFICATION_MESSAGE && wxUSE_LIBNOTIFY
27
28 #include "wx/notifmsg.h"
29
30 #ifndef WX_PRECOMP
31 #include "wx/app.h"
32 #endif // WX_PRECOMP
33
34 #include <libnotify/notify.h>
35
36 #include "wx/module.h"
37
38 // General note about error handling: as notifications are meant to be
39 // non-intrusive, we use wxLogDebug() and not wxLogError() if anything goes
40 // wrong here to avoid spamming the user with message boxes. As all methods
41 // return boolean indicating success or failure, the caller could show the
42 // notification in some other way or notify about the error itself if needed.
43 #include "wx/gtk/private/error.h"
44
45 // ----------------------------------------------------------------------------
46 // A module for cleaning up libnotify on exit.
47 // ----------------------------------------------------------------------------
48
49 class wxLibnotifyModule : public wxModule
50 {
51 public:
52 virtual bool OnInit()
53 {
54 // We're initialized on demand.
55 return true;
56 }
57
58 virtual void OnExit()
59 {
60 if ( notify_is_initted() )
61 notify_uninit();
62 }
63
64 // Do initialize the library.
65 static bool Initialize()
66 {
67 if ( !notify_is_initted() )
68 {
69 if ( !notify_init(wxTheApp->GetAppName().utf8_str()) )
70 return false;
71 }
72
73 return true;
74 }
75
76 private:
77 wxDECLARE_DYNAMIC_CLASS(wxLibnotifyModule);
78 };
79
80 wxIMPLEMENT_DYNAMIC_CLASS(wxLibnotifyModule, wxModule);
81
82 // ============================================================================
83 // wxNotificationMessage implementation
84 // ============================================================================
85
86 bool wxNotificationMessage::GTKSetIconName(const wxString& name)
87 {
88 m_iconName = name;
89
90 return true;
91 }
92
93 bool wxNotificationMessage::Show(int timeout)
94 {
95 if ( !wxLibnotifyModule::Initialize() )
96 return false;
97
98 // Determine the GTK+ icon to use from flags and also set the urgency
99 // appropriately.
100 const char* icon;
101 NotifyUrgency urgency;
102 switch ( GetFlags() )
103 {
104 case wxICON_INFORMATION:
105 icon = "dialog-information";
106 urgency = NOTIFY_URGENCY_LOW;
107 break;
108
109 case wxICON_WARNING:
110 icon = "dialog-warning";
111 urgency = NOTIFY_URGENCY_NORMAL;
112 break;
113
114 case wxICON_ERROR:
115 icon = "dialog-error";
116 urgency = NOTIFY_URGENCY_CRITICAL;
117 break;
118
119 default:
120 wxFAIL_MSG( "Unknown notification message flags." );
121 return false;
122 }
123
124 // Explicitly specified icon name overrides the implicit one determined by
125 // the flags.
126 wxScopedCharBuffer buf;
127 if ( !m_iconName.empty() )
128 {
129 buf = m_iconName.utf8_str();
130 icon = buf;
131 }
132
133 // Create the notification or update an existing one if we had already been
134 // shown before.
135 if ( !m_notification )
136 {
137 m_notification = notify_notification_new
138 (
139 GetTitle().utf8_str(),
140 GetMessage().utf8_str(),
141 icon
142 #if !wxUSE_LIBNOTIFY_0_7
143 // There used to be an "associated window"
144 // parameter in this function but it has
145 // disappeared by 0.7, so use it for previous
146 // versions only.
147 , 0
148 #endif // libnotify < 0.7
149 );
150 if ( !m_notification )
151 {
152 wxLogDebug("Failed to creation notification.");
153
154 return false;
155 }
156 }
157 else
158 {
159 if ( !notify_notification_update
160 (
161 m_notification,
162 GetTitle().utf8_str(),
163 GetMessage().utf8_str(),
164 icon
165 ) )
166 {
167 wxLogDebug(wxS("notify_notification_update() unexpectedly failed."));
168 }
169 }
170
171
172 // Set the notification parameters not specified during creation.
173 notify_notification_set_timeout
174 (
175 m_notification,
176 timeout == Timeout_Auto ? NOTIFY_EXPIRES_DEFAULT
177 : timeout == Timeout_Never ? NOTIFY_EXPIRES_NEVER
178 : 1000*timeout
179 );
180
181 notify_notification_set_urgency(m_notification, urgency);
182
183
184 // Finally do show the notification.
185 wxGtkError error;
186 if ( !notify_notification_show(m_notification, error.Out()) )
187 {
188 wxLogDebug("Failed to shown notification: %s", error.GetMessage());
189
190 return false;
191 }
192
193 return true;
194 }
195
196 bool wxNotificationMessage::Close()
197 {
198 wxCHECK_MSG( m_notification, false,
199 wxS("Can't close not shown notification.") );
200
201 wxGtkError error;
202 if ( !notify_notification_close(m_notification, error.Out()) )
203 {
204 wxLogDebug("Failed to hide notification: %s", error.GetMessage());
205
206 return false;
207 }
208
209 return true;
210 }
211
212 wxNotificationMessage::~wxNotificationMessage()
213 {
214 if ( m_notification )
215 g_object_unref(m_notification);
216 }
217
218 #endif // wxUSE_NOTIFICATION_MESSAGE && wxUSE_LIBNOTIFY