diff --git a/COMPILE.txt b/COMPILE.txt index 15847cc3c..a6d14bad2 100644 --- a/COMPILE.txt +++ b/COMPILE.txt @@ -455,7 +455,7 @@ OS X probably easier to just install all of them) - MacPorts - To install the dependencies, run: - sudo port install cairo +quartz -x11 pango +quartz -x11 gdk-pixbuf2 -x11 gtk2 +quartz libsigcxx2 + sudo port install cairo +quartz -x11 pango +quartz -x11 gdk-pixbuf2 -x11 gtk2 +quartz libsigcxx2 gtk-osx-application +no_python - gtkmm port will fail to install. Use `-s’ option. sudo port -s install gtkmm - To install other dependencies and tools. diff --git a/rtgui/CMakeLists.txt b/rtgui/CMakeLists.txt index 459c52a9b..9bfbb7e5d 100644 --- a/rtgui/CMakeLists.txt +++ b/rtgui/CMakeLists.txt @@ -32,6 +32,11 @@ set (BASESOURCEFILES include_directories (BEFORE "${CMAKE_CURRENT_BINARY_DIR}") +if (APPLE) + # At the time of writing Cmake has no module finder for gtkmacintegration so here we have it hard-coded, if installed via macports it should be in /opt/local/... + set (EXTRA_LIB_RTGUI gtkmacintegration) + set (EXTRA_INCDIR ${EXTRA_INCDIR} /opt/local/include/gtkmacintegration) +endif (APPLE) if (WIN32) set (EXTRA_SRC windirmonitor.cc myicon.rc) set (EXTRA_LIB_RTGUI winmm) @@ -42,9 +47,13 @@ if (WIN32) #set_target_properties (rth PROPERTIES LINK_FLAGS "-mwindows") else (WIN32) include_directories (${EXTRA_INCDIR} ${GLIB2_INCLUDE_DIRS} ${GLIBMM_INCLUDE_DIRS} - ${GTK_INCLUDE_DIRS} ${GTKMM_INCLUDE_DIRS} ${GIO_INCLUDE_DIRS} ${GIOMM_INCLUDE_DIRS} ${IPTCDATA_INCLUDE_DIRS} ${LCMS_INCLUDE_DIRS} ${EXPAT_INCLUDE_DIRS} ${FFTW3F_LIBRARY_DIRS} ${GTHREAD_INCLUDE_DIRS} ${GOBJECT_INCLUDE_DIRS} ${CANBERRA-GTK_INCLUDE_DIRS}) + ${GTK_INCLUDE_DIRS} ${GTKMM_INCLUDE_DIRS} ${GIO_INCLUDE_DIRS} ${GIOMM_INCLUDE_DIRS} ${IPTCDATA_INCLUDE_DIRS} + ${LCMS_INCLUDE_DIRS} ${EXPAT_INCLUDE_DIRS} ${FFTW3F_LIBRARY_DIRS} ${GTHREAD_INCLUDE_DIRS} ${GOBJECT_INCLUDE_DIRS} + ${CANBERRA-GTK_INCLUDE_DIRS}) link_directories (${EXTRA_LIBDIR} ${GLIB2_LIBRARY_DIRS} ${GLIBMM_LIBRARY_DIRS} - ${GTK_LIBRARY_DIRS} ${GTKMM_LIBRARY_DIRS} ${GIO_LIBRARY_DIRS} ${GIOMM_LIBRARY_DIRS} ${IPTCDATA_LIBRARY_DIRS} ${LCMS_LIBRARY_DIRS} ${EXPAT_LIBRARY_DIRS} ${FFTW3F_LIBRARY_DIRS} ${GTHREAD_LIBRARY_DIRS} ${GOBJECT_LIBRARY_DIRS} ${CANBERRA-GTK_LIBRARY_DIRS}) + ${GTK_LIBRARY_DIRS} ${GTKMM_LIBRARY_DIRS} ${GIO_LIBRARY_DIRS} ${GIOMM_LIBRARY_DIRS} ${IPTCDATA_LIBRARY_DIRS} + ${LCMS_LIBRARY_DIRS} ${EXPAT_LIBRARY_DIRS} ${FFTW3F_LIBRARY_DIRS} ${GTHREAD_LIBRARY_DIRS} ${GOBJECT_LIBRARY_DIRS} + ${CANBERRA-GTK_LIBRARY_DIRS}) endif (WIN32) # create config.h which defines where data are stored configure_file ("${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/config.h") @@ -55,6 +64,7 @@ set_target_properties (rth PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS}" OUTPUT_ #target_link_libraries (rth rtengine ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${TIFF_LIBRARIES} ${EXTRA_LIB} ${GOBJECT_LIBRARIES} ${GTHREAD_LIBRARIES} # ${GLIB2_LIBRARIES} ${GLIBMM_LIBRARIES} ${GTK_LIBRARIES} ${GTKMM_LIBRARIES} ${GIO_LIBRARIES} ${GIOMM_LIBRARIES} ${LCMS_LIBRARIES} ${IPTCDATA_LIBRARIES}) target_link_libraries (rth rtengine ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${TIFF_LIBRARIES} ${GOBJECT_LIBRARIES} ${GTHREAD_LIBRARIES} - ${GLIB2_LIBRARIES} ${GLIBMM_LIBRARIES} ${GTK_LIBRARIES} ${GTKMM_LIBRARIES} ${GIO_LIBRARIES} ${GIOMM_LIBRARIES} ${LCMS_LIBRARIES} ${EXPAT_LIBRARIES} ${FFTW3F_LIBRARIES} ${IPTCDATA_LIBRARIES} ${CANBERRA-GTK_LIBRARIES} ${EXTRA_LIB_RTGUI}) + ${GLIB2_LIBRARIES} ${GLIBMM_LIBRARIES} ${GTK_LIBRARIES} ${GTKMM_LIBRARIES} ${GIO_LIBRARIES} ${GIOMM_LIBRARIES} ${LCMS_LIBRARIES} ${EXPAT_LIBRARIES} + ${FFTW3F_LIBRARIES} ${IPTCDATA_LIBRARIES} ${CANBERRA-GTK_LIBRARIES} ${EXTRA_LIB_RTGUI}) install (TARGETS rth DESTINATION ${BINDIR}) diff --git a/rtgui/rtwindow.cc b/rtgui/rtwindow.cc index c0ad44429..cf3b31f9a 100644 --- a/rtgui/rtwindow.cc +++ b/rtgui/rtwindow.cc @@ -24,6 +24,53 @@ #include "rtimage.h" #include "whitebalance.h" +#if defined(__APPLE__) +static gboolean +osx_should_quit_cb (GtkosxApplication *app, gpointer data) +{ + RTWindow *rtWin = (RTWindow *)data; + return rtWin->on_delete_event(0); +} + +static void +osx_will_quit_cb (GtkosxApplication *app, gpointer data) +{ + RTWindow *rtWin = (RTWindow *)data; + rtWin->on_delete_event(0); + gtk_main_quit (); +} + +bool RTWindow::osxFileOpenEvent(Glib::ustring path) { + + CacheManager* cm = CacheManager::getInstance(); + Thumbnail* thm= cm->getEntry( path ); + if(thm && fpanel){ + std::vector entries; + entries.push_back(thm); + fpanel->fileCatalog->openRequested(entries); + return true; + } + return false; +} + +static gboolean +osx_open_file_cb (GtkosxApplication *app, gchar *path_, gpointer data) +{ + RTWindow *rtWin = (RTWindow *)data; + if (!argv1.empty()) { + // skip handling if we have a file argument or else we get double open of same file + return false; + } + Glib::ustring path = Glib::ustring(path_); + Glib::ustring suffix = path.length() > 4 ? path.substr(path.length()-3) : ""; + suffix = suffix.lowercase(); + if (suffix == "pp3") { + path = path.substr(0, path.length()-4); + } + return rtWin->osxFileOpenEvent(path); +} +#endif // __APPLE__ + RTWindow::RTWindow () :mainNB(NULL) ,bpanel(NULL) @@ -49,6 +96,23 @@ RTWindow::RTWindow () } #endif //GLIBMM_EXCEPTIONS_ENABLED +#if defined(__APPLE__) + { + osxApp = (GtkosxApplication *)g_object_new (GTKOSX_TYPE_APPLICATION, NULL); + gboolean falseval = FALSE; + gboolean trueval = TRUE; + RTWindow *rtWin = this; + g_signal_connect (osxApp, "NSApplicationBlockTermination", G_CALLBACK (osx_should_quit_cb), rtWin); + g_signal_connect (osxApp, "NSApplicationWillTerminate", G_CALLBACK (osx_will_quit_cb), rtWin); + g_signal_connect (osxApp, "NSApplicationOpenFile", G_CALLBACK (osx_open_file_cb), rtWin); + // RT don't have a menu, but we must create a dummy one to get the default OS X app menu working + GtkWidget *menubar; + menubar = gtk_menu_bar_new (); + gtkosx_application_set_menu_bar (osxApp, GTK_MENU_SHELL (menubar)); + gtkosx_application_set_use_quartz_accelerators (osxApp, FALSE); + gtkosx_application_ready (osxApp); + } +#endif set_title("RawTherapee "+versionString); property_allow_shrink() = true; set_default_size(options.windowWidth, options.windowHeight); @@ -58,7 +122,8 @@ RTWindow::RTWindow () maximize(); else unmaximize(); - + + on_delete_has_run = false; is_fullscreen = false; property_destroy_with_parent().set_value(false); signal_window_state_event().connect( sigc::mem_fun(*this, &RTWindow::on_window_state_event) ); @@ -211,6 +276,9 @@ RTWindow::~RTWindow() if(!simpleEditor) delete pldBridge; pldBridge = NULL; +#if defined(__APPLE__) + g_object_unref (osxApp); +#endif } void RTWindow::findVerNumbers(int* numbers, Glib::ustring versionStr) { @@ -460,6 +528,11 @@ void RTWindow::addBatchQueueJobs (std::vector &entries) { } bool RTWindow::on_delete_event(GdkEventAny* event) { + + if (on_delete_has_run) { + // on Mac OSX we can get multiple events + return false; + } // Check if any editor is still processing, and do NOT quit if so. Otherwise crashes and inconsistent caches bool isProcessing=false; @@ -520,7 +593,8 @@ bool RTWindow::on_delete_event(GdkEventAny* event) { Options::save (); hide(); - return true; + on_delete_has_run = true; + return false; } void RTWindow::showPreferences () { diff --git a/rtgui/rtwindow.h b/rtgui/rtwindow.h index b798613f9..54fbdedca 100644 --- a/rtgui/rtwindow.h +++ b/rtgui/rtwindow.h @@ -26,6 +26,9 @@ #include "progressconnector.h" #include "editwindow.h" #include "splash.h" +#if defined(__APPLE__) +#include +#endif class RTWindow : public Gtk::Window, public rtengine::ProgressListener{ @@ -39,6 +42,7 @@ class RTWindow : public Gtk::Window, public rtengine::ProgressListener{ Gtk::ProgressBar prProgBar; PLDBridge* pldBridge; bool is_fullscreen; + bool on_delete_has_run; Gtk::Button * btn_fullscreen; Gtk::Image *iFullscreen, *iFullscreen_exit; @@ -49,11 +53,17 @@ class RTWindow : public Gtk::Window, public rtengine::ProgressListener{ bool on_expose_event_epanel(GdkEventExpose* event); bool on_expose_event_fpanel(GdkEventExpose* event); bool splashClosed(GdkEventAny* event); +#if defined(__APPLE__) + GtkosxApplication *osxApp; +#endif public: RTWindow (); ~RTWindow(); +#if defined(__APPLE__) + bool osxFileOpenEvent(Glib::ustring path); +#endif void addEditorPanel (EditorPanel* ep,const std::string &name); void remEditorPanel (EditorPanel* ep); bool selectEditorPanel(const std::string &name);