📄 vfs-execute.c
字号:
/** C Implementation: vfs-execute** Description: *** Author: Hong Jen Yee (PCMan) <pcman.tw (AT) gmail.com>, (C) 2006** Copyright: See COPYING file that comes with this distribution**/#include "vfs-execute.h"/* FIXME: Startup notification may cause problems */#define SN_API_NOT_YET_FROZEN#include <libsn/sn-launcher.h>#include <gtk/gtk.h>#include <gdk/gdkx.h>#include <X11/Xatom.h>#include <string.h>#include <stdlib.h>#include <time.h>gboolean vfs_exec( const char* work_dir, char** argv, char** envp, const char* disp_name, GSpawnFlags flags, GError **err ){ return vfs_exec_on_screen( gdk_screen_get_default(), work_dir, argv, envp, disp_name, flags, err );}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;}/* This function is taken from the code of thunar, written by Benedikt Meurer <benny@xfce.org> */static ginttvsn_get_active_workspace_number ( GdkScreen *screen ){ GdkWindow * root; gulong bytes_after_ret = 0; gulong nitems_ret = 0; guint *prop_ret = NULL; Atom _NET_CURRENT_DESKTOP; Atom _WIN_WORKSPACE; Atom type_ret = None; gint format_ret; gint ws_num = 0; gdk_error_trap_push (); root = gdk_screen_get_root_window ( screen ); /* determine the X atom values */ _NET_CURRENT_DESKTOP = XInternAtom ( GDK_WINDOW_XDISPLAY ( root ), "_NET_CURRENT_DESKTOP", False ); _WIN_WORKSPACE = XInternAtom ( GDK_WINDOW_XDISPLAY ( root ), "_WIN_WORKSPACE", False ); if ( XGetWindowProperty ( GDK_WINDOW_XDISPLAY ( root ), GDK_WINDOW_XWINDOW ( root ), _NET_CURRENT_DESKTOP, 0, 32, False, XA_CARDINAL, &type_ret, &format_ret, &nitems_ret, &bytes_after_ret, ( gpointer ) & prop_ret ) != Success ) { if ( XGetWindowProperty ( GDK_WINDOW_XDISPLAY ( root ), GDK_WINDOW_XWINDOW ( root ), _WIN_WORKSPACE, 0, 32, False, XA_CARDINAL, &type_ret, &format_ret, &nitems_ret, &bytes_after_ret, ( gpointer ) & prop_ret ) != Success ) { if ( G_UNLIKELY ( prop_ret != NULL ) ) { XFree ( prop_ret ); prop_ret = NULL; } } } if ( G_LIKELY ( prop_ret != NULL ) ) { if ( G_LIKELY ( type_ret != None && format_ret != 0 ) ) ws_num = *prop_ret; XFree ( prop_ret ); } gdk_error_trap_pop (); return ws_num;}gboolean vfs_exec_on_screen( GdkScreen* screen, const char* work_dir, char** argv, char** envp, const char* disp_name, GSpawnFlags flags, GError **err ){ SnLauncherContext * ctx = NULL; SnDisplay* display; 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; time_t cur_time; if ( ! envp ) envp = environ; while ( envp[ n_env ] ) ++n_env; new_env = g_new( char*, n_env + 2 ); for ( i = 0; i < n_env; ++i ) { if ( strncmp( envp[ i ], "DISPLAY=", 8 ) == 0 ) display_index = i; else if ( strncmp( envp[ i ], "DESKTOP_STARTUP_ID=", 19 ) ) new_env[ i ] = g_strdup( envp[ i ] ); } 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 = sn_launcher_context_setup_child_process; new_env[ i++ ] = g_strconcat( "DESKTOP_STARTUP_ID=", sn_launcher_context_get_startup_id ( ctx ), NULL ); } /* 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 { ++n_env; 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 ); g_strfreev( new_env ); if ( G_LIKELY ( ctx ) ) { if ( G_LIKELY ( ret ) ) g_timeout_add ( 30 * 1000, sn_timeout, ctx ); else { sn_launcher_context_complete ( ctx ); sn_launcher_context_unref ( ctx ); } } if ( G_LIKELY ( display ) ) sn_display_unref ( display ); return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -