static gboolean sn_timeout( gpointer user_data ) { SnLauncherContext * ctx = ( SnLauncherContext* ) user_data; gdk_threads_enter(); /* FIXME: startup notification, is this correct? */ sn_launcher_context_complete ( ctx ); sn_launcher_context_unref ( ctx ); gdk_threads_leave(); return FALSE; }
void launcher_action(LauncherIcon *icon, XEvent* evt) { char *cmd = calloc(strlen(icon->cmd) + 10, 1); sprintf(cmd, "(%s&)", icon->cmd); #if HAVE_SN SnLauncherContext* ctx; Time time; if (startup_notifications) { ctx = sn_launcher_context_new(server.sn_dsp, server.screen); sn_launcher_context_set_name(ctx, icon->icon_tooltip); sn_launcher_context_set_description(ctx, "Application launched from tint2"); sn_launcher_context_set_binary_name (ctx, icon->cmd); // Get a timestamp from the X event if (evt->type == ButtonPress || evt->type == ButtonRelease) { time = evt->xbutton.time; } else { fprintf(stderr, "Unknown X event: %d\n", evt->type); free(cmd); return; } sn_launcher_context_initiate(ctx, "tint2", icon->cmd, time); } #endif /* HAVE_SN */ pid_t pid; pid = fork(); if (pid < 0) { fprintf(stderr, "Could not fork\n"); } else if (pid == 0) { // Child process #if HAVE_SN if (startup_notifications) { sn_launcher_context_setup_child_process(ctx); } #endif // HAVE_SN // Allow children to exist after parent destruction setsid(); // Run the command execl("/bin/sh", "/bin/sh", "-c", icon->cmd, NULL); fprintf(stderr, "Failed to execlp %s\n", icon->cmd); #if HAVE_SN if (startup_notifications) { sn_launcher_context_unref(ctx); } #endif // HAVE_SN exit(1); } else { // Parent process #if HAVE_SN if (startup_notifications) { g_tree_insert(server.pids, GINT_TO_POINTER (pid), ctx); } #endif // HAVE_SN } free(cmd); }
void startup_notify_end(StartupNotify *s) { #if HAVE_LIBSTARTUP_NOTIFICATION E_RETURN_IF_FAIL(s != 0); sn_launcher_context_complete(s->context); sn_launcher_context_unref(s->context); sn_display_unref(s->display); edelib_unsetenv("DESKTOP_STARTUP_ID"); XSync(fl_display, False); delete s; #endif }
static void sigchld_handler(int sig) { UNUSED(sig); // Wait for all dead processes pid_t pid; while ((pid = waitpid(-1, NULL, WNOHANG)) > 0) { SnLauncherContext* ctx; ctx = (SnLauncherContext*)g_tree_lookup(server.pids, GINT_TO_POINTER(pid)); if (ctx == NULL) { WARN("Unknown child %d terminated!", pid); } else { g_tree_remove(server.pids, GINT_TO_POINTER(pid)); sn_launcher_context_complete(ctx); sn_launcher_context_unref(ctx); } } }
void sn_shutdown(gboolean reconfig) { GSList *it; if (reconfig) return; obt_main_loop_x_remove(ob_main_loop, sn_handler); for (it = sn_waits; it; it = g_slist_next(it)) sn_startup_sequence_unref((SnStartupSequence*)it->data); g_slist_free(sn_waits); sn_waits = NULL; screen_set_root_cursor(); sn_launcher_context_unref(sn_launcher); sn_monitor_context_unref(sn_context); sn_display_unref(sn_display); }
void XDesktopContainer::eventLoop() { XEvent ev; #ifdef HAVE_STARTUP_NOTIFICATION sn_context = NULL; sn_display = NULL; sn_bool_t retval; sn_display = sn_display_new (display, error_trap_push, error_trap_pop); #endif /* HAVE_STARTUP_NOTIFICATION */ for(;;) { if( !XPending( display ) && timer){ if(!bg->IsOneShot()){ timer->Update(); } } else { XNextEvent(display, &ev); #ifdef HAVE_STARTUP_NOTIFICATION if (sn_display != NULL){ sn_display_process_event (sn_display, &ev); } #endif /* HAVE_STARTUP_NOTIFICATION */ event = ev; parseEvent(); } } #ifdef HAVE_STARTUP_NOTIFICATION sn_launcher_context_unref (sn_context); if (sn_display) { sn_display_unref (sn_display); } #endif /* HAVE_STARTUP_NOTIFICATION */ }
void sn_setup_spawn_environment(const gchar *program, const gchar *name, const gchar *icon_name, const gchar *wmclass, gint desktop) { gchar *desc; const char *id; desc = g_strdup_printf(_("Running %s"), program); if (sn_launcher_context_get_initiated(sn_launcher)) { sn_launcher_context_unref(sn_launcher); sn_launcher = sn_launcher_context_new(sn_display, ob_screen); } sn_launcher_context_set_name(sn_launcher, name ? name : program); sn_launcher_context_set_description(sn_launcher, desc); sn_launcher_context_set_icon_name(sn_launcher, icon_name ? icon_name : program); sn_launcher_context_set_binary_name(sn_launcher, program); if (wmclass) sn_launcher_context_set_wmclass(sn_launcher, wmclass); if (desktop >= 0 && (unsigned) desktop < screen_num_desktops) sn_launcher_context_set_workspace(sn_launcher, (signed) desktop); sn_launcher_context_initiate(sn_launcher, "openbox", program, event_time()); id = sn_launcher_context_get_startup_id(sn_launcher); /* 20 second timeout for apps to start */ sn_launcher_context_ref(sn_launcher); obt_main_loop_timeout_add(ob_main_loop, 20 * G_USEC_PER_SEC, sn_launch_wait_timeout, sn_launcher, g_direct_equal, (GDestroyNotify)sn_launcher_context_unref); setenv("DESKTOP_STARTUP_ID", id, TRUE); g_free(desc); }
// Launch a command and initiate a startup notification int runcmd(FXString cmd, FXString cmdname, FXString dir, FXString startdir, FXbool usesn = true, FXString snexcepts = "") { int ret; // Change to current directory ret = chdir(dir.text()); if (ret < 0) { int errcode = errno; if (errcode) { fprintf(stderr, _("Error: Can't enter folder %s: %s"), dir.text(), strerror(errcode)); } else { fprintf(stderr, _("Error: Can't enter folder %s"), dir.text()); } return(-1); } // Get rid of possible command options cmdname = cmdname.before(' '); // Check if command is in the startup notification exception list FXbool startup_notify = true; if (snexcepts != "") { FXString entry; for (int i = 0; ; i++) { entry = snexcepts.section(':', i); if (streq(entry.text(), "")) { break; } if (streq(entry.text(), cmdname.text())) { startup_notify = false; break; } } } // Run command with startup notification if (usesn && startup_notify) { Display* xdisplay; SnDisplay* display; SnLauncherContext* context; Time timestamp; // Open display xdisplay = XOpenDisplay(NULL); if (xdisplay == NULL) { fprintf(stderr, _("Error: Can't open display\n")); ret = chdir(startdir.text()); if (ret < 0) { int errcode = errno; if (errcode) { fprintf(stderr, _("Error: Can't enter folder %s: %s"), startdir.text(), strerror(errcode)); } else { fprintf(stderr, _("Error: Can't enter folder %s"), startdir.text()); } } return(-1); } // Message displayed in the task bar (if any) FXString message; message.format(_("Start of %s"), cmdname.text()); // Initiate launcher context display = sn_display_new(xdisplay, NULL, NULL); context = sn_launcher_context_new(display, DefaultScreen(xdisplay)); sn_launcher_context_set_name(context, message.text()); sn_launcher_context_set_binary_name(context, cmdname.text()); sn_launcher_context_set_description(context, message.text()); sn_launcher_context_set_icon_name(context, cmdname.text()); timestamp = gettimestamp(); sn_launcher_context_initiate(context, "Xfe", cmd.text(), timestamp); // Run command in background cmd += " &"; static pid_t child_pid = 0; switch ((child_pid = fork())) { case -1: fprintf(stderr, _("Error: Fork failed: %s\n"), strerror(errno)); break; case 0: // Child sn_launcher_context_setup_child_process(context); execl("/bin/sh", "sh", "-c", cmd.text(), (char*)NULL); _exit(EXIT_SUCCESS); break; } sn_launcher_context_unref(context); } // Run command without startup notification else { // Run command in background cmd += " &"; ret = system(cmd.text()); if (ret < 0) { fprintf(stderr, _("Error: Can't execute command %s"), cmd.text()); return(-1); } // Just display the wait cursor during a second sleep(1); } // Go back to startup directory ret = chdir(startdir.text()); if (ret < 0) { int errcode = errno; if (errcode) { fprintf(stderr, _("Error: Can't enter folder %s: %s"), startdir.text(), strerror(errcode)); } else { fprintf(stderr, _("Error: Can't enter folder %s"), startdir.text()); } return(-1); } return(0); }
gboolean vfs_exec_on_screen( GdkScreen* screen, const char* work_dir, char** argv, char** envp, const char* disp_name, GSpawnFlags flags, GError **err ) { #ifdef HAVE_SN SnLauncherContext * ctx = NULL; SnDisplay* display; #endif gboolean ret; GSpawnChildSetupFunc setup_func = NULL; extern char **environ; char** new_env = envp; int i, n_env = 0; char* display_name; int display_index = -1, startup_id_index = -1; if ( ! envp ) envp = environ; n_env = g_strv_length(envp); new_env = g_new0( char*, n_env + 4 ); for ( i = 0; i < n_env; ++i ) { /* g_debug( "old envp[%d] = \"%s\"" , i, envp[i]); */ if ( 0 == strncmp( envp[ i ], "DISPLAY=", 8 ) ) display_index = i; else { if ( 0 == strncmp( envp[ i ], "DESKTOP_STARTUP_ID=", 19 ) ) startup_id_index = i; new_env[i] = g_strdup( envp[ i ] ); } } #ifdef HAVE_SN display = sn_display_new ( GDK_SCREEN_XDISPLAY ( screen ), ( SnDisplayErrorTrapPush ) gdk_error_trap_push, ( SnDisplayErrorTrapPush ) gdk_error_trap_pop ); if ( G_LIKELY ( display ) ) { if ( !disp_name ) disp_name = argv[ 0 ]; ctx = sn_launcher_context_new( display, gdk_screen_get_number( screen ) ); sn_launcher_context_set_description( ctx, disp_name ); sn_launcher_context_set_name( ctx, g_get_prgname() ); sn_launcher_context_set_binary_name( ctx, argv[ 0 ] ); sn_launcher_context_set_workspace ( ctx, tvsn_get_active_workspace_number( screen ) ); /* FIXME: I don't think this is correct, other people seem to use CurrentTime here. However, using CurrentTime causes problems, so I so it like this. Maybe this is incorrect, but it works, so, who cares? */ /* time( &cur_time ); */ sn_launcher_context_initiate( ctx, g_get_prgname(), argv[ 0 ], gtk_get_current_event_time() /*cur_time*/ ); setup_func = (GSpawnChildSetupFunc) sn_launcher_context_setup_child_process; if( startup_id_index >= 0 ) g_free( new_env[i] ); else startup_id_index = i++; new_env[ startup_id_index ] = g_strconcat( "DESKTOP_STARTUP_ID=", sn_launcher_context_get_startup_id ( ctx ), NULL ); } #endif /* This is taken from gdk_spawn_on_screen */ display_name = gdk_screen_make_display_name ( screen ); if ( display_index >= 0 ) new_env[ display_index ] = g_strconcat( "DISPLAY=", display_name, NULL ); else new_env[ i++ ] = g_strconcat( "DISPLAY=", display_name, NULL ); g_free( display_name ); new_env[ i ] = NULL; ret = g_spawn_async( work_dir, argv, new_env, flags, NULL, NULL, NULL, err ); /* for debugging */ #if 0 g_debug( "debug vfs_execute_on_screen(): flags: %d, display_index=%d", flags, display_index ); for( i = 0; argv[i]; ++i ) { g_debug( "argv[%d] = \"%s\"" , i, argv[i] ); } for( i = 0; i < n_env /*new_env[i]*/; ++i ) { g_debug( "new_env[%d] = \"%s\"" , i, new_env[i] ); } if( ret ) g_debug( "the program was executed without error" ); else g_debug( "launch failed: %s", (*err)->message ); #endif g_strfreev( new_env ); #ifdef HAVE_SN if ( G_LIKELY ( ctx ) ) { if ( G_LIKELY ( ret ) ) g_timeout_add ( 20 * 1000, sn_timeout, ctx ); else { sn_launcher_context_complete ( ctx ); sn_launcher_context_unref ( ctx ); } } if ( G_LIKELY ( display ) ) sn_display_unref ( display ); #endif return ret; }