Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

ccjimmy

macrumors newbie
Original poster
Mar 15, 2011
14
0
My program create a window using GLUT,
when this program running on WINDOWS XP, the "glutEntryFunc" works well, which means when I leave the window I created by "glutCreateWindow" and click other windows by mouse_L button, the window will loss focus,when I enter the window I created and click by hit mouse_L button, the Window will retrieve the Focus.

but on MAC OS, when my mouse leave the Window without mouse click, it will lose Focus, why?

how can I make it works well as in WINDOWS XP on MAC OS?

below is the sample code, it will works both on MAC OS and WINDOWS XP.


#include <stdio.h>
#include "GLUT.h"
#include <stdlib.h>

void Update(int para)
{
glutPostRedisplay();
glutTimerFunc(17,Update,0);
}

void exitfunc(int para)
{
exit(0);
}
void key_process(unsigned char key,int x,int y)
{
if(key == '\033')//ESC
{
exit(0);
}
}

void display()
{
glClear(GL_COLOR_BUFFER_BIT);
glutSwapBuffers();
}

void focus_lost(int bAct)
{
if(bAct == GLUT_ENTERED)
{
printf("get focus \n");
}
else
{
printf("lose focus\n");
}
}

int main(int argc, char ** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
{
glutInitWindowSize(1024,768);
}
glutCreateWindow("Xcode Glut Demo");
glutTimerFunc(17, Update,0);
glutDisplayFunc(display);
glutKeyboardFunc(key_process);
glutEntryFunc(focus_lost);
glutMainLoop();
}
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
You're mistaken about the behaviour of the entry callback. It's an entry callback, not a focus callback. It is meant to be called when the mouse enters or leaves the window, not just when window gains or looses focus. The Windows behaviour is wrong here. See the GLUT3 spec: http://www.opengl.org/resources/libraries/glut/spec3/node53.html

AFAIK you can't get notifications for when the window gains or loses focus using just GLUT.
 

ccjimmy

macrumors newbie
Original poster
Mar 15, 2011
14
0
You're mistaken about the behaviour of the entry callback. It's an entry callback, not a focus callback. It is meant to be called when the mouse enters or leaves the window, not just when window gains or looses focus. The Windows behaviour is wrong here. See the GLUT3 spec: http://www.opengl.org/resources/libraries/glut/spec3/node53.html

AFAIK you can't get notifications for when the window gains or loses focus using just GLUT.

yes, I was mistaken...

besides GLUT, any idear for me to handle gain/loss focus of my program?
 

jiminaus

macrumors 65816
Dec 16, 2010
1,449
1
Sydney
besides GLUT, any idear for me to handle gain/loss focus of my program?

It involves some Objective-C, but I've coded a solution which gets your focus_lost function called when the application itself loses focus. This is the same as the window losing focus, assuming you only ever have one window open at a time.

If you use XCode, just add focuslistener.h and focuslistener.m to your project. You might also need to add the Cocoa framework to your target.

If you're compiling from Terminal, put focuslistener.h and focuslistener.m next to main.c and the compile with:
Code:
gcc -framework GLUT -framework OpenGL -framework Cocoa -o gluttest main.c focuslistener.m
Change gluttest to whatever you want the executable to be called.

main.c
Code:
#include <stdio.h>
#include <GLUT/GLUT.h>
#include <stdlib.h>

[color=blue]#ifdef __APPLE__
#include "focuslistener.h"
#endif[/color]

void Update(int para)
{
    glutPostRedisplay();
    glutTimerFunc(17,Update,0);
}

void exitfunc(int para)
{
    exit(0);
}

void key_process(unsigned char key,int x,int y)
{	
    if(key == '\033')//ESC
    {	
        exit(0);
    }
}

void display() 
{ 
    glClear(GL_COLOR_BUFFER_BIT);
    glutSwapBuffers();
}

void focus_lost(int bAct)
{
    if(bAct == GLUT_ENTERED)
    {
        printf("get focus \n");
    }
    else
    {
        printf("lose focus\n");
    }
}

[color=blue]void myEntryFunc(void (*callback)(int))
{
#ifdef __APPLE__
    setupFocusListener(callback);
#else
    glutEntryFunc(callback);
#endif
}[/color]

int main(int argc, char ** argv) 
{ 
    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
    {
        glutInitWindowSize(1024,768);	
    }
    glutCreateWindow("Xcode Glut Demo"); 
    glutTimerFunc(17, Update,0);
    glutDisplayFunc(display);
    glutKeyboardFunc(key_process);
    [color=blue]myEntryFunc(focus_lost);[/color]
    glutMainLoop(); 
}

focuslistener.h
Code:
#ifdef __OBJC__

#import <Foundation/Foundation.h>

@interface FocusListener : NSObject {
@private
    void (*callback)(int);
}

@property (assign, nonatomic) void (*callback)(int);

- (void)applicationDidBecomeActiveNotification:(NSNotification *)aNotification;
- (void)applicationDidResignActiveNotification:(NSNotification *)aNotification;

@end

#endif

void setupFocusListener(void (*callback)(int));

focustlistener.m
Code:
#import "focuslistener.h"
#import <Cocoa/Cocoa.h>
#import <GLUT/GLUT.h>

@implementation FocusListener

@synthesize callback;

- (id)init
{
    self = [super init];
    if (self) {
        callback = NULL;
    }
    return self;
}

- (void)applicationDidBecomeActiveNotification:(NSNotification *)aNotification
{
    if (callback) {
        callback(GLUT_ENTERED);
    }
}

- (void)applicationDidResignActiveNotification:(NSNotification *)aNotification
{
    if (callback) {
        callback(GLUT_LEFT);
    }
}

@end

void setupFocusListener(void (*callback)(int))
{
    static FocusListener *listener = nil;
    
    if (!listener) {
        listener = [[FocusListener alloc] init];
        NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
        [center addObserver:listener selector:@selector(applicationDidBecomeActiveNotification:) name:NSApplicationDidBecomeActiveNotification object:nil];
        [center addObserver:listener selector:@selector(applicationDidResignActiveNotification:) name:NSApplicationDidResignActiveNotification object:nil];
    }
    
    listener.callback = callback;    
}
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.