Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 332497 - [Carbon]Eclipse RCP application steal focus
Summary: [Carbon]Eclipse RCP application steal focus
Status: RESOLVED WONTFIX
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.7   Edit
Hardware: Macintosh Mac OS X - Carbon (unsup.)
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact: Silenio Quarti CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-12-14 04:24 EST by alf CLA
Modified: 2012-06-20 11:41 EDT (History)
5 users (show)

See Also:


Attachments
my launcher code (9.25 KB, application/octet-stream)
2010-12-14 04:29 EST, alf CLA
no flags Details
bug image (25.75 KB, image/png)
2010-12-14 04:43 EST, alf CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description alf CLA 2010-12-14 04:24:39 EST
Build Identifier: I20101019-0800

I custom eclipse rcp application to my app. I code a my launcher(carbon code) to call eclipse launcher(eclipse execute file).
In my c launcher code:
main(){
    //(1) show menu
        IBNibRef menuNibRef = NULL;
	printf("Show menu before....... \n");
	if ( CreateNibReference(CFSTR("main"),&menuNibRef) == noErr) /* Make dock icon refresh */
	{
		SetMenuBarFromNib(menuNibRef,menubar);	 
		printf("Show menu after....... \n");
	}
      // (2) find out process name
		ProcessSerialNumber psn;
		CFStringRef name = NULL;
		char *nameCStr = (char *) malloc(sizeof(char) * 512);
		if (GetCurrentProcess(&psn) == noErr) {
			CopyProcessName(&psn,&name);
			CFStringGetCString(name, nameCStr, 512, kCFStringEncodingUTF8);
			printf("Run CopyProcessName() function.......\n ");
			printf("From A application, Process name is: %s \n" , nameCStr);
		}

      // (3) launcher eclipse
        char** cargs = (char**) malloc((2) * sizeof (char*));
	cargs[0]="/Applications/eclipse/Eclipse.app/Contents/MacOS/aaa/eclipse";
	cargs[1]=NULL;
	execv("/Applications/eclipse/Eclipse.app/Contents/MacOS/aaa/eclipse", cargs);
     printf("Hello, World!\n");
      return 0;
}

Problem: Eclipse steal focus twice. 
   (A) splash steal focus once.  I fixed it by creating Info.plist and adding "APPL". 
   (B) workbench steal focus once, if my launcher including (1) or (2) code. 
        If code only include:
           cargs[0]="/Applications/eclipse/Eclipse.app/Contents/MacOS/aaa/eclipse";
	cargs[1]=NULL;
	execv("/Applications/eclipse/Eclipse.app/Contents/MacOS/aaa/eclipse", cargs);
        workbench will do not steal focus.
 

Reproducible: Always

Steps to Reproduce:
1. Create RCP application, and export it to product.
2. Modify eclipse path layout.
    Copy eclispe product folder to /Applications. Into /Applications/eclipse/Eclipse.app/Contents/MacOS, create a folder named "aaa", move eclipes and eclipse.ini into this folder. For fix first problem, also need to copy Info.plist into this folder. For launcher eclipse, need to change eclipse.ini file to find out plugin.
3. Install my launcher.
download my launcher and copy it into /Applications/eclipse/Eclipse.app/Contents/MacOS, modify /Applications/eclipse/Eclipse.app/Contents/Info.plist contents "Executable file = alftestrcprun1"
4. Run eclispe by click Eclipse.app. 
5. Quickly open a "Finder", and waiting eclispe open. eclispe will show top.
Comment 1 alf CLA 2010-12-14 04:29:14 EST
Created attachment 185113 [details]
my launcher code

this launcher will make workbench steal focus...
Comment 2 alf CLA 2010-12-14 04:31:16 EST
Steal focus launcher source code:

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <stdio.h>
#include <Carbon/Carbon.h>
#define MAXPATH 1024
static const CFStringRef menubar = CFSTR("MenuBar"); /* globmenu.h MENU_TOPLEVEL */
int main (int argc, const char * argv[]) {
	
	IBNibRef menuNibRef = NULL;
	printf("Show menu before....... \n");
	if ( CreateNibReference(CFSTR("main"),&menuNibRef) == noErr) /* Make dock icon refresh */
	{
		SetMenuBarFromNib(menuNibRef,menubar);	 
		printf("Show menu after....... \n");
	}
	
		ProcessSerialNumber psn;
		CFStringRef name = NULL;
		char *nameCStr = (char *) malloc(sizeof(char) * 512);
		if (GetCurrentProcess(&psn) == noErr) {
			CopyProcessName(&psn,&name);
			CFStringGetCString(name, nameCStr, 512, kCFStringEncodingUTF8);
			printf("Run CopyProcessName() function.......\n ");
			printf("From A application, Process name is: %s \n" , nameCStr);
		}
	
    char** cargs = (char**) malloc((2) * sizeof (char*));
	cargs[0]="/Applications/eclipse/Eclipse.app/Contents/MacOS/aaa/eclipse";
	cargs[1]=NULL;
	execv("/Applications/eclipse/Eclipse.app/Contents/MacOS/aaa/eclipse", cargs);
    printf("Hello, World!\n");
    return 0;
}
Comment 3 alf CLA 2010-12-14 04:32:24 EST
Don't steal focus code:

#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <stdio.h>
#include <Carbon/Carbon.h>
#define MAXPATH 1024
static const CFStringRef menubar = CFSTR("MenuBar"); /* globmenu.h MENU_TOPLEVEL */
int main (int argc, const char * argv[]) {
 char** cargs = (char**) malloc((2) * sizeof (char*));
	cargs[0]="/Applications/eclipse/Eclipse.app/Contents/MacOS/aaa/eclipse";
	cargs[1]=NULL;
	execv("/Applications/eclipse/Eclipse.app/Contents/MacOS/aaa/eclipse", cargs);
    printf("Hello, World!\n");
    return 0;
}
Comment 4 alf CLA 2010-12-14 04:42:27 EST
By the way, I found out : 
      when workbench steal focus, just look like steal focus. I mean that you can click mac menu bar and find it changed. Please look attachment.
Comment 5 alf CLA 2010-12-14 04:43:32 EST
Created attachment 185115 [details]
bug image
Comment 6 Scott Kovatch CLA 2010-12-14 20:42:56 EST
Good detective work on this one... 

For the first problem, CreateNibReference needs to use the bundle manager to locate the nib file. If it can't find an Info.plist, it will synthesize one, and in the process of doing that, it registers with the process manager to get the name of the application. Supplying a correct Info.plist file prevents the bundle manager from having to infer the information that's normally in the Info.plist.

In the second case, calling GetCurrentProcess forces the application to register with the process manager, if it isn't already. Doing that turns the application into a foreground application, and it gets activated (stealing focus, as you have described.)

While this is all useful to know, is this code a modification of the existing launcher code? This isn't SWT code.
Comment 7 alf CLA 2010-12-14 22:23:50 EST
(In reply to comment #6)
> While this is all useful to know, is this code a modification of the existing
> launcher code? This isn't SWT code.

In our RCP application, we write a new program that call eclipse launcher to launcher eclipse.
Like this :  my launcher --> eclispe launcher --> JVM

I find out another problem. If you launch my RCP by UI(I mean click app in Finder),the eclispe workbench will steal focus. But you launch my RCP by shell(e.g. run /Application/eclispe/Eclipse.app/Contetents/MacOS/alftestrcprun1 in shell),it does not. So strange problem.
Comment 8 alf CLA 2010-12-14 22:30:02 EST
This bug only reproduce in carbon. Cocoa work well.
Comment 9 Grant Gayed CLA 2012-06-20 11:41:26 EDT
Closing report, platform is discontinued.