X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fguicast%2Fbcwindowbase.C;h=adaaa6e266f779464b5d12099179a8aad94c9f6c;hp=9f3e2123c843c7e0f336ae1d4c53105b03b04a71;hb=HEAD;hpb=b89feee3b26be17a08bf1598618d4d7709a73cb9 diff --git a/cinelerra-5.1/guicast/bcwindowbase.C b/cinelerra-5.1/guicast/bcwindowbase.C index 9f3e2123..adaaa6e2 100644 --- a/cinelerra-5.1/guicast/bcwindowbase.C +++ b/cinelerra-5.1/guicast/bcwindowbase.C @@ -254,6 +254,7 @@ int BC_WindowBase::initialize() display_lock_owner = 0; test_keypress = 0; keys_return[0] = 0; + context_help_keyword[0] = 0; is_deleting = 0; window_lock = 0; resend_event_window = 0; @@ -1172,6 +1173,24 @@ if( debug && event->type != ClientMessage ) { //__LINE__, //keysym); +// force setting modifiers state if a modifier key pressed + switch( keysym ) { + case XK_Alt_L: + case XK_Alt_R: + alt_mask = 1; + break; + case XK_Shift_L: + case XK_Shift_R: + shift_mask = 1; + break; + case XK_Control_L: + case XK_Control_R: + ctrl_mask = 1; + break; + default: + break; + } + // block out control keys if(keysym > 0xffe0 && keysym < 0xffff) break; // block out Alt_GR key @@ -1308,8 +1327,26 @@ if( debug && event->type != ClientMessage ) { case KeyRelease: XLookupString((XKeyEvent*)event, keys_return, 1, &keysym, 0); + get_key_masks(event->xkey.state); +// force clearing modifiers state if a modifier key released + switch( keysym ) { + case XK_Alt_L: + case XK_Alt_R: + alt_mask = 0; + break; + case XK_Shift_L: + case XK_Shift_R: + shift_mask = 0; + break; + case XK_Control_L: + case XK_Control_R: + ctrl_mask = 0; + break; + default: + break; + } dispatch_keyrelease_event(); -// printf("BC_WindowBase::dispatch_event KeyRelease keysym=0x%x keystate=0x%lld\n", +// printf("BC_WindowBase::dispatch_event KeyRelease keysym=%#lx keystate=%04x\n", // keysym, event->xkey.state); break; @@ -1730,6 +1767,90 @@ int BC_WindowBase::close_event() return 1; } +// *** CONTEXT_HELP *** +// This basic implementation serves solely for context help. +// We are handling Alt/H only. Any subclass requiring more sophisticated +// processing of keystrokes has to provide its own overloaded handler. +int BC_WindowBase::keypress_event() +{ +// printf("BC_WindowBase::keypress_event: %d\n", get_keypress()); + return context_help_check_and_show(); +} + +// The stuff up to END_CONTEXT_HELP serves solely for context help +void BC_WindowBase::context_help_set_keyword(const char *keyword) +{ + if (keyword) strcpy(context_help_keyword, keyword); +} + +const char *BC_WindowBase::context_help_get_keyword() +{ +// If we have context_help_keyword defined here, return it. +// Otherwise recursively track widget hierarchy up to top_level +// and return the nearest found nonempty keyword. +// If nothing found, the special keyword "TOC" is returned. + if (context_help_keyword[0] || this == top_level || + this == parent_window || ! parent_window) { + if (! context_help_keyword[0] && this == top_level) + context_help_set_keyword("TOC"); + return context_help_keyword; + } + return parent_window->context_help_get_keyword(); +} + +void BC_WindowBase::context_help_show(const char *keyword) +{ + char cmd[BCTEXTLEN]; + + if (! keyword) return; + + sprintf(cmd, "\"%s/doc/ContextManual.pl\" \"%s\"", getenv("CIN_DAT"), + keyword); +// printf("BC_WindowBase::context_help_show(%s):\n%s\n", keyword, cmd); + +// ContextManual.pl starts browser in background, so system() should not block + system(cmd); +} + +void BC_WindowBase::context_help_show() +{ + context_help_show(context_help_get_keyword()); +} + +int BC_WindowBase::context_help_check_and_show(const char *keyword) +{ + if (! keyword) return 0; + if (! keyword[0]) return 0; + +// We are handling Alt/H only + if (get_keypress() != 'h' || ! alt_down()) return 0; + +// Restrict cursor location to that widget keystroke occured in + if (! is_tooltip_event_win() || ! cursor_inside()) return 0; + + context_help_show(keyword); + return 1; +} + +int BC_WindowBase::context_help_check_and_show() +{ + const char *keyword; + +// We are handling Alt/H only + if (get_keypress() != 'h' || ! alt_down()) return 0; + +// Restrict cursor location, so any subwindow can define its own help keyword + if (! is_tooltip_event_win() || ! cursor_inside()) return 0; + +// If a widget has not defined its own help keyword, the parent can provide it + keyword = context_help_get_keyword(); + if (! keyword[0]) return 0; + + context_help_show(keyword); + return 1; +} +// *** END_CONTEXT_HELP *** + int BC_WindowBase::dispatch_drag_start() { int result = 0; @@ -2445,7 +2566,11 @@ void BC_WindowBase::init_im() if(!(input_method = XOpenIM(display, NULL, NULL, NULL))) { printf("BC_WindowBase::init_im: Could not open input method.\n"); + XSetLocaleModifiers("@im=local"); + if(!(input_method = XOpenIM(display, NULL, NULL, NULL))) { + printf("BC_WindowBase::init_im: Could not open input method local.\n"); exit(1); + } } if(XGetIMValues(input_method, XNQueryInputStyle, &xim_styles, NULL) || xim_styles == NULL) @@ -4036,6 +4161,12 @@ int BC_WindowBase::is_event_win() return this->win == top_level->event_win; } +int BC_WindowBase::is_tooltip_event_win() +{ + return this->win == top_level->event_win || + tooltip_popup && tooltip_popup->win == top_level->event_win; +} + void BC_WindowBase::set_dragging(int value) { is_dragging = value;