X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fguicast%2Fbcwindowbase.C;h=1ef0d5939cc8e697ae71ffe3a94b2bbcdc894b3b;hp=823d81aa609b18099724ca341cd2d24d2e876dfd;hb=04031cc2a664d2a6d9d2a37954c55cc68742d78c;hpb=72a6abf751403bd91464e77ff2cece01c9756a6b diff --git a/cinelerra-5.1/guicast/bcwindowbase.C b/cinelerra-5.1/guicast/bcwindowbase.C index 823d81aa..1ef0d593 100644 --- a/cinelerra-5.1/guicast/bcwindowbase.C +++ b/cinelerra-5.1/guicast/bcwindowbase.C @@ -36,7 +36,7 @@ #include "bcwindowbase.h" #include "bcwindowevents.h" #include "bccmodels.h" -#include "colors.h" +#include "bccolors.h" #include "condition.h" #include "cursors.h" #include "bchash.h" @@ -46,6 +46,7 @@ #include "mutex.h" #include "sizes.h" #include "vframe.h" +#include "workarounds.h" #ifdef HAVE_GL #include @@ -61,7 +62,6 @@ #include #include - BC_ResizeCall::BC_ResizeCall(int w, int h) { this->w = w; @@ -85,9 +85,8 @@ Window XGroupLeader = 0; Mutex BC_KeyboardHandlerLock::keyboard_listener_mutex("keyboard_listener",0); ArrayList BC_KeyboardHandler::listeners; -BC_WindowBase::BC_WindowBase(int opts) +BC_WindowBase::BC_WindowBase() { - this->options = opts; //printf("BC_WindowBase::BC_WindowBase 1\n"); BC_WindowBase::initialize(); } @@ -147,13 +146,13 @@ BC_WindowBase::~BC_WindowBase() delete pixmap; +//printf("delete glx=%08x, win=%08x %s\n", (unsigned)glx_win, (unsigned)win, title); #ifdef HAVE_GL - if( get_resources()->get_synchronous() && - (top_level->options & GLX_WINDOW) && glx_win != 0 ) + if( get_resources()->get_synchronous() && glx_win != 0 ) { get_resources()->get_synchronous()->delete_window(this); - else + } #endif - XDestroyWindow(top_level->display, win); + XDestroyWindow(top_level->display, win); if(bg_pixmap && !shared_bg_pixmap) delete bg_pixmap; if(icon_pixmap) delete icon_pixmap; @@ -177,13 +176,17 @@ BC_WindowBase::~BC_WindowBase() &BC_WindowBase::mediumfont, &BC_WindowBase::largefont, &BC_WindowBase::bigfont, + &BC_WindowBase::clockfont, }; for( int i=sizeof(xfont)/sizeof(xfont[0]); --i>=0; ) XFreeFont(display, this->*xfont[i]); -// bug in X causes XRenderExtensionInfo to be damaged if this is done here -// left to be done in XCloseDisplay by Xlib. -#if defined(HAVE_XFT) && 0 +#ifdef HAVE_XFT +// prevents a bug when Xft closes with unrefd fonts + FcPattern *defaults = FcPatternCreate(); + FcPatternAddInteger(defaults, "maxunreffonts", 0); + XftDefaultSet(display, defaults); + static void *BC_WindowBase::*xft_font[] = { &BC_WindowBase::smallfont_xft, &BC_WindowBase::mediumfont_xft, @@ -192,10 +195,11 @@ BC_WindowBase::~BC_WindowBase() &BC_WindowBase::bold_smallfont_xft, &BC_WindowBase::bold_mediumfont_xft, &BC_WindowBase::bold_largefont_xft, + &BC_WindowBase::clockfont_xft, }; for( int i=sizeof(xft_font)/sizeof(xft_font[0]); --i>=0; ) { XftFont *xft = (XftFont *)(this->*xft_font[i]); - if( xft ) XftFontClose (display, xft); + if( xft ) xftFontClose (display, xft); } #endif finit_im(); @@ -210,23 +214,15 @@ BC_WindowBase::~BC_WindowBase() XvUngrabPort(display, xvideo_port_id, CurrentTime); unlock_window(); -// Can't close display if another thread is waiting for events. -// Synchronous thread must delete display it owns a GLX_WINDOW // Must be last reference to display. -#ifndef SINGLE_THREAD -#ifdef HAVE_GL - if( (options & GLX_DISPLAY) != 0 && get_resources()->get_synchronous() ) { - printf(_("BC_WindowBase::~BC_WindowBase window deleted but opengl deletion is not\n" - "implemented for BC_Pixmap.\n")); - get_resources()->get_synchronous()->delete_display(this); - } - else -#endif - XCloseDisplay(display); +// _XftDisplayInfo needs a lock. + get_resources()->create_window_lock->lock("BC_WindowBase::~BC_WindowBase"); + XCloseDisplay(display); + get_resources()->create_window_lock->unlock(); + // clipboard uses a different display connection clipboard->stop_clipboard(); delete clipboard; -#endif // SINGLE_THREAD } resize_history.remove_all_objects(); @@ -261,6 +257,7 @@ int BC_WindowBase::initialize() keys_return[0] = 0; is_deleting = 0; window_lock = 0; + resend_event_window = 0; x = 0; y = 0; w = 0; @@ -295,6 +292,7 @@ int BC_WindowBase::initialize() active_menubar = 0; active_popup_menu = 0; active_subwindow = 0; + cursor_entered = 0; pixmap = 0; bg_pixmap = 0; _7segment_pixmaps = 0; @@ -302,7 +300,6 @@ int BC_WindowBase::initialize() force_tooltip = 0; // next_repeat_id = 0; tooltip_popup = 0; - tooltip_done = 0; current_font = MEDIUMFONT; current_color = BLACK; current_cursor = ARROW_CURSOR; @@ -325,16 +322,24 @@ int BC_WindowBase::initialize() #ifdef HAVE_LIBXXF86VM vm_switched = 0; #endif - smallfont_xft = 0; - bold_largefont_xft = 0; - bold_mediumfont_xft = 0; - bold_smallfont_xft = 0; input_method = 0; input_context = 0; + smallfont = 0; + mediumfont = 0; + largefont = 0; + bigfont = 0; + clockfont = 0; + + smallfont_xft = 0; mediumfont_xft = 0; largefont_xft = 0; bigfont_xft = 0; + clockfont_xft = 0; + + bold_smallfont_xft = 0; + bold_mediumfont_xft = 0; + bold_largefont_xft = 0; #ifdef SINGLE_THREAD completion_lock = new Condition(0, "BC_WindowBase::completion_lock"); #else @@ -371,22 +376,10 @@ int BC_WindowBase::initialize() FocusChangeMask -int BC_WindowBase::create_window(BC_WindowBase *parent_window, - const char *title, - int x, - int y, - int w, - int h, - int minw, - int minh, - int allow_resize, - int private_color, - int hide, - int bg_color, - const char *display_name, - int window_type, - BC_Pixmap *bg_pixmap, - int group_it) +int BC_WindowBase::create_window(BC_WindowBase *parent_window, const char *title, + int x, int y, int w, int h, int minw, int minh, int allow_resize, + int private_color, int hide, int bg_color, const char *display_name, + int window_type, BC_Pixmap *bg_pixmap, int group_it) { XSetWindowAttributes attr; unsigned long mask; @@ -398,12 +391,8 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, #endif id = get_resources()->get_id(); - int need_lock = 0; if(parent_window) top_level = parent_window->top_level; - if( top_level ) { // need this to avoid deadlock with Xlib's locks - need_lock = 1; - lock_window("BC_WindowBase::create_window"); - } + if( top_level ) lock_window("BC_WindowBase::create_window"); get_resources()->create_window_lock->lock("BC_WindowBase::create_window"); #ifdef HAVE_LIBXXF86VM @@ -427,7 +416,7 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, else this->display_name[0] = 0; - put_title(_(title)); + put_title(title); if(bg_pixmap) shared_bg_pixmap = 1; subwindows = new BC_SubWindowList; @@ -453,6 +442,7 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, if( shm_completion_event < 0 ) shm_completion_event = ShmCompletion + XShmGetEventBase(display); #endif + lock_window("BC_WindowBase::create_window 1"); screen = DefaultScreen(display); rootwin = RootWindow(display, screen); @@ -530,24 +520,11 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, size_hints.x = this->x; size_hints.y = this->y; } - - char *txlist[2]; - txlist[0] = this->title; - txlist[1] = 0; - XTextProperty titleprop; - if(options & WINDOW_UTF8) - Xutf8TextListToTextProperty(display, txlist, 1, - XUTF8StringStyle, &titleprop); - else - XmbTextListToTextProperty(display, txlist, 1, - XStdICCTextStyle, &titleprop); - XSetWMProperties(display, win, &titleprop, &titleprop, - 0, 0, &size_hints, 0, 0); - XFree(titleprop.value); + XSetWMProperties(display, win, 0, 0, 0, 0, &size_hints, 0, 0); get_atoms(); - + set_title(title); #ifndef SINGLE_THREAD - clipboard = new BC_Clipboard(display_name); + clipboard = new BC_Clipboard(this); clipboard->start_clipboard(); #endif @@ -569,6 +546,7 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, PropModeReplace, (unsigned char *)&XGroupLeader, true); } init_im(); + set_icon(get_resources()->default_icon); } #ifdef HAVE_LIBXXF86VM @@ -659,7 +637,7 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, if(!hidden) show_window(); } get_resources()->create_window_lock->unlock(); - if(need_lock) unlock_window(); + unlock_window(); return 0; } @@ -684,6 +662,15 @@ Display* BC_WindowBase::init_display(const char *display_name) } } } + + static int xsynch = -1; + if( xsynch < 0 ) { + const char *cp = getenv("CIN_XSYNCH"); + xsynch = !cp ? 0 : atoi(cp); + } + if( xsynch > 0 ) + XSynchronize(display, True); + return display; } @@ -963,12 +950,15 @@ locking_message = event->xclient.message_type; // event_names[event->type] : "Unknown"); //} - if( active_grab && active_grab->grab_event(event) ) { + if( active_grab ) { unlock_window(); - return 0; + active_grab->lock_window("BC_WindowBase::dispatch_event 3"); + result = active_grab->grab_event(event); + active_grab->unlock_window(); + if( result ) return result; + lock_window("BC_WindowBase::dispatch_event 4"); } - switch(event->type) { case ClientMessage: // Clear the resize buffer @@ -1007,7 +997,7 @@ locking_message = event->xclient.message_type; done = 1; } else { // We currently use X marshalling for xatom events, we can switch to something else later - recieve_custom_xatoms((xatom_event *)ptr); + receive_custom_xatoms((xatom_event *)ptr); } break; @@ -1030,6 +1020,10 @@ locking_message = event->xclient.message_type; break; case ButtonPress: + if(motion_events) + { + dispatch_motion_event(); + } get_key_masks(event->xbutton.state); cursor_x = event->xbutton.x; cursor_y = event->xbutton.y; @@ -1074,6 +1068,10 @@ locking_message = event->xclient.message_type; break; case ButtonRelease: + if(motion_events) + { + dispatch_motion_event(); + } get_key_masks(event->xbutton.state); button_number = event->xbutton.button; event_win = event->xany.window; @@ -1257,6 +1255,20 @@ locking_message = event->xclient.message_type; case XK_KP_Insert: key_pressed = KPINS; break; case XK_KP_Decimal: case XK_KP_Delete: key_pressed = KPDEL; break; + + case XK_F1: key_pressed = KEY_F1; break; + case XK_F2: key_pressed = KEY_F2; break; + case XK_F3: key_pressed = KEY_F3; break; + case XK_F4: key_pressed = KEY_F4; break; + case XK_F5: key_pressed = KEY_F5; break; + case XK_F6: key_pressed = KEY_F6; break; + case XK_F7: key_pressed = KEY_F7; break; + case XK_F8: key_pressed = KEY_F8; break; + case XK_F9: key_pressed = KEY_F9; break; + case XK_F10: key_pressed = KEY_F10; break; + case XK_F11: key_pressed = KEY_F11; break; + case XK_F12: key_pressed = KEY_F12; break; + case XK_Menu: key_pressed = KPMENU; break; /* menu */ // remote control // above case XK_KP_Enter: key_pressed = KPENTER; break; /* check */ @@ -1326,16 +1338,33 @@ locking_message = event->xclient.message_type; break; case LeaveNotify: + if( event->xcrossing.mode != NotifyNormal ) break; + cursor_entered = 0; event_win = event->xany.window; dispatch_cursor_leave(); break; case EnterNotify: + if( event->xcrossing.mode != NotifyNormal ) break; + + if( !cursor_entered ) { + for( int i=0; iwin == event->xcrossing.window ) + cursor_entered = 1; + } + if( !cursor_entered && get_resources()->grab_input_focus && + !event->xcrossing.focus && event->xcrossing.window == win ) { + cursor_entered = 1; + } + if( cursor_entered ) + focus(); + } event_win = event->xany.window; cursor_x = event->xcrossing.x; cursor_y = event->xcrossing.y; dispatch_cursor_enter(); break; + default: break; } @@ -1344,7 +1373,14 @@ locking_message = event->xclient.message_type; #ifndef SINGLE_THREAD unlock_window(); - if(event) delete event; + if(event) { + if( resend_event_window ) { + resend_event_window->put_event(event); + resend_event_window = 0; + } + else + delete event; + } #else // if(done) completion_lock->unlock(); #endif @@ -1771,69 +1807,54 @@ int BC_WindowBase::dispatch_drag_motion() } - - - -int BC_WindowBase::show_tooltip(int w, int h) +int BC_WindowBase::show_tooltip(const char *text, int x, int y, int w, int h) { - Window tempwin; - - if(tooltip_text && !tooltip_on && - (force_tooltip || get_resources()->tooltips_enabled)) - { - int x, y; +// default text + int forced = !text ? force_tooltip : 1; + if( !text ) text = tooltip_text; + if( !text || (!forced && !get_resources()->tooltips_enabled) ) { top_level->hide_tooltip(); - + return 1; + } +// default w,h + if(w < 0) w = get_text_width(MEDIUMFONT, text) + TOOLTIP_MARGIN * 2; + if(h < 0) h = get_text_height(MEDIUMFONT, text) + TOOLTIP_MARGIN * 2; +// default x,y (win relative) + if( x < 0 ) x = get_w(); + if( y < 0 ) y = get_h(); + int wx, wy; + get_root_coordinates(x, y, &wx, &wy); +// keep the tip inside the window/display + int x0 = top_level->get_x(), x1 = x0 + top_level->get_w(); + int x2 = top_level->get_screen_x(0, -1) + top_level->get_screen_w(0, -1); + if( x1 > x2 ) x1 = x2; + if( wx < x0 ) wx = x0; + if( wx >= (x1-=w) ) wx = x1; + int y0 = top_level->get_y(), y1 = y0 + top_level->get_h(); + int y2 = top_level->get_root_h(0); + if( y1 > y2 ) y1 = y2; + if( wy < y0 ) wy = y0; + if( wy >= (y1-=h) ) wy = y1; +// avoid tip under cursor (flickers) + int abs_x, abs_y; + get_abs_cursor(abs_x,abs_y, 0); + if( wx < abs_x && abs_x < wx+w && wy < abs_y && abs_y < wy+h ) { + if( wx-abs_x < wy-abs_y ) + wx = abs_x+1; + else + wy = abs_y+1; + } + if( !tooltip_on ) { tooltip_on = 1; - if(w < 0) - w = get_text_width(MEDIUMFONT, tooltip_text); - - if(h < 0) - h = get_text_height(MEDIUMFONT, tooltip_text); - - w += TOOLTIP_MARGIN * 2; - h += TOOLTIP_MARGIN * 2; - - XTranslateCoordinates(top_level->display, win, - top_level->rootwin, get_w(), get_h(), - &x, &y, &tempwin); - // keep the tip inside the window/display - int top_x = top_level->get_x(); - if( x < top_x ) x = top_x; - int top_w = top_x + top_level->get_w(); - int lmt_w = top_level->get_screen_x(0, -1) + top_level->get_screen_w(0, -1); - if( top_w < lmt_w ) lmt_w = top_w; - if( x+w > lmt_w ) x = lmt_w-w; - if( x < 0 ) x = 0; - int top_y = top_level->get_y(); - if( y < top_y ) y = top_y; - int top_h = top_y + top_level->get_h(); - int lmt_h = top_level->get_root_h(0); - if( top_h < lmt_h ) lmt_h = top_h; - if( y+h > lmt_h ) y = lmt_h-h; - if( y < 0 ) y = 0; - int abs_x, abs_y, win_x, win_y; - unsigned int temp_mask; - Window temp_win; - XQueryPointer(top_level->display, top_level->win, - &temp_win, &temp_win, &abs_x, &abs_y, - &win_x, &win_y, &temp_mask); - // check for cursor inside popup - if( x < abs_x && abs_x < x+w && y < abs_y && abs_y < y+h ) - { - if( x-abs_x < y-abs_y ) - x = abs_x+1; - else - y = abs_y+1; - } - tooltip_popup = new BC_Popup(top_level, x, y, w, h, - get_resources()->tooltip_bg_color); - - draw_tooltip(); - tooltip_popup->set_font(MEDIUMFONT); - tooltip_popup->flash(); - tooltip_popup->flush(); + tooltip_popup = new BC_Popup(top_level, wx, wy, w, h, + get_resources()->tooltip_bg_color); } + else + tooltip_popup->reposition_window(wx, wy, w, h); + + draw_tooltip(text); + tooltip_popup->flash(); + tooltip_popup->flush(); return 0; } @@ -1871,11 +1892,6 @@ int BC_WindowBase::set_tooltip(const char *text) } return 0; } -void BC_WindowBase::set_tooltip_done(int v) -{ - tooltip_done = v; -} - // signal the event handler to repeat int BC_WindowBase::set_repeat(int64_t duration) { @@ -1969,7 +1985,7 @@ int BC_WindowBase::arm_repeat(int64_t duration) } #endif -int BC_WindowBase::recieve_custom_xatoms(xatom_event *event) +int BC_WindowBase::receive_custom_xatoms(xatom_event *event) { return 0; } @@ -2030,7 +2046,7 @@ void BC_WindowBase::init_cursors() downleft_resize_cursor = XCreateFontCursor(display, XC_bottom_left_corner); downright_resize_cursor = XCreateFontCursor(display, XC_bottom_right_corner); hourglass_cursor = XCreateFontCursor(display, XC_watch); - + grabbed_cursor = create_grab_cursor(); static char cursor_data[] = { 0,0,0,0, 0,0,0,0 }; Colormap colormap = DefaultColormap(display, screen); @@ -2042,49 +2058,6 @@ void BC_WindowBase::init_cursors() pixmap_bottom, pixmap_bottom, &black, &black, 0, 0); // XDefineCursor(display, win, transparent_cursor); XFreePixmap(display, pixmap_bottom); - - int iw = 23, iw1 = iw-1, iw2 = iw/2; - int ih = 23, ih1 = ih-1, ih2 = ih/2; - VFrame grab(iw,ih,BC_RGB888); - grab.clear_frame(); - grab.set_pixel_color(RED); // fg - grab.draw_smooth(iw2,0, iw1,0, iw1,ih2); - grab.draw_smooth(iw1,ih2, iw1,ih1, iw2,ih1); - grab.draw_smooth(iw2,ih1, 0,ih1, 0,ih2); - grab.draw_smooth(0,ih2, 0,0, iw2,0); - grab.set_pixel_color(WHITE); // bg - grab.draw_line(0,ih2, iw2-2,ih2); - grab.draw_line(iw2+2,ih2, iw1,ih2); - grab.draw_line(iw2,0, iw2,ih2-2); - grab.draw_line(iw2,ih2+2, iw2,ih1); - - int bpl = (iw+7)/8, isz = bpl * ih; - char img[isz]; memset(img, 0, isz); - char msk[isz]; memset(msk, 0, isz); - unsigned char **rows = grab.get_rows(); - for( int iy=0; iy>3] |= (1<<(ix&7)); - if( !ip[1] ) op[ix>>3] |= (1<<(ix&7)); - } - } - unsigned long white_pix = WhitePixel(display, screen); - unsigned long black_pix = BlackPixel(display, screen); - Pixmap img_xpm = XCreatePixmapFromBitmapData(display, rootwin, - img, iw,ih, white_pix,black_pix, 1); - Pixmap msk_xpm = XCreatePixmapFromBitmapData(display, rootwin, - msk, iw,ih, white_pix,black_pix, 1); - - XColor fc, bc; - fc.flags = bc.flags = DoRed | DoGreen | DoBlue; - fc.red = 0xffff; fc.green = fc.blue = 0; // fg - bc.red = bc.green = bc.blue = 0x0000; // bg - grabbed_cursor = XCreatePixmapCursor(display, img_xpm,msk_xpm, &fc,&bc, iw2,ih2); - XFreePixmap(display, img_xpm); - XFreePixmap(display, msk_xpm); } int BC_WindowBase::evaluate_color_model(int client_byte_order, int server_byte_order, int depth) @@ -2236,6 +2209,53 @@ int BC_WindowBase::create_shared_colors() return 0; } +Cursor BC_WindowBase::create_grab_cursor() +{ + int iw = 23, iw1 = iw-1, iw2 = iw/2; + int ih = 23, ih1 = ih-1, ih2 = ih/2; + VFrame grab(iw,ih,BC_RGB888); + grab.clear_frame(); + grab.set_pixel_color(RED); // fg + grab.draw_smooth(iw2,0, iw1,0, iw1,ih2); + grab.draw_smooth(iw1,ih2, iw1,ih1, iw2,ih1); + grab.draw_smooth(iw2,ih1, 0,ih1, 0,ih2); + grab.draw_smooth(0,ih2, 0,0, iw2,0); + grab.set_pixel_color(WHITE); // bg + grab.draw_line(0,ih2, iw2-2,ih2); + grab.draw_line(iw2+2,ih2, iw1,ih2); + grab.draw_line(iw2,0, iw2,ih2-2); + grab.draw_line(iw2,ih2+2, iw2,ih1); + + int bpl = (iw+7)/8, isz = bpl * ih; + char img[isz]; memset(img, 0, isz); + char msk[isz]; memset(msk, 0, isz); + unsigned char **rows = grab.get_rows(); + for( int iy=0; iy>3] |= (1<<(ix&7)); + if( !ip[1] ) op[ix>>3] |= (1<<(ix&7)); + } + } + unsigned long white_pix = WhitePixel(display, screen); + unsigned long black_pix = BlackPixel(display, screen); + Pixmap img_xpm = XCreatePixmapFromBitmapData(display, rootwin, + img, iw,ih, white_pix,black_pix, 1); + Pixmap msk_xpm = XCreatePixmapFromBitmapData(display, rootwin, + msk, iw,ih, white_pix,black_pix, 1); + + XColor fc, bc; + fc.flags = bc.flags = DoRed | DoGreen | DoBlue; + fc.red = 0xffff; fc.green = fc.blue = 0; // fg + bc.red = bc.green = bc.blue = 0x0000; // bg + Cursor cursor = XCreatePixmapCursor(display, img_xpm,msk_xpm, &fc,&bc, iw2,ih2); + XFreePixmap(display, img_xpm); + XFreePixmap(display, msk_xpm); + return cursor; +} + int BC_WindowBase::allocate_color_table() { int red, green, blue, color; @@ -2304,6 +2324,10 @@ int BC_WindowBase::init_fonts() if( !(bigfont = XLoadQueryFont(display, _(resources.big_font2))) ) bigfont = XLoadQueryFont(display, "fixed"); + if((clockfont = XLoadQueryFont(display, _(resources.clock_font))) == NULL) + if((clockfont = XLoadQueryFont(display, _(resources.clock_font2))) == NULL) + clockfont = XLoadQueryFont(display, "fixed"); + init_xft(); if(get_resources()->use_fontset) { @@ -2322,8 +2346,11 @@ int BC_WindowBase::init_fonts() largefontset = XCreateFontSet(display, "fixed,*", &m, &n, &d); bigfontset = XCreateFontSet(display, resources.big_fontset, &m, &n, &d); if( !bigfontset ) - largefontset = XCreateFontSet(display, "fixed,*", &m, &n, &d); - if(bigfontset && largefontset && mediumfontset && smallfontset) { + bigfontset = XCreateFontSet(display, "fixed,*", &m, &n, &d); + clockfontset = XCreateFontSet(display, resources.clock_fontset, &m, &n, &d); + if( !clockfontset ) + clockfontset = XCreateFontSet(display, "fixed,*", &m, &n, &d); + if(clockfontset && bigfontset && largefontset && mediumfontset && smallfontset) { curr_fontset = mediumfontset; get_resources()->use_fontset = 1; } @@ -2340,66 +2367,79 @@ void BC_WindowBase::init_xft() { #ifdef HAVE_XFT if( !get_resources()->use_xft ) return; +// apparently, xft is not reentrant, more than this is needed +static Mutex xft_init_lock("BC_WindowBase::xft_init_lock", 0); +xft_init_lock.lock("BC_WindowBase::init_xft"); if(!(smallfont_xft = (resources.small_font_xft[0] == '-' ? - XftFontOpenXlfd(display, screen, resources.small_font_xft) : - XftFontOpenName(display, screen, resources.small_font_xft))) ) + xftFontOpenXlfd(display, screen, resources.small_font_xft) : + xftFontOpenName(display, screen, resources.small_font_xft))) ) if(!(smallfont_xft = - XftFontOpenXlfd(display, screen, resources.small_font_xft2))) - smallfont_xft = XftFontOpenXlfd(display, screen, "fixed"); + xftFontOpenXlfd(display, screen, resources.small_font_xft2))) + smallfont_xft = xftFontOpenXlfd(display, screen, "fixed"); if(!(mediumfont_xft = (resources.medium_font_xft[0] == '-' ? - XftFontOpenXlfd(display, screen, resources.medium_font_xft) : - XftFontOpenName(display, screen, resources.medium_font_xft))) ) + xftFontOpenXlfd(display, screen, resources.medium_font_xft) : + xftFontOpenName(display, screen, resources.medium_font_xft))) ) if(!(mediumfont_xft = - XftFontOpenXlfd(display, screen, resources.medium_font_xft2))) - mediumfont_xft = XftFontOpenXlfd(display, screen, "fixed"); + xftFontOpenXlfd(display, screen, resources.medium_font_xft2))) + mediumfont_xft = xftFontOpenXlfd(display, screen, "fixed"); if(!(largefont_xft = (resources.large_font_xft[0] == '-' ? - XftFontOpenXlfd(display, screen, resources.large_font_xft) : - XftFontOpenName(display, screen, resources.large_font_xft))) ) + xftFontOpenXlfd(display, screen, resources.large_font_xft) : + xftFontOpenName(display, screen, resources.large_font_xft))) ) if(!(largefont_xft = - XftFontOpenXlfd(display, screen, resources.large_font_xft2))) - largefont_xft = XftFontOpenXlfd(display, screen, "fixed"); + xftFontOpenXlfd(display, screen, resources.large_font_xft2))) + largefont_xft = xftFontOpenXlfd(display, screen, "fixed"); if(!(bigfont_xft = (resources.big_font_xft[0] == '-' ? - XftFontOpenXlfd(display, screen, resources.big_font_xft) : - XftFontOpenName(display, screen, resources.big_font_xft))) ) + xftFontOpenXlfd(display, screen, resources.big_font_xft) : + xftFontOpenName(display, screen, resources.big_font_xft))) ) if(!(bigfont_xft = - XftFontOpenXlfd(display, screen, resources.big_font_xft2))) - bigfont_xft = XftFontOpenXlfd(display, screen, "fixed"); + xftFontOpenXlfd(display, screen, resources.big_font_xft2))) + bigfont_xft = xftFontOpenXlfd(display, screen, "fixed"); + if(!(clockfont_xft = + (resources.clock_font_xft[0] == '-' ? + xftFontOpenXlfd(display, screen, resources.clock_font_xft) : + xftFontOpenName(display, screen, resources.clock_font_xft))) ) + clockfont_xft = xftFontOpenXlfd(display, screen, "fixed"); + if(!(bold_smallfont_xft = (resources.small_b_font_xft[0] == '-' ? - XftFontOpenXlfd(display, screen, resources.small_b_font_xft) : - XftFontOpenName(display, screen, resources.small_b_font_xft))) ) - bold_smallfont_xft = XftFontOpenXlfd(display, screen, "fixed"); + xftFontOpenXlfd(display, screen, resources.small_b_font_xft) : + xftFontOpenName(display, screen, resources.small_b_font_xft))) ) + bold_smallfont_xft = xftFontOpenXlfd(display, screen, "fixed"); if(!(bold_mediumfont_xft = (resources.medium_b_font_xft[0] == '-' ? - XftFontOpenXlfd(display, screen, resources.medium_b_font_xft) : - XftFontOpenName(display, screen, resources.medium_b_font_xft))) ) - bold_mediumfont_xft = XftFontOpenXlfd(display, screen, "fixed"); + xftFontOpenXlfd(display, screen, resources.medium_b_font_xft) : + xftFontOpenName(display, screen, resources.medium_b_font_xft))) ) + bold_mediumfont_xft = xftFontOpenXlfd(display, screen, "fixed"); if(!(bold_largefont_xft = (resources.large_b_font_xft[0] == '-' ? - XftFontOpenXlfd(display, screen, resources.large_b_font_xft) : - XftFontOpenName(display, screen, resources.large_b_font_xft))) ) - bold_largefont_xft = XftFontOpenXlfd(display, screen, "fixed"); + xftFontOpenXlfd(display, screen, resources.large_b_font_xft) : + xftFontOpenName(display, screen, resources.large_b_font_xft))) ) + bold_largefont_xft = xftFontOpenXlfd(display, screen, "fixed"); -// Extension failed to locate fonts if( !smallfont_xft || !mediumfont_xft || !largefont_xft || !bigfont_xft || - !bold_largefont_xft || !bold_mediumfont_xft || !bold_largefont_xft ) { + !bold_largefont_xft || !bold_mediumfont_xft || !bold_largefont_xft || + !clockfont_xft ) { printf("BC_WindowBase::init_fonts: no xft fonts found:" - " %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n", + " %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n %s=%p\n", resources.small_font_xft, smallfont_xft, resources.medium_font_xft, mediumfont_xft, resources.large_font_xft, largefont_xft, resources.big_font_xft, bigfont_xft, + resources.clock_font_xft, clockfont_xft, resources.small_b_font_xft, bold_smallfont_xft, resources.medium_b_font_xft, bold_mediumfont_xft, resources.large_b_font_xft, bold_largefont_xft); get_resources()->use_xft = 0; exit(1); } +// _XftDisplayInfo needs a lock. + xftDefaultHasRender(display); +xft_init_lock.unlock(); #endif // HAVE_XFT } @@ -2631,21 +2671,22 @@ Cursor BC_WindowBase::get_cursor_struct(int cursor) { switch(cursor) { - case ARROW_CURSOR: return top_level->arrow_cursor; break; + case ARROW_CURSOR: return top_level->arrow_cursor; case CROSS_CURSOR: return top_level->cross_cursor; - case IBEAM_CURSOR: return top_level->ibeam_cursor; break; - case VSEPARATE_CURSOR: return top_level->vseparate_cursor; break; - case HSEPARATE_CURSOR: return top_level->hseparate_cursor; break; - case MOVE_CURSOR: return top_level->move_cursor; break; - case LEFT_CURSOR: return top_level->left_cursor; break; - case RIGHT_CURSOR: return top_level->right_cursor; break; - case UPRIGHT_ARROW_CURSOR: return top_level->upright_arrow_cursor; break; - case UPLEFT_RESIZE: return top_level->upleft_resize_cursor; break; - case UPRIGHT_RESIZE: return top_level->upright_resize_cursor; break; - case DOWNLEFT_RESIZE: return top_level->downleft_resize_cursor; break; - case DOWNRIGHT_RESIZE: return top_level->downright_resize_cursor; break; - case HOURGLASS_CURSOR: return top_level->hourglass_cursor; break; - case TRANSPARENT_CURSOR: return top_level->transparent_cursor; break; + case IBEAM_CURSOR: return top_level->ibeam_cursor; + case VSEPARATE_CURSOR: return top_level->vseparate_cursor; + case HSEPARATE_CURSOR: return top_level->hseparate_cursor; + case MOVE_CURSOR: return top_level->move_cursor; + case LEFT_CURSOR: return top_level->left_cursor; + case RIGHT_CURSOR: return top_level->right_cursor; + case UPRIGHT_ARROW_CURSOR: return top_level->upright_arrow_cursor; + case UPLEFT_RESIZE: return top_level->upleft_resize_cursor; + case UPRIGHT_RESIZE: return top_level->upright_resize_cursor; + case DOWNLEFT_RESIZE: return top_level->downleft_resize_cursor; + case DOWNRIGHT_RESIZE: return top_level->downright_resize_cursor; + case HOURGLASS_CURSOR: return top_level->hourglass_cursor; + case TRANSPARENT_CURSOR: return top_level->transparent_cursor; + case GRABBED_CURSOR: return top_level->grabbed_cursor; } return 0; } @@ -2749,6 +2790,7 @@ XFontStruct* BC_WindowBase::get_font_struct(int font) case MEDIUMFONT: return top_level->mediumfont; break; case LARGEFONT: return top_level->largefont; break; case BIGFONT: return top_level->bigfont; break; + case CLOCKFONT: return top_level->clockfont; break; } return 0; } @@ -2764,6 +2806,7 @@ XFontSet BC_WindowBase::get_fontset(int font) case MEDIUMFONT: fs = top_level->mediumfontset; break; case LARGEFONT: fs = top_level->largefontset; break; case BIGFONT: fs = top_level->bigfontset; break; + case CLOCKFONT: fs = top_level->clockfontset; break; } } @@ -2778,6 +2821,7 @@ XftFont* BC_WindowBase::get_xft_struct(int font) case MEDIUMFONT: return (XftFont*)top_level->mediumfont_xft; case LARGEFONT: return (XftFont*)top_level->largefont_xft; case BIGFONT: return (XftFont*)top_level->bigfont_xft; + case CLOCKFONT: return (XftFont*)top_level->clockfont_xft; case MEDIUMFONT_3D: return (XftFont*)top_level->bold_mediumfont_xft; case SMALLFONT_3D: return (XftFont*)top_level->bold_smallfont_xft; case LARGEFONT_3D: return (XftFont*)top_level->bold_largefont_xft; @@ -2788,13 +2832,6 @@ XftFont* BC_WindowBase::get_xft_struct(int font) #endif - - - - - - - int BC_WindowBase::get_current_font() { return top_level->current_font; @@ -2830,6 +2867,7 @@ void BC_WindowBase::set_fontset(int font) case MEDIUMFONT: fs = top_level->mediumfontset; break; case LARGEFONT: fs = top_level->largefontset; break; case BIGFONT: fs = top_level->bigfontset; break; + case CLOCKFONT: fs = top_level->clockfontset; break; } } @@ -2853,7 +2891,7 @@ int BC_WindowBase::get_single_text_width(int font, const char *text, int length) #ifdef X_HAVE_UTF8_STRING if(get_resources()->locale_utf8) { - XftTextExtentsUtf8(top_level->display, + xftTextExtentsUtf8(top_level->display, get_xft_struct(font), (const XftChar8 *)text, length, @@ -2862,7 +2900,7 @@ int BC_WindowBase::get_single_text_width(int font, const char *text, int length) else #endif { - XftTextExtents8(top_level->display, + xftTextExtents8(top_level->display, get_xft_struct(font), (const XftChar8 *)text, length, @@ -2893,26 +2931,6 @@ int BC_WindowBase::get_single_text_width(int font, const char *text, int length) } } -int BC_WindowBase::get_single_text_width(int font, const wchar_t *text, int length) -{ -#ifdef HAVE_XFT - if(get_resources()->use_xft && get_xft_struct(font)) { - XGlyphInfo extents; - - XftTextExtents32(top_level->display, get_xft_struct(font), - (const FcChar32*)text, length, &extents); - return extents.xOff; - } -#endif - if(!get_font_struct(font)) return 0; - XChar2b xtext[length], *xp = xtext; - for( int i=0; ibyte1 = (unsigned char) (text[i] >> 8); - xp->byte2 = (unsigned char) (text[i] & 0xff); - } - return XTextWidth16(get_font_struct(font), xtext, length); -} - int BC_WindowBase::get_text_width(int font, const char *text, int length) { int i, j, w = 0, line_w = 0; @@ -3372,12 +3390,20 @@ int BC_WindowBase::ungrab(BC_WindowBase *window) this->grab_active = 0; return 1; } +int BC_WindowBase::grab_event_count() +{ + int result = 0; +#ifndef SINGLE_THREAD + result = grab_active->get_event_count(); +#endif + return result; +} int BC_WindowBase::grab_buttons() { XSync(top_level->display, False); if( XGrabButton(top_level->display, AnyButton, AnyModifier, top_level->rootwin, True, ButtonPressMask | ButtonReleaseMask, - GrabModeAsync, GrabModeSync, None, grabbed_cursor) == GrabSuccess ) { + GrabModeAsync, GrabModeSync, None, None) == GrabSuccess ) { set_active_subwindow(this); return 0; } @@ -3391,31 +3417,14 @@ void BC_WindowBase::ungrab_buttons() } void BC_WindowBase::grab_cursor() { - XDefineCursor(top_level->display, top_level->rootwin, grabbed_cursor); + Cursor cursor_grab = get_cursor_struct(GRABBED_CURSOR); + XGrabPointer(top_level->display, top_level->rootwin, True, + PointerMotionMask | ButtonPressMask | ButtonReleaseMask, + GrabModeAsync, GrabModeAsync, None, cursor_grab, CurrentTime); } void BC_WindowBase::ungrab_cursor() { - XUndefineCursor(top_level->display, top_level->rootwin); -} - -int BC_WindowBase::get_w() -{ - return w; -} - -int BC_WindowBase::get_h() -{ - return h; -} - -int BC_WindowBase::get_x() -{ - return x; -} - -int BC_WindowBase::get_y() -{ - return y; + XUngrabPointer(top_level->display, CurrentTime); } // for get_root_w/h @@ -3451,6 +3460,8 @@ BC_WindowBase::get_xinerama_info(int screen) return 0; } int top_x = get_x(), top_y = get_y(); + if( BC_DisplayInfo::left_border >= 0 ) top_x += BC_DisplayInfo::left_border; + if( BC_DisplayInfo::top_border >= 0 ) top_y += BC_DisplayInfo::top_border; for( int i=0; i= xinerama_info[i].height ) continue; @@ -3461,6 +3472,38 @@ BC_WindowBase::get_xinerama_info(int screen) return 0; } +void BC_WindowBase::get_fullscreen_geometry(int &wx, int &wy, int &ww, int &wh) +{ + XineramaScreenInfo *info = top_level->get_xinerama_info(-1); + if( info ) { + wx = info->x_org; wy = info->y_org; + ww = info->width; wh = info->height; + } + else { + wx = get_screen_x(0, -1); + wy = get_screen_y(0, -1); + int scr_w0 = get_screen_w(0, 0); + int root_w = get_root_w(0); + int root_h = get_root_h(0); + if( root_w > scr_w0 ) { // multi-headed + if( wx >= scr_w0 ) { + // assumes right side is the big one + ww = root_w - scr_w0; + wh = root_h; + } + else { + // use same aspect ratio to compute left height + ww = scr_w0; + wh = (w*root_h) / (root_w-scr_w0); + } + } + else { + ww = root_w; + wh = root_h; + } + } +} + int BC_WindowBase::get_screen_x(int lock_display, int screen) { int result = -1; @@ -3736,13 +3779,45 @@ BC_Clipboard* BC_WindowBase::get_clipboard() #endif } -void BC_WindowBase::get_relative_cursor_xy(int &x, int &y, int lock_window) +Atom BC_WindowBase::to_clipboard(const char *data, long len, int clipboard_num) +{ + return get_clipboard()->to_clipboard(this, data, len, clipboard_num); +} + +long BC_WindowBase::from_clipboard(char *data, long maxlen, int clipboard_num) +{ + return get_clipboard()->from_clipboard(data, maxlen, clipboard_num); +} + +long BC_WindowBase::clipboard_len(int clipboard_num) +{ + return get_clipboard()->clipboard_len(clipboard_num); +} + +int BC_WindowBase::do_selection_clear(Window win) +{ + top_level->event_win = win; + return dispatch_selection_clear(); +} + +int BC_WindowBase::dispatch_selection_clear() +{ + int result = 0; + for( int i=0; itotal && !result; ++i ) + result = subwindows->values[i]->dispatch_selection_clear(); + if( !result ) + result = selection_clear_event(); + return result; +} + + +void BC_WindowBase::get_relative_cursor(int &x, int &y, int lock_window) { int abs_x, abs_y, win_x, win_y; unsigned int temp_mask; Window temp_win; - if(lock_window) this->lock_window("BC_WindowBase::get_relative_cursor_xy"); + if(lock_window) this->lock_window("BC_WindowBase::get_relative_cursor"); XQueryPointer(top_level->display, top_level->win, &temp_win, &temp_win, &abs_x, &abs_y, &win_x, &win_y, &temp_mask); @@ -3754,23 +3829,23 @@ void BC_WindowBase::get_relative_cursor_xy(int &x, int &y, int lock_window) int BC_WindowBase::get_relative_cursor_x(int lock_window) { int x, y; - get_relative_cursor_xy(x, y, lock_window); + get_relative_cursor(x, y, lock_window); return x; } int BC_WindowBase::get_relative_cursor_y(int lock_window) { int x, y; - get_relative_cursor_xy(x, y, lock_window); + get_relative_cursor(x, y, lock_window); return y; } -void BC_WindowBase::get_abs_cursor_xy(int &abs_x, int &abs_y, int lock_window) +void BC_WindowBase::get_abs_cursor(int &abs_x, int &abs_y, int lock_window) { int win_x, win_y; unsigned int temp_mask; Window temp_win; - if(lock_window) this->lock_window("BC_WindowBase::get_abs_cursor_xy"); + if(lock_window) this->lock_window("BC_WindowBase::get_abs_cursor"); XQueryPointer(top_level->display, top_level->win, &temp_win, &temp_win, &abs_x, &abs_y, &win_x, &win_y, &temp_mask); @@ -3779,20 +3854,20 @@ void BC_WindowBase::get_abs_cursor_xy(int &abs_x, int &abs_y, int lock_window) int BC_WindowBase::get_abs_cursor_x(int lock_window) { int abs_x, abs_y; - get_abs_cursor_xy(abs_x, abs_y, lock_window); + get_abs_cursor(abs_x, abs_y, lock_window); return abs_x; } int BC_WindowBase::get_abs_cursor_y(int lock_window) { int abs_x, abs_y; - get_abs_cursor_xy(abs_x, abs_y, lock_window); + get_abs_cursor(abs_x, abs_y, lock_window); return abs_y; } -void BC_WindowBase::get_pop_cursor_xy(int &px, int &py, int lock_window) +void BC_WindowBase::get_pop_cursor(int &px, int &py, int lock_window) { int margin = 100; - get_abs_cursor_xy(px, py, lock_window); + get_abs_cursor(px, py, lock_window); if( px < margin ) px = margin; if( py < margin ) py = margin; int wd = get_screen_w(lock_window,-1) - margin; @@ -3803,13 +3878,13 @@ void BC_WindowBase::get_pop_cursor_xy(int &px, int &py, int lock_window) int BC_WindowBase::get_pop_cursor_x(int lock_window) { int px, py; - get_pop_cursor_xy(px, py, lock_window); + get_pop_cursor(px, py, lock_window); return px; } int BC_WindowBase::get_pop_cursor_y(int lock_window) { int px, py; - get_pop_cursor_xy(px, py, lock_window); + get_pop_cursor(px, py, lock_window); return py; } @@ -3827,27 +3902,34 @@ int BC_WindowBase::match_window(Window win) int BC_WindowBase::get_cursor_over_window() { - if(top_level != this) return top_level->get_cursor_over_window(); - int abs_x, abs_y, win_x, win_y; - unsigned int temp_mask; + unsigned int mask_return; Window root_return, child_return; - int ret = XQueryPointer(display, win, + int ret = XQueryPointer(top_level->display, top_level->rootwin, &root_return, &child_return, &abs_x, &abs_y, - &win_x, &win_y, &temp_mask); -//printf("BC_WindowBase::get_cursor_over_window %d %s 0x%x %d 0x%x\n", -// __LINE__, title, win, ret, child_return); - - int result = !ret || child_return == None ? 0 : - match_window(child_return); - return result; + &win_x, &win_y, &mask_return); + if( ret && child_return == None ) ret = 0; + if( ret && win != child_return ) + ret = top_level->match_window(child_return); +// query pointer can return a window manager window with this top_level as a child +// for kde this can be two levels deep + unsigned int nchildren_return = 0; + Window parent_return, *children_return = 0; + Window top_win = top_level->win; + while( !ret && top_win != top_level->rootwin && top_win != root_return && + XQueryTree(top_level->display, top_win, &root_return, + &parent_return, &children_return, &nchildren_return) ) { + if( children_return ) XFree(children_return); + if( (top_win=parent_return) == child_return ) ret = 1; + } + return ret; } int BC_WindowBase::cursor_above() { int rx, ry; - get_relative_cursor_xy(rx, ry); + get_relative_cursor(rx, ry); return rx < 0 || rx >= get_w() || ry < 0 || ry >= get_h() ? 0 : 1; } @@ -4131,39 +4213,30 @@ void BC_WindowBase::put_title(const char *text) *cp = 0; } -void BC_WindowBase::set_title(const char *text) -{ - put_title(_(text)); - - char *txlist[2]; - txlist[0] = this->title; - txlist[1] = 0; - - XTextProperty titleprop; - XmbTextListToTextProperty(top_level->display, txlist, 1, - XStdICCTextStyle, &titleprop); - XSetWMName(top_level->display, top_level->win, &titleprop); - XSetWMIconName(top_level->display, top_level->win, &titleprop); - XFree(titleprop.value); - - flush(); -} - -void BC_WindowBase::set_utf8title(const char *text) -{ - XTextProperty titleprop; - char *txlist[2]; - - strcpy(this->title, text); - txlist[0] = this->title; - txlist[1] = 0; - - Xutf8TextListToTextProperty(top_level->display, txlist, 1, - XUTF8StringStyle, &titleprop); - XSetWMName(top_level->display, top_level->win, &titleprop); - XSetWMIconName(top_level->display, top_level->win, &titleprop); - XFree(titleprop.value); - +void BC_WindowBase::set_title(const char *text, int utf8) +{ +// utf8>0: wm + net_wm, utf8=0: wm only, utf<0: net_wm only + put_title(text); + const unsigned char *wm_title = (const unsigned char *)title; + int title_len = strlen((const char *)title); + if( utf8 >= 0 ) { + Atom xa_wm_name = XA_WM_NAME; + Atom xa_icon_name = XA_WM_ICON_NAME; + Atom xa_string = XA_STRING; + XChangeProperty(display, win, xa_wm_name, xa_string, 8, + PropModeReplace, wm_title, title_len); + XChangeProperty(display, win, xa_icon_name, xa_string, 8, + PropModeReplace, wm_title, title_len); + } + if( utf8 != 0 ) { + Atom xa_net_wm_name = XInternAtom(display, "_NET_WM_NAME", True); + Atom xa_net_icon_name = XInternAtom(display, "_NET_WM_ICON_NAME", True); + Atom xa_utf8_string = XInternAtom(display, "UTF8_STRING", True); + XChangeProperty(display, win, xa_net_wm_name, xa_utf8_string, 8, + PropModeReplace, wm_title, title_len); + XChangeProperty(display, win, xa_net_icon_name, xa_utf8_string, 8, + PropModeReplace, wm_title, title_len); + } flush(); } @@ -4253,6 +4326,7 @@ int BC_WindowBase::load_defaults(BC_Hash *defaults) resources->filebox_columnwidth[1] = defaults->get("FILEBOX_WIDTH1", resources->filebox_columnwidth[1]); resources->filebox_columnwidth[2] = defaults->get("FILEBOX_WIDTH2", resources->filebox_columnwidth[2]); resources->filebox_columnwidth[3] = defaults->get("FILEBOX_WIDTH3", resources->filebox_columnwidth[3]); + resources->filebox_size_format = defaults->get("FILEBOX_SIZE_FORMAT", get_resources()->filebox_size_format); defaults->get("FILEBOX_FILTER", resources->filebox_filter); return 0; } @@ -4280,6 +4354,7 @@ int BC_WindowBase::save_defaults(BC_Hash *defaults) defaults->update("FILEBOX_WIDTH2", resources->filebox_columnwidth[2]); defaults->update("FILEBOX_WIDTH3", resources->filebox_columnwidth[3]); defaults->update("FILEBOX_FILTER", resources->filebox_filter); + defaults->update("FILEBOX_SIZE_FORMAT", get_resources()->filebox_size_format); return 0; } @@ -4459,6 +4534,20 @@ void BC_WindowBase::dequeue_events(Window win) event_lock->unlock(); } +int BC_WindowBase::resend_event(BC_WindowBase *window) +{ + if( resend_event_window ) return 1; + resend_event_window = window; + return 0; +} + +#else + +int BC_WindowBase::resend_event(BC_WindowBase *window) +{ + return 1; +} + #endif // SINGLE_THREAD int BC_WindowBase::get_id() @@ -4488,3 +4577,11 @@ void BC_WindowBase::flicker(int n, int ms) set_opaque(); } +void BC_WindowBase::focus() +{ + XWindowAttributes xwa; + XGetWindowAttributes(top_level->display, top_level->win, &xwa); + if( xwa.map_state == IsViewable ) + XSetInputFocus(top_level->display, top_level->win, RevertToParent, CurrentTime); +} +