//printf("delete glx=%08x, win=%08x %s\n", (unsigned)glx_win, (unsigned)win, title);
#ifdef HAVE_GL
if( get_resources()->get_synchronous() && glx_win != 0 ) {
+ if( window_type == MAIN_WINDOW )
+ unlock_window();
get_resources()->get_synchronous()->delete_window(this);
+ if( window_type == MAIN_WINDOW )
+ lock_window("BC_WindowBase::delete_window");
}
#endif
XDestroyWindow(top_level->display, win);
mask = CWEventMask | CWBackPixel | CWColormap |
CWOverrideRedirect | CWSaveUnder | CWCursor;
- attr.event_mask = DEFAULT_EVENT_MASKS |
- KeyPressMask |
- KeyReleaseMask;
+ attr.event_mask = DEFAULT_EVENT_MASKS | ExposureMask |
+ KeyPressMask | KeyReleaseMask;
if(this->bg_color == -1)
this->bg_color = resources.get_bg_color();
init_lock->unlock();
// Handle common events
- while(!done)
- {
- dispatch_event(0);
+ while( !done ) {
+ dispatch_event();
}
unset_all_repeaters();
int locking_event = -1;
int locking_message = -1;
-int BC_WindowBase::dispatch_event(XEvent *event)
+int BC_WindowBase::dispatch_event()
{
Window tempwin;
int result;
XClientMessageEvent *ptr;
int cancel_resize, cancel_translation;
- const int debug = 0;
+ volatile static int debug = 0;
+ XEvent *event;
key_pressed = 0;
-//static const char *event_names[] = {
-// "Reply", "Error", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease", "MotionNotify",
-// "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut", "KeymapNotify", "Expose", "GraphicsExpose",
-// "NoExpose", "VisibilityNotify", "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify",
-// "MapRequest", "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify",
-// "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify", "SelectionClear",
-// "SelectionRequest", "SelectionNotify", "ColormapNotify", "ClientMessage", "MappingNotify",
-// "GenericEvent", "LASTEvent",
-//};
-//
-//if(debug)
-//if(event->type != ClientMessage) {
-// printf("BC_WindowBase::dispatch_event %d %s %p %d (%s)\n",
-//__LINE__, title, event, event->type,
-// event->type>=0 && event->type<sizeof(event_names)/sizeof(event_names[0]) ?
-// event_names[event->type] : "Unknown");
-//}
+if( debug && event->type != ClientMessage ) {
+ static const char *event_names[] = {
+ "Reply", "Error", "KeyPress", "KeyRelease", "ButtonPress", "ButtonRelease", "MotionNotify",
+ "EnterNotify", "LeaveNotify", "FocusIn", "FocusOut", "KeymapNotify", "Expose", "GraphicsExpose",
+ "NoExpose", "VisibilityNotify", "CreateNotify", "DestroyNotify", "UnmapNotify", "MapNotify",
+ "MapRequest", "ReparentNotify", "ConfigureNotify", "ConfigureRequest", "GravityNotify",
+ "ResizeRequest", "CirculateNotify", "CirculateRequest", "PropertyNotify", "SelectionClear",
+ "SelectionRequest", "SelectionNotify", "ColormapNotify", "ClientMessage", "MappingNotify",
+ "GenericEvent", "LASTEvent",
+ };
+ const int nevents = sizeof(event_names)/sizeof(event_names[0]);
+
+ printf("BC_WindowBase::dispatch_event %d %s %p %d (%s)\n", __LINE__,
+ title, event, event->type, event->type>=0 && event->type<nevents ?
+ event_names[event->type] : "Unknown");
+}
if( active_grab ) {
unlock_window();
switch(event->type) {
case ClientMessage:
// Clear the resize buffer
- if(resize_events) dispatch_resize_event(last_resize_w, last_resize_h);
+ if( resize_events )
+ dispatch_resize_event(last_resize_w, last_resize_h);
// Clear the motion buffer since this can clear the window
- if(motion_events)
- {
+ if( motion_events )
dispatch_motion_event();
- }
ptr = (XClientMessageEvent*)event;
-
-
- if(ptr->message_type == ProtoXAtom &&
- (Atom)ptr->data.l[0] == DelWinXAtom)
- {
+ if( ptr->message_type == ProtoXAtom &&
+ (Atom)ptr->data.l[0] == DelWinXAtom ) {
close_event();
}
- else
- if(ptr->message_type == RepeaterXAtom)
- {
+ else if( ptr->message_type == RepeaterXAtom ) {
dispatch_repeat_event(ptr->data.l[0]);
-// Make sure the repeater still exists.
-// for(int i = 0; i < repeaters.total; i++)
-// {
-// if(repeaters.values[i]->repeat_id == ptr->data.l[0])
-// {
-// dispatch_repeat_event_master(ptr->data.l[0]);
-// break;
-// }
-// }
}
- else
- if(ptr->message_type == SetDoneXAtom)
- {
+ else if( ptr->message_type == SetDoneXAtom ) {
done = 1;
- } else
- { // We currently use X marshalling for xatom events, we can switch to something else later
- receive_custom_xatoms((xatom_event *)ptr);
+ }
+ else {
+ receive_custom_xatoms((xatom_event *)ptr);
}
break;
case Expose:
event_win = event->xany.window;
- dispatch_expose_event();
+ result = 0;
+ for( int i=0; !result && i<popups.size(); ++i ) { // popups take focus
+ if( popups[i]->win == event_win )
+ result = popups[i]->dispatch_expose_event();
+ }
+ if( !result )
+ result = dispatch_expose_event();
break;
case MotionNotify:
return 0;
}
+int BC_WindowBase::break_lock()
+{
+ if( !top_level ) return 0;
+ if( top_level != this ) return top_level->break_lock();
+ if( top_level->display_lock_owner != pthread_self() ) return 0;
+ if( top_level->window_lock != 1 ) return 0;
+ UNSET_LOCK(this);
+ window_lock = 0;
+ display_lock_owner = 0;
+#ifdef SINGLE_THREAD
+ BC_Display::unlock_display();
+#else
+ XUnlockDisplay(display);
+#endif
+ return 1;
+}
+
void BC_WindowBase::set_done(int return_value)
{
if(done_set) return;
size_hints.max_width = w;
size_hints.min_height = h;
size_hints.max_height = h;
+ if( this->x > -BC_INFINITY && this->x < BC_INFINITY ) {
+ size_hints.flags |= PPosition;
+ size_hints.x = this->x;
+ size_hints.y = this->y;
+ }
XSetNormalHints(top_level->display, win, &size_hints);
}
XResizeWindow(top_level->display, win, w, h);