void sn_startup(gboolean reconfig) { if (reconfig) return; sn_display = sn_display_new(obt_display, NULL, NULL); sn_context = sn_monitor_context_new(sn_display, ob_screen, sn_event_func, NULL, NULL); sn_launcher = sn_launcher_context_new(sn_display, ob_screen); xqueue_add_callback(sn_handler, NULL); }
void sn_startup(gboolean reconfig) { if (reconfig) return; sn_display = sn_display_new(obt_display, NULL, NULL); sn_context = sn_monitor_context_new(sn_display, ob_screen, sn_event_func, NULL, NULL); sn_launcher = sn_launcher_context_new(sn_display, ob_screen); obt_main_loop_x_add(ob_main_loop, sn_handler, NULL, NULL); }
void init_X11() { server.dsp = XOpenDisplay(NULL); if (!server.dsp) DIE("tint: could not open display."); server_init_atoms(); server.screen = DefaultScreen(server.dsp); server.root_win = RootWindow(server.dsp, server.screen); server.desktop = server_get_current_desktop(); server_init_visual(); XSetErrorHandler((XErrorHandler)server_catch_error); #ifdef HAVE_SN // Initialize startup-notification server.sn_dsp = sn_display_new(server.dsp, error_trap_push, error_trap_pop); server.pids = g_tree_new(cmp_ptr); // Setup a handler for child termination struct sigaction act; memset(&act, 0, sizeof(struct sigaction)); act.sa_handler = sigchld_handler; if (sigaction(SIGCHLD, &act, 0)) { perror("sigaction"); } #endif // HAVE_SN imlib_context_set_display(server.dsp); imlib_context_set_visual(server.visual); imlib_context_set_colormap(server.colormap); /* Catch events */ XSelectInput(server.dsp, server.root_win, PropertyChangeMask | StructureNotifyMask); setlocale(LC_ALL, ""); // config file use '.' as decimal separator setlocale(LC_NUMERIC, "POSIX"); // load default icon gchar* path; const gchar* const* data_dirs; data_dirs = g_get_system_data_dirs(); int i; for (i = 0; data_dirs[i] != NULL; i++) { path = g_build_filename(data_dirs[i], "tinto", "default_icon.png", NULL); if (g_file_test(path, G_FILE_TEST_EXISTS)) default_icon = imlib_load_image(path); g_free(path); } // get monitor and desktop config get_monitors(); get_desktops(); }
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 */ }
static void startup_notification_complete(void) { Display *xdisplay; xdisplay = GDK_DISPLAY(); sn_display = sn_display_new(xdisplay, sn_error_trap_push, sn_error_trap_pop); sn_context = sn_launchee_context_new_from_environment(sn_display, DefaultScreen(xdisplay)); if (sn_context != NULL) { sn_launchee_context_complete(sn_context); sn_launchee_context_unref(sn_context); sn_display_unref(sn_display); } }
StartupNotify *startup_notify_start(const char *program, const char *icon) { #ifdef HAVE_LIBSTARTUP_NOTIFICATION const char *id; fl_open_display(); StartupNotify *s = new StartupNotify; s->display = sn_display_new(fl_display, error_trap_push, error_trap_pop); s->context = sn_launcher_context_new(s->display, fl_screen); sn_launcher_context_set_binary_name(s->context, program); sn_launcher_context_set_icon_name(s->context, icon); sn_launcher_context_initiate(s->context, "ede-launch", program, CurrentTime); id = sn_launcher_context_get_startup_id(s->context); if(!id) id = ""; edelib_setenv("DESKTOP_STARTUP_ID", id, 1); XSync(fl_display, False); return s; #else return 0; #endif }
// Indicate that launchee has completed startup void startup_completed(void) { SnLauncheeContext* launchee; Display* xdisplay; SnDisplay* display; // Open display xdisplay = XOpenDisplay(NULL); if (xdisplay != NULL) { // Create startup notification context display = sn_display_new(xdisplay, NULL, NULL); launchee = sn_launchee_context_new_from_environment(display, DefaultScreen(xdisplay)); // Indicate startup has completed and free resources if (launchee) { sn_launchee_context_complete(launchee); sn_launchee_context_unref(launchee); } sn_display_unref(display); XCloseDisplay(xdisplay); } }
int main(int argc, char **argv) { int i, x, y; /* Config Parameters */ int switch_count = 1; char *img_file = NULL; char *dotdesktop_file = NULL; MBDotDesktop *dd = NULL; Bool start_app = False; char png_path[256] = { 0 }; TrayApp = mb_tray_app_new ( "mb-applet-launcher", resize_callback, paint_callback, &argc, &argv ); for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { if (!strcmp ("--title", argv[i]) || !strcmp ("-n", argv[i])) { if (++i>=argc) usage (argv[0]); win_panel_title = argv[i]; switch_count += 2; continue; } if (!strcmp ("--kill", argv[i]) || !strcmp ("-k", argv[i])) { action = ACTION_KILL; switch_count++; continue; } if (!strcmp ("--start", argv[i]) || !strcmp ("-s", argv[i])) { start_app = True; switch_count++; continue; } if (!strcmp ("--kill", argv[i]) || !strcmp ("-k", argv[i])) { action = ACTION_KILL; switch_count++; continue; } if (!strcmp ("--relaunch", argv[i]) || !strcmp ("-l", argv[i])) { action = ACTION_NONE; switch_count++; continue; } if (!strcmp ("--message", argv[i]) || !strcmp ("-m", argv[i])) { action = ACTION_MESSAGE_DOCK; switch_count++; continue; } if (!strcmp ("--no-animation", argv[i]) || !strcmp ("-na", argv[i])) { DoAnimation = False; switch_count++; continue; } if (!strcmp ("--desktop", argv[i])) { if (++i>=argc) usage (argv[0]); dotdesktop_file = argv[i]; switch_count += 2; continue; } usage(argv[0]); } else break; } if (argc-switch_count < 2 && dotdesktop_file == NULL) usage(argv[0]); dpy = mb_tray_app_xdisplay(TrayApp); screen = mb_tray_app_xscreen(TrayApp); atom_wm_state = XInternAtom(dpy, "WM_STATE", False); atom_wm_delete = XInternAtom(dpy, "WM_DELETE_WINDOW", False); atom_wm_protos = XInternAtom(dpy, "WM_PROTOCOLS", False); pb = mb_pixbuf_new(dpy, mb_tray_app_xscreen(TrayApp)); if (dotdesktop_file != NULL) { if ((dd = mb_dotdesktop_new_from_file(dotdesktop_file)) != NULL && mb_dotdesktop_get(dd, "Name") && mb_dotdesktop_get(dd, "Icon") && mb_dotdesktop_get(dd, "Exec") ) { img_file = mb_dotdesktop_get(dd, "Icon"); if (img_file[0] != '/') { snprintf(png_path, 256, "%s/pixmaps/%s", DATADIR, mb_dotdesktop_get(dd, "Icon") ); img_file = strdup(png_path); } cmd_str = mb_dotdesktop_get_exec(dd); if (!win_panel_title) win_panel_title = mb_dotdesktop_get(dd, "Name"); #ifdef USE_LIBSN if (mb_dotdesktop_get(dd, "SingleInstance") && !strcasecmp(mb_dotdesktop_get(dd, "SingleInstance"), "true")) { action = ACTION_SI; } else if (mb_dotdesktop_get(dd, "StartupNotify") && !strcasecmp(mb_dotdesktop_get(dd, "StartupNotify"), "true")) { action = ACTION_SN; } else #endif if (mb_dotdesktop_get(dd, "X-MB-NoWindow") && !strcasecmp(mb_dotdesktop_get(dd, "X-MB-NoWindow"), "true")) { DoAnimation = False; action = ACTION_NONE; } } else { fprintf(stderr,"%s: failed to parse %s\n", argv[0], dotdesktop_file); exit(1); } } else { img_file = argv[switch_count]; if (img_file[0] != '/') { /* FIXME: should really get from theme */ snprintf(png_path, 256, "%s/pixmaps/%s", DATADIR, img_file); img_file = strdup(png_path); } cmd_str = arr_to_str(&argv[switch_count+1], argc - switch_count - 1); } if (!(img_icon = mb_pixbuf_img_new_from_file(pb, img_file))) { fprintf(stderr, "%s: failed to load image %s \n", argv[0], img_file ); exit(1); } /* make active button image */ img_icon_active = mb_pixbuf_img_clone(pb, img_icon); for (x=0; x<mb_pixbuf_img_get_width(img_icon); x++) for (y=0; y<mb_pixbuf_img_get_height(img_icon); y++) { int aa; unsigned char r,g,b,a; mb_pixbuf_img_get_pixel (pb, img_icon_active, x, y, &r, &g, &b, &a); aa = (int)a; aa -= 0x80; if (aa < 0) aa = 0; mb_pixbuf_img_set_pixel_alpha(img_icon_active, x, y, aa); } #ifdef USE_LIBSN if (action == ACTION_SN || action == ACTION_SI) sn_dpy = sn_display_new (dpy, NULL, NULL); #endif mb_tray_app_set_xevent_callback (TrayApp, xevent_callback ); mb_tray_app_set_button_callback (TrayApp, button_callback ); if (win_panel_title == NULL) /* XXX UTF8 naming */ { win_panel_title = malloc( strlen(argv[1+switch_count]) + strlen(" Launcher") + 1 ); strcpy(win_panel_title, argv[1+switch_count]); strcat(win_panel_title, " Launcher"); } mb_tray_app_set_name (TrayApp, win_panel_title); XSelectInput(dpy, mb_tray_app_xrootwin(TrayApp), SubstructureNotifyMask); signal(SIGCHLD, SIG_IGN); mb_tray_app_set_icon(TrayApp, pb, img_icon); /* make sure we always end up on the left of the panel */ mb_tray_app_request_offset (TrayApp, -1); if (start_app) { switch(action) { #ifdef USE_LIBSN case ACTION_SN: sn_activate(win_panel_title, cmd_str); break; case ACTION_SI: si_activate(win_panel_title, cmd_str); break; #endif case ACTION_NONE: fork_exec(cmd_str); break; case ACTION_KILL: case ACTION_TOGGLE_WIN_STATE: fork_exec(cmd_str); win_launched = get_launch_window(); break; } } mb_tray_app_main (TrayApp); XCloseDisplay(dpy); exit(0); }
int main(int argc, char **argv) { MBTrayApp *app = NULL; MBPixbufImage *img_icon = NULL; struct timeval tv; char *icon_path; struct timezone tz; struct tm *localTime = NULL; time_t actualTime; #if ENABLE_NLS setlocale (LC_ALL, ""); bindtextdomain (PACKAGE, DATADIR "/locale"); bind_textdomain_codeset (PACKAGE, "UTF-8"); textdomain (PACKAGE); #endif app = mb_tray_app_new ( _("Clock"), resize_callback, paint_callback, &argc, &argv ); if (app == NULL) usage(); Pixbuf = mb_pixbuf_new(mb_tray_app_xdisplay(app), mb_tray_app_xscreen(app)); Col = mb_col_new_from_spec(Pixbuf, "#000000"); Fnt = mb_font_new_from_string(mb_tray_app_xdisplay(app), "Sans bold"); mb_font_set_color (Fnt, Col); memset(&tv,0,sizeof(struct timeval)); /* Figure out number of seconds till next minute */ gettimeofday(&tv, &tz); actualTime = tv.tv_sec; localTime = localtime(&actualTime); tv.tv_usec = 0; tv.tv_sec = 60 - localTime->tm_sec; /* This we then get reset when first called to 60 */ mb_tray_app_set_timeout_callback (app, timeout_callback, &tv); mb_tray_app_set_button_callback (app, button_callback ); mb_tray_app_set_theme_change_callback (app, theme_change_callback ); if (file_exists(CONTEXT_APP)) { mb_tray_app_set_context_info (app, _("Set Time")); mb_tray_app_set_context_callback (app, context_callback); } if ((icon_path = mb_dot_desktop_icon_get_full_path (NULL, 16, "minitime.png")) != NULL) { if ((img_icon = mb_pixbuf_img_new_from_file(Pixbuf, icon_path)) != NULL) { mb_tray_app_set_icon(app, Pixbuf, img_icon); mb_pixbuf_img_free(Pixbuf, img_icon); } free(icon_path); } #ifdef USE_LIBSN sn_dpy = sn_display_new (mb_tray_app_xdisplay(app), NULL, NULL); #endif mb_tray_app_main (app); return 1; }
// 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; }