/////////////////////////////////////////////////////////////////////////////// // Name: src/gtk/notifmsg.cpp // Purpose: wxNotificationMessage for wxGTK using libnotify. // Author: Vadim Zeitlin // Created: 2012-07-25 // Copyright: (c) 2012 Vadim Zeitlin // Licence: wxWindows licence /////////////////////////////////////////////////////////////////////////////// // ============================================================================ // declarations // ============================================================================ // ---------------------------------------------------------------------------- // headers // ---------------------------------------------------------------------------- // for compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" #ifdef __BORLANDC__ #pragma hdrstop #endif #if wxUSE_NOTIFICATION_MESSAGE && wxUSE_LIBNOTIFY #include "wx/notifmsg.h" #ifndef WX_PRECOMP #include "wx/app.h" #endif // WX_PRECOMP #include #include "wx/module.h" // General note about error handling: as notifications are meant to be // non-intrusive, we use wxLogDebug() and not wxLogError() if anything goes // wrong here to avoid spamming the user with message boxes. As all methods // return boolean indicating success or failure, the caller could show the // notification in some other way or notify about the error itself if needed. #include "wx/gtk/private/error.h" // ---------------------------------------------------------------------------- // A module for cleaning up libnotify on exit. // ---------------------------------------------------------------------------- class wxLibnotifyModule : public wxModule { public: virtual bool OnInit() { // We're initialized on demand. return true; } virtual void OnExit() { if ( notify_is_initted() ) notify_uninit(); } // Do initialize the library. static bool Initialize() { if ( !notify_is_initted() ) { if ( !notify_init(wxTheApp->GetAppName().utf8_str()) ) return false; } return true; } private: wxDECLARE_DYNAMIC_CLASS(wxLibnotifyModule); }; wxIMPLEMENT_DYNAMIC_CLASS(wxLibnotifyModule, wxModule); // ============================================================================ // wxNotificationMessage implementation // ============================================================================ bool wxNotificationMessage::GTKSetIconName(const wxString& name) { m_iconName = name; return true; } bool wxNotificationMessage::Show(int timeout) { if ( !wxLibnotifyModule::Initialize() ) return false; // Determine the GTK+ icon to use from flags and also set the urgency // appropriately. const char* icon; NotifyUrgency urgency; switch ( GetFlags() ) { case wxICON_INFORMATION: icon = "dialog-information"; urgency = NOTIFY_URGENCY_LOW; break; case wxICON_WARNING: icon = "dialog-warning"; urgency = NOTIFY_URGENCY_NORMAL; break; case wxICON_ERROR: icon = "dialog-error"; urgency = NOTIFY_URGENCY_CRITICAL; break; default: wxFAIL_MSG( "Unknown notification message flags." ); return false; } // Explicitly specified icon name overrides the implicit one determined by // the flags. wxScopedCharBuffer buf; if ( !m_iconName.empty() ) { buf = m_iconName.utf8_str(); icon = buf; } // Create the notification or update an existing one if we had already been // shown before. if ( !m_notification ) { m_notification = notify_notification_new ( GetTitle().utf8_str(), GetMessage().utf8_str(), icon #if !wxUSE_LIBNOTIFY_0_7 // There used to be an "associated window" // parameter in this function but it has // disappeared by 0.7, so use it for previous // versions only. , 0 #endif // libnotify < 0.7 ); if ( !m_notification ) { wxLogDebug("Failed to creation notification."); return false; } } else { if ( !notify_notification_update ( m_notification, GetTitle().utf8_str(), GetMessage().utf8_str(), icon ) ) { wxLogDebug(wxS("notify_notification_update() unexpectedly failed.")); } } // Set the notification parameters not specified during creation. notify_notification_set_timeout ( m_notification, timeout == Timeout_Auto ? NOTIFY_EXPIRES_DEFAULT : timeout == Timeout_Never ? NOTIFY_EXPIRES_NEVER : 1000*timeout ); notify_notification_set_urgency(m_notification, urgency); // Finally do show the notification. wxGtkError error; if ( !notify_notification_show(m_notification, error.Out()) ) { wxLogDebug("Failed to shown notification: %s", error.GetMessage()); return false; } return true; } bool wxNotificationMessage::Close() { wxCHECK_MSG( m_notification, false, wxS("Can't close not shown notification.") ); wxGtkError error; if ( !notify_notification_close(m_notification, error.Out()) ) { wxLogDebug("Failed to hide notification: %s", error.GetMessage()); return false; } return true; } wxNotificationMessage::~wxNotificationMessage() { if ( m_notification ) g_object_unref(m_notification); } #endif // wxUSE_NOTIFICATION_MESSAGE && wxUSE_LIBNOTIFY