Added config option so can force 'bad categories' into Other using freedesktop list
[pandora-libraries.git] / minimenu / mmenu.c
index ca0d4aa..83743bc 100644 (file)
@@ -80,7 +80,6 @@ char *g_skinpath = NULL; // where 'skin_selected' is located .. the fullpath inc
 pnd_conf_handle g_skinconf = NULL;
 
 void sigquit_handler ( int n );
-unsigned char cat_is_visible ( pnd_conf_handle h, char *catname );
 unsigned char app_is_visible ( pnd_conf_handle h, char *uniqueid );
 
 int main ( int argc, char *argv[] ) {
@@ -355,9 +354,12 @@ int main ( int argc, char *argv[] ) {
     emit_and_quit ( MM_QUIT );
   }
 
+  // init categories
+  category_init();
+
   // create all cat
   if ( pnd_conf_get_as_int_d ( g_conf, "categories.do_all_cat", 1 ) ) {
-    category_push ( g_x11_present ? CATEGORY_ALL "    (X11)" : CATEGORY_ALL "   (No X11)", NULL /*app*/, 0, NULL /* fspath */ );
+    category_push ( g_x11_present ? CATEGORY_ALL "    (X11)" : CATEGORY_ALL "   (No X11)", NULL /*app*/, 0, NULL /* fspath */, 1 /* visible */ );
   }
 
   // set up category mappings
@@ -385,6 +387,7 @@ int main ( int argc, char *argv[] ) {
 
   /* set speed to minimenu run-speed, now that we're all set up
    */
+#if 0 /* something crashes at high speed image caching.. */
   int use_mm_speed = pnd_conf_get_as_int_d ( g_conf, "minimenu.use_mm_speed", 0 );
   if ( use_mm_speed > 0 ) {
     int mm_speed = pnd_conf_get_as_int_d ( g_conf, "minimenu.mm_speed", -1 );
@@ -394,6 +397,7 @@ int main ( int argc, char *argv[] ) {
       system ( buffer );
     }
   } // do speed change?
+#endif
 
   // do it!
   while ( 1 ) { // forever!
@@ -427,7 +431,7 @@ int main ( int argc, char *argv[] ) {
     } // rescan?
 
     // sleep? block?
-    usleep ( 5000 );
+    usleep ( 100000 /*5000*/ );
 
   } // while
 
@@ -502,6 +506,11 @@ void applications_free ( void ) {
 
 void applications_scan ( void ) {
 
+  // has user disabled pnd scanning, by chance?
+  if ( ! pnd_conf_get_as_int_d ( g_conf, "filesystem.do_pnd_disco", 1 ) ) {
+    goto dirbrowser_scan; // skip pnd's
+  }
+
   // show disco screen
   ui_discoverscreen ( 1 /* clear screen */ );
 
@@ -660,26 +669,32 @@ void applications_scan ( void ) {
         ( pnd_pxml_get_x11 ( iter -> option_no_x11 ) == pnd_pxml_x11_required && g_x11_present == 1 )
        )
     {
+      if ( iter -> title_en == NULL || iter -> title_en [ 0 ] == '\0' ) {
+       // null title; just skip it.
+      } else {
+
+       // push to All category
+       // we do this first, so first category is always All
+       if ( pnd_conf_get_as_int_d ( g_conf, "categories.do_all_cat", 1 ) ) {
+         category_push ( g_x11_present ? CATEGORY_ALL "    (X11)" : CATEGORY_ALL "   (No X11)", iter, ovrh, NULL /* fspath */, 1 /* visible */ );
+       } // all?
 
-      // push to All category
-      // we do this first, so first category is always All
-      if ( pnd_conf_get_as_int_d ( g_conf, "categories.do_all_cat", 1 ) ) {
-       category_push ( g_x11_present ? CATEGORY_ALL "    (X11)" : CATEGORY_ALL "   (No X11)", iter, ovrh, NULL /* fspath */ );
-      } // all?
+       // is this app suppressed? if not, show it in whatever categories the user is allowing
+       if ( iter -> unique_id && app_is_visible ( g_conf, iter -> unique_id ) ) {
 
-      // is this app suppressed? if not, show it in whatever categories the user is allowing
-      if ( iter -> unique_id && app_is_visible ( g_conf, iter -> unique_id ) ) {
+         // main categories
+         category_meta_push ( iter -> main_category, NULL /* no parent cat */, iter, ovrh, cat_is_visible ( g_conf, iter -> main_category ) ); //pnd_conf_get_as_int_d ( g_conf, "tabs.top_maincat", 1 ) );
+         category_meta_push ( iter -> main_category1, iter -> main_category, iter, ovrh, cat_is_visible ( g_conf, iter -> main_category1 ) ); //pnd_conf_get_as_int_d ( g_conf, "tabs.top_maincat1", 0 ) );
+         category_meta_push ( iter -> main_category2, iter -> main_category, iter, ovrh, cat_is_visible ( g_conf, iter -> main_category2 ) ); //pnd_conf_get_as_int_d ( g_conf, "tabs.top_maincat2", 0 ) );
+         // alt categories
+         category_meta_push ( iter -> alt_category, NULL /* no parent cat */, iter, ovrh, cat_is_visible ( g_conf, iter -> alt_category ) ); //pnd_conf_get_as_int_d ( g_conf, "tabs.top_altcat", 0 ) );
+         category_meta_push ( iter -> alt_category1, iter -> alt_category, iter, ovrh, cat_is_visible ( g_conf, iter -> alt_category1 ) ); //pnd_conf_get_as_int_d ( g_conf, "tabs.top_altcat1", 0 ) );
+         category_meta_push ( iter -> alt_category2, iter -> alt_category, iter, ovrh, cat_is_visible ( g_conf, iter -> alt_category2 ) ); //pnd_conf_get_as_int_d ( g_conf, "tabs.top_altcat2", 0 ) );
 
-       // main categories
-       category_meta_push ( iter -> main_category, NULL /* no parent cat */, iter, ovrh, cat_is_visible ( g_conf, iter -> main_category ) ); //pnd_conf_get_as_int_d ( g_conf, "tabs.top_maincat", 1 ) );
-       category_meta_push ( iter -> main_category1, iter -> main_category, iter, ovrh, cat_is_visible ( g_conf, iter -> main_category1 ) ); //pnd_conf_get_as_int_d ( g_conf, "tabs.top_maincat1", 0 ) );
-       category_meta_push ( iter -> main_category2, iter -> main_category, iter, ovrh, cat_is_visible ( g_conf, iter -> main_category2 ) ); //pnd_conf_get_as_int_d ( g_conf, "tabs.top_maincat2", 0 ) );
-       // alt categories
-       category_meta_push ( iter -> alt_category, NULL /* no parent cat */, iter, ovrh, cat_is_visible ( g_conf, iter -> alt_category ) ); //pnd_conf_get_as_int_d ( g_conf, "tabs.top_altcat", 0 ) );
-       category_meta_push ( iter -> alt_category1, iter -> alt_category, iter, ovrh, cat_is_visible ( g_conf, iter -> alt_category1 ) ); //pnd_conf_get_as_int_d ( g_conf, "tabs.top_altcat1", 0 ) );
-       category_meta_push ( iter -> alt_category2, iter -> alt_category, iter, ovrh, cat_is_visible ( g_conf, iter -> alt_category2 ) ); //pnd_conf_get_as_int_d ( g_conf, "tabs.top_altcat2", 0 ) );
+       } // app is visible?
 
-      } // app is visible?
+      } // has title?
 
     } // register with categories or filter out
 
@@ -688,8 +703,7 @@ void applications_scan ( void ) {
     itercount++;
   } // while
 
-  // sort (some) categories
-  category_sort();
+ dirbrowser_scan:
 
   // set up filesystem browser tabs
   if ( pnd_conf_get_as_int_d ( g_conf, "filesystem.do_browser", 0 ) ) {
@@ -707,7 +721,7 @@ void applications_scan ( void ) {
 
       // check if dir is empty; if so, skip it.
       if ( ! is_dir_empty ( buffer ) ) {
-       category_push ( tabname /* tab name */, NULL /* app */, 0 /* override */, buffer /* fspath */ );
+       category_push ( tabname /* tab name */, NULL /* app */, 0 /* override */, buffer /* fspath */, 1 /* visible */ );
       }
 
     }
@@ -718,6 +732,9 @@ void applications_scan ( void ) {
   // dump categories
   //category_dump();
 
+  // publish desired categories
+  category_publish ( CFNORMAL, NULL );
+
   // let deferred icon cache go now
   ui_post_scan();
 
@@ -800,3 +817,51 @@ void setup_notifications ( void ) {
 
   return;
 }
+
+// for Pleng
+// Goal: normally menu will quit when an app is invoked, but there are cases when some folks
+// may configure their system and want mmenu to live instead (save on restart time, don't care
+// about RAM, using a multitasking tray/window manager setup...), so instead of 'exit and emit'
+// here we just run the app directly and cross fingers!
+void emit_and_run ( char *buffer ) {
+
+  // run the bloody thing
+  int f;
+
+  if ( ( f = fork() ) < 0 ) {
+    // error forking
+  } else if ( f > 0 ) {
+    // parent
+  } else {
+    // child, do it
+    execl ( "/bin/sh", "/bin/sh", "-c", buffer + strlen(MM_RUN) + 1, (char*) NULL );
+  } 
+
+  return;
+}
+
+// this code was swiped from pnd_utility pnd_exec_no_wait_1 as it became a little too minimenu-specific to remain there
+void exec_raw_binary ( char *fullpath ) {
+  int i;
+
+  if ( ( i = fork() ) < 0 ) {
+    printf ( "ERROR: Couldn't fork()\n" );
+    return;
+  }
+
+  if ( i ) {
+    return; // parent process, don't care
+  }
+
+  // child process, do something
+  execl ( "/bin/sh", "/bin/sh", "-c", fullpath, (char*) NULL );
+  //execl ( fullpath, fullpath, (char*) NULL );
+
+  // error invoking something, and we're the child process, so just die before all hell breaks lose with us thinking we're the (second!) parent on return!
+  exit ( -1 );
+
+  // getting here is an error
+  //printf ( "Error attempting to run %s\n", fullpath );
+
+  return;
+}