3232#include <unistd.h>
3333#include <math.h>
3434#include <limits.h>
35+ #include <sys/wait.h>
3536
3637#include <X11/Xlib.h>
3738#include <X11/Xutil.h>
@@ -115,8 +116,8 @@ static CFStringRef dClip = CFSTR("Clip");
115116
116117static void dockIconPaint (CFRunLoopTimerRef timer , void * data );
117118static void iconMouseDown (WObjDescriptor * desc , XEvent * event );
118- static pid_t execCommand (WAppIcon * btn , const char * command , WSavedState * state );
119- static void trackDeadProcess (pid_t pid , unsigned char status , WDock * dock );
119+ static pid_t _dockExecCommand (WAppIcon * btn , const char * command , WSavedState * state );
120+ static void _dockHandleProcessExit (pid_t pid , unsigned char status , WDock * dock );
120121static int getClipButton (int px , int py );
121122static void toggleLowered (WDock * dock );
122123static void toggleCollapsed (WDock * dock );
@@ -807,7 +808,7 @@ static void launchDockedApplication(WAppIcon *btn, Bool withSelection)
807808 btn -> flags .drop_launch = 0 ;
808809 btn -> flags .paste_launch = withSelection ;
809810 scr -> last_dock = btn -> dock ;
810- btn -> pid = execCommand (btn , (withSelection ? btn -> paste_command : btn -> command ), NULL );
811+ btn -> pid = _dockExecCommand (btn , (withSelection ? btn -> paste_command : btn -> command ), NULL );
811812 if (btn -> pid > 0 ) {
812813 if (btn -> flags .buggy_app ) {
813814 /* give feedback that the app was launched */
@@ -1741,7 +1742,7 @@ void wDockLaunchWithState(WAppIcon *btn, WSavedState *state)
17411742 btn -> flags .drop_launch = 0 ;
17421743 btn -> flags .paste_launch = 0 ;
17431744
1744- btn -> pid = execCommand (btn , btn -> command , state );
1745+ btn -> pid = _dockExecCommand (btn , btn -> command , state );
17451746
17461747 if (btn -> pid > 0 ) {
17471748 if (!btn -> flags .forced_dock && !btn -> flags .buggy_app ) {
@@ -1862,7 +1863,7 @@ int wDockReceiveDNDDrop(WScreen *scr, XEvent *event)
18621863 btn -> flags .paste_launch = 0 ;
18631864 btn -> flags .drop_launch = 1 ;
18641865 scr -> last_dock = dock ;
1865- btn -> pid = execCommand (btn , btn -> dnd_command , NULL );
1866+ btn -> pid = _dockExecCommand (btn , btn -> dnd_command , NULL );
18661867 if (btn -> pid > 0 ) {
18671868 dockIconPaint (NULL , btn );
18681869 } else {
@@ -2754,7 +2755,53 @@ static void swapDock(WDock *dock)
27542755 wScreenUpdateUsableArea (scr );
27552756}
27562757
2757- static pid_t execCommand (WAppIcon * btn , const char * command , WSavedState * state )
2758+ static void _dockHandleProcessExit (pid_t pid , unsigned char status , WDock * dock )
2759+ {
2760+ WAppIcon * icon ;
2761+ int i ;
2762+
2763+ CFLog (kCFLogLevelInfo , CFSTR ("%s: PID == %i, exit status == %i" ), __func__ , pid , status );
2764+
2765+ for (i = 0 ; i < dock -> max_icons ; i ++ ) {
2766+ icon = dock -> icon_array [i ];
2767+ if (!icon )
2768+ continue ;
2769+
2770+ if (icon -> flags .launching && icon -> pid == pid ) {
2771+ if (!icon -> flags .relaunching ) {
2772+ icon -> flags .running = 0 ;
2773+ icon -> main_window = None ;
2774+ }
2775+ wDockFinishLaunch (icon );
2776+ icon -> pid = 0 ;
2777+ if (status != 0 ) {
2778+ char msg [PATH_MAX ];
2779+ char * cmd ;
2780+ char * message ;
2781+
2782+ #ifdef USE_DOCK_XDND
2783+ if (icon -> flags .drop_launch )
2784+ cmd = icon -> dnd_command ;
2785+ else
2786+ #endif
2787+ if (icon -> flags .paste_launch )
2788+ cmd = icon -> paste_command ;
2789+ else
2790+ cmd = icon -> command ;
2791+
2792+ snprintf (msg , sizeof (msg ), _ ("Could not execute command \"%s\"\n%s" ), cmd , strerror (errno ));
2793+ message = wstrdup (msg );
2794+ dispatch_sync (workspace_q , ^{
2795+ WSRunAlertPanel (_ ("Workspace Dock" ), message , _ ("Got It" ), NULL , NULL );
2796+ wfree (message );
2797+ });
2798+ }
2799+ break ;
2800+ }
2801+ }
2802+ }
2803+
2804+ static pid_t _dockExecCommand (WAppIcon * btn , const char * command , WSavedState * state )
27582805{
27592806 WScreen * scr = btn -> icon -> core -> screen_ptr ;
27602807 pid_t pid ;
@@ -2805,8 +2852,13 @@ static pid_t execCommand(WAppIcon *btn, const char *command, WSavedState *state)
28052852 sigprocmask (SIG_UNBLOCK , & sigs , NULL );
28062853
28072854 args [argc ] = NULL ;
2808- execvp (argv [0 ], args );
2809- exit (111 );
2855+ int ret ;
2856+ ret = execvp (argv [0 ], args );
2857+ if (ret < 0 ) {
2858+ CFLog (kCFLogLevelError , CFSTR ("%s: return %i error #%i -- %s" ), __func__ , ret , errno ,
2859+ strerror (errno ));
2860+ }
2861+ exit (ret );
28102862 }
28112863 wtokenfree (argv , argc );
28122864
@@ -2822,9 +2874,9 @@ static pid_t execCommand(WAppIcon *btn, const char *command, WSavedState *state)
28222874 state -> desktop = scr -> current_desktop ;
28232875 }
28242876 wWindowAddSavedState (btn -> wm_instance , btn -> wm_class , cmdline , pid , state );
2825- if (strcmp (btn -> wm_class , "GNUstep" )) {
2826- wAddExitHandler (pid , (WExitHandler * )trackDeadProcess , btn -> dock );
2827- }
2877+ // if (strcmp(btn->wm_class, "GNUstep")) {
2878+ wAddExitHandler (pid , (WExitHandler * )_dockHandleProcessExit , btn -> dock );
2879+ // }
28282880 } else if (state ) {
28292881 wfree (state );
28302882 }
@@ -3157,50 +3209,6 @@ void wClipUpdateForDesktopChange(WScreen *scr, int desktop)
31573209 }
31583210}
31593211
3160- static void trackDeadProcess (pid_t pid , unsigned char status , WDock * dock )
3161- {
3162- WAppIcon * icon ;
3163- int i ;
3164-
3165- for (i = 0 ; i < dock -> max_icons ; i ++ ) {
3166- icon = dock -> icon_array [i ];
3167- if (!icon )
3168- continue ;
3169-
3170- if (icon -> flags .launching && icon -> pid == pid ) {
3171- if (!icon -> flags .relaunching ) {
3172- icon -> flags .running = 0 ;
3173- icon -> main_window = None ;
3174- }
3175- wDockFinishLaunch (icon );
3176- icon -> pid = 0 ;
3177- if (status == 111 ) {
3178- char msg [PATH_MAX ];
3179- char * cmd ;
3180- char * message ;
3181-
3182- #ifdef USE_DOCK_XDND
3183- if (icon -> flags .drop_launch )
3184- cmd = icon -> dnd_command ;
3185- else
3186- #endif
3187- if (icon -> flags .paste_launch )
3188- cmd = icon -> paste_command ;
3189- else
3190- cmd = icon -> command ;
3191-
3192- snprintf (msg , sizeof (msg ), _ ("Could not execute command \"%s\"" ), cmd );
3193- message = wstrdup (msg );
3194- dispatch_async (workspace_q , ^{
3195- WSRunAlertPanel (_ ("Workspace Dock" ), message , _ ("Got It" ), NULL , NULL );
3196- wfree (message );
3197- });
3198- }
3199- break ;
3200- }
3201- }
3202- }
3203-
32043212/* This function is called when the dock switches state between
32053213 * "normal" (including auto-raise/lower) and "keep on top". It is
32063214 * therefore clearly distinct from wDockLower/Raise, which are called
@@ -3783,7 +3791,7 @@ static void iconMouseDown(WObjDescriptor *desc, XEvent *event)
37833791 if (dock -> menu -> flags .mapped )
37843792 wMenuUnmap (dock -> menu );
37853793
3786- if (IsDoubleClick (scr , event )) {
3794+ if (wEventIsDoubleClick (scr , event )) {
37873795 /* double-click was not on the main Dock or Clip icon */
37883796 /* || getClipButton(event->xbutton.x, event->xbutton.y) == CLIP_IDLE) { */
37893797 if (dock -> type == WM_DOCK && aicon -> yindex != 0 ) {
0 commit comments