diff options
Diffstat (limited to 'sfx2/source/appl/shutdowniconunx.cxx')
-rw-r--r-- | sfx2/source/appl/shutdowniconunx.cxx | 137 |
1 files changed, 76 insertions, 61 deletions
diff --git a/sfx2/source/appl/shutdowniconunx.cxx b/sfx2/source/appl/shutdowniconunx.cxx index b9799f5818..7e3aa09347 100644 --- a/sfx2/source/appl/shutdowniconunx.cxx +++ b/sfx2/source/appl/shutdowniconunx.cxx @@ -1,3 +1,4 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #ifdef ENABLE_QUICKSTART_APPLET @@ -7,19 +8,20 @@ #include <gtk/gtk.h> #include <glib.h> -#include <eggtray/eggtrayicon.h> -#include <vos/mutex.hxx> +#include <osl/mutex.hxx> #include <vcl/bitmapex.hxx> #include <vcl/bmpacc.hxx> #include <sfx2/app.hxx> -#ifndef _SFX_APP_HRC #include "app.hrc" -#endif #ifndef __SHUTDOWNICON_HXX__ #define USE_APP_SHORTCUTS #include "shutdownicon.hxx" #endif +#ifdef ENABLE_GIO +#include <gio/gio.h> +#endif + // Cut/paste from vcl/inc/svids.hrc #define SV_ICON_SMALL_START 25000 @@ -36,9 +38,13 @@ using namespace ::rtl; using namespace ::osl; static ResMgr *pVCLResMgr; -static EggTrayIcon *pTrayIcon; +static GtkStatusIcon* pTrayIcon; static GtkWidget *pExitMenuItem = NULL; static GtkWidget *pOpenMenuItem = NULL; +static GtkWidget *pDisableMenuItem = NULL; +#ifdef ENABLE_GIO +GFileMonitor* pMonitor = NULL; +#endif static void open_url_cb( GtkWidget *, gpointer data ) { @@ -66,9 +72,10 @@ static void systray_disable_cb() static void exit_quickstarter_cb( GtkWidget * ) { - egg_tray_icon_cancel_message (pTrayIcon, 1 ); - ShutdownIcon::getInstance()->terminateDesktop(); plugin_shutdown_sys_tray(); + //terminate may cause this .so to be unloaded. So we must be hands off + //all calls into this .so after this call + ShutdownIcon::terminateDesktop(); } static void menu_deactivate_cb( GtkWidget *pMenu ) @@ -89,7 +96,8 @@ static GdkPixbuf * ResIdToPixbuf( USHORT nResId ) g_return_val_if_fail( pSalBitmap != NULL, NULL ); Size aSize( pSalBitmap->Width(), pSalBitmap->Height() ); - g_return_val_if_fail( Size( pSalAlpha->Width(), pSalAlpha->Height() ) == aSize, NULL ); + if (pSalAlpha) + g_return_val_if_fail( Size( pSalAlpha->Width(), pSalAlpha->Height() ) == aSize, NULL ); int nX, nY; guchar *pPixbufData = ( guchar * )g_malloc( 4 * aSize.Width() * aSize.Height() ); @@ -265,7 +273,7 @@ static void populate_menu( GtkWidget *pMenu ) pMenuItem = gtk_separator_menu_item_new(); gtk_menu_shell_append( pMenuShell, pMenuItem ); - (void) add_image_menu_item + pDisableMenuItem = add_image_menu_item ( pMenuShell, GTK_STOCK_CLOSE, pShutdownIcon->GetResString( STR_QUICKSTART_PRELAUNCH_UNX ), G_CALLBACK( systray_disable_cb ) ); @@ -289,30 +297,7 @@ static void refresh_menu( GtkWidget *pMenu ) bool bModal = ShutdownIcon::bModalMode; gtk_widget_set_sensitive( pExitMenuItem, !bModal); gtk_widget_set_sensitive( pOpenMenuItem, !bModal); -} - -extern "C" { -static void -layout_menu( GtkMenu *menu, - gint *x, gint *y, gboolean *push_in, - gpointer ) -{ - GtkRequisition req; - GtkWidget *ebox = GTK_BIN( pTrayIcon )->child; - - gtk_widget_size_request( GTK_WIDGET( menu ), &req ); - gdk_window_get_origin( ebox->window, x, y ); - - (*x) += ebox->allocation.x; - (*y) += ebox->allocation.y; - - if (*y >= gdk_screen_get_height (gtk_widget_get_screen (ebox)) / 2) - (*y) -= req.height; - else - (*y) += ebox->allocation.height; - - *push_in = TRUE; -} + gtk_widget_set_sensitive( pDisableMenuItem, !bModal); } static gboolean display_menu_cb( GtkWidget *, @@ -336,26 +321,36 @@ static gboolean display_menu_cb( GtkWidget *, refresh_menu( pMenu ); gtk_menu_popup( GTK_MENU( pMenu ), NULL, NULL, - layout_menu, NULL, 0, event->time ); + gtk_status_icon_position_menu, pTrayIcon, + 0, event->time ); return TRUE; } -extern "C" { - static gboolean - show_at_idle( gpointer ) - { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); - gtk_widget_show_all( GTK_WIDGET( pTrayIcon ) ); - return FALSE; - } +#ifdef ENABLE_GIO +/* + * See rhbz#610103. If the quickstarter is running, then LibreOffice is + * upgraded, then the old quickstarter is still running, but is now unreliable + * as the old install has been deleted. A fairly intractable problem but we + * can avoid much of the pain if we turn off the quickstarter if we detect + * that it has been physically deleted. +*/ +static void notify_file_changed(GFileMonitor * /*gfilemonitor*/, GFile * /*arg1*/, + GFile * /*arg2*/, GFileMonitorEvent event_type, gpointer /*user_data*/) +{ + if (event_type == G_FILE_MONITOR_EVENT_DELETED) + exit_quickstarter_cb(NULL); } +#endif void SAL_DLLPUBLIC_EXPORT plugin_init_sys_tray() { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); + ::SolarMutexGuard aGuard; - if( !g_type_from_name( "GdkDisplay" ) ) + if( /* need gtk_status to resolve */ + (gtk_check_version( 2, 10, 0 ) != NULL) || + /* we need the vcl plugin and mainloop initialized */ + !g_type_from_name( "GdkDisplay" ) ) return; OString aLabel; @@ -365,45 +360,65 @@ void SAL_DLLPUBLIC_EXPORT plugin_init_sys_tray() pShutdownIcon->GetResString( STR_QUICKSTART_TIP ), RTL_TEXTENCODING_UTF8 ); - pTrayIcon = egg_tray_icon_new( aLabel ); - - GtkWidget *pParent = gtk_event_box_new(); - GtkTooltips *pTooltips = gtk_tooltips_new(); - gtk_tooltips_set_tip( GTK_TOOLTIPS( pTooltips ), pParent, aLabel, NULL ); - - GtkWidget *pIconImage = gtk_image_new(); - gtk_container_add( GTK_CONTAINER( pParent ), pIconImage ); - pVCLResMgr = CREATEVERSIONRESMGR( vcl ); GdkPixbuf *pPixbuf = ResIdToPixbuf( SV_ICON_ID_OFFICE ); gtk_image_set_from_pixbuf( GTK_IMAGE( pIconImage ), pPixbuf ); g_object_unref( pPixbuf ); + g_object_set (pTrayIcon, "title", aLabel.getStr(), + "tooltip_text", aLabel.getStr(), NULL); + GtkWidget *pMenu = gtk_menu_new(); g_signal_connect (pMenu, "deactivate", G_CALLBACK (menu_deactivate_cb), NULL); - g_signal_connect( pParent, "button_press_event", - G_CALLBACK( display_menu_cb ), pMenu ); - gtk_container_add( GTK_CONTAINER( pTrayIcon ), pParent ); - - // Show at idle to avoid artefacts at startup - g_idle_add (show_at_idle, (gpointer) pTrayIcon); + g_signal_connect(pTrayIcon, "button_press_event", + G_CALLBACK(display_menu_cb), pMenu); // disable shutdown pShutdownIcon->SetVeto( true ); pShutdownIcon->addTerminateListener(); + +#ifdef ENABLE_GIO + GFile* pFile = NULL; + rtl::OUString sLibraryFileUrl; + if (osl::Module::getUrlFromAddress(plugin_init_sys_tray, sLibraryFileUrl)) + pFile = g_file_new_for_uri(rtl::OUStringToOString(sLibraryFileUrl, RTL_TEXTENCODING_UTF8).getStr()); + + if (pFile) + { + if ((pMonitor = g_file_monitor_file(pFile, G_FILE_MONITOR_NONE, NULL, NULL))) + g_signal_connect(pMonitor, "changed", (GCallback)notify_file_changed, NULL); + g_object_unref(pFile); + } +#endif } void SAL_DLLPUBLIC_EXPORT plugin_shutdown_sys_tray() { - ::vos::OGuard aGuard( Application::GetSolarMutex() ); + ::SolarMutexGuard aGuard; if( !pTrayIcon ) return; - gtk_widget_destroy( GTK_WIDGET( pTrayIcon ) ); + +#ifdef ENABLE_GIO + if (pMonitor) + { + g_signal_handlers_disconnect_by_func(pMonitor, + (void*)notify_file_changed, pMonitor); + g_file_monitor_cancel(pMonitor); + g_object_unref(pMonitor); + pMonitor = NULL; + } +#endif + + g_object_unref(pTrayIcon); pTrayIcon = NULL; + pExitMenuItem = NULL; pOpenMenuItem = NULL; + pDisableMenuItem = NULL; } #endif // ENABLE_QUICKSTART_APPLET + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |