Esempio n. 1
0
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;
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
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
}
Esempio n. 4
0
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);
        }
    }
}
Esempio n. 5
0
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);
}
Esempio n. 6
0
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  */
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
// 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);
}
Esempio n. 9
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;
}