}
resize_history.remove_all_objects();
+ delete grab_lock;
#ifndef SINGLE_THREAD
common_events.remove_all_objects();
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;
event_condition = new Condition(0, "BC_WindowBase::event_condition");
init_lock = new Condition(0, "BC_WindowBase::init_lock");
#endif
+ grab_lock = new Mutex("BC_WindowBase::grab_lock");
cursor_timer = new Timer;
event_thread = 0;
}
if( active_grab ) {
+ grab_lock->lock("BC_WindowBase::dispatch_event 3");
unlock_window();
- active_grab->lock_window("BC_WindowBase::dispatch_event 3");
- result = active_grab->grab_event(event);
- active_grab->unlock_window();
+ result = 0;
+ if( active_grab ) {
+ active_grab->lock_window("BC_WindowBase::dispatch_event 3");
+ result = active_grab->grab_event(event);
+ active_grab->unlock_window();
+ }
+ grab_lock->unlock();
if( result ) return result;
lock_window("BC_WindowBase::dispatch_event 4");
}
//printf("BC_WindowBase::dispatch_event %d %d\n", __LINE__, button_number);
event_win = event->xany.window;
- if (button_number < 6) {
- if(button_number < 4)
+ if( button_number < 6 ) {
+ if( button_number < 4 )
button_down = 1;
button_pressed = event->xbutton.button;
button_time1 = button_time2;
drag_x2 = cursor_x + get_resources()->drag_radius;
drag_y1 = cursor_y - get_resources()->drag_radius;
drag_y2 = cursor_y + get_resources()->drag_radius;
-
- if((long)(button_time3 - button_time1) < resources->double_click * 2)
- {
- triple_click = 1;
- button_time3 = button_time2 = button_time1 = 0;
- }
- if((long)(button_time3 - button_time2) < resources->double_click)
- {
- double_click = 1;
-// button_time3 = button_time2 = button_time1 = 0;
- }
- else
- {
- triple_click = 0;
- double_click = 0;
+ if( button_number < 4 ) {
+ if((long)(button_time3 - button_time1) < resources->double_click * 2) {
+ triple_click = 1;
+ button_time3 = button_time2 = button_time1 = 0;
+ }
+ if((long)(button_time3 - button_time2) < resources->double_click) {
+ double_click = 1;
+// button_time3 = button_time2 = button_time1 = 0;
+ }
+ else {
+ triple_click = 0;
+ double_click = 0;
+ }
}
-
dispatch_button_press();
}
break;
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;
int BC_WindowBase::grab(BC_WindowBase *window)
{
- if( window->active_grab && this != window->active_grab ) return 0;
- window->active_grab = this;
- this->grab_active = window;
- return 1;
+ int ret = 0;
+ BC_WindowBase *grab_window = window->active_grab;
+ if( grab_window ) {
+ int locked = get_window_lock();
+ if( locked ) unlock_window();
+ grab_window->lock_window("BC_WindowBase::grab(BC_WindowBase");
+ grab_window->handle_ungrab();
+ grab_window->unlock_window();
+ if( locked ) lock_window("BC_WindowBase::grab(BC_WindowBase");
+ }
+ window->grab_lock->lock("BC_WindowBase::grab");
+ if( !window->active_grab ) {
+ window->active_grab = this;
+ this->grab_active = window;
+ ret = 1;
+ }
+ window->grab_lock->unlock();
+ return ret;
}
int BC_WindowBase::ungrab(BC_WindowBase *window)
{
- if( window->active_grab && this != window->active_grab ) return 0;
- window->active_grab = 0;
- this->grab_active = 0;
- return 1;
+ int ret = 0;
+ window->grab_lock->lock("BC_WindowBase::ungrab");
+ if( this == window->active_grab ) {
+ window->active_grab = 0;
+ this->grab_active = 0;
+ ret = 1;
+ }
+ window->grab_lock->unlock();
+ return ret;
}
int BC_WindowBase::grab_event_count()
{
get_abs_cursor(px, py, lock_window);
if( px < xmargin ) px = xmargin;
if( py < ymargin ) py = ymargin;
- int wd = get_screen_w(lock_window,-1) - xmargin;
+ int wd = get_screen_x(lock_window,-1) + get_screen_w(lock_window,-1) - xmargin;
if( px > wd ) px = wd;
- int ht = get_screen_h(lock_window,-1) - ymargin;
+ int ht = get_screen_y(lock_window,-1) + get_screen_h(lock_window,-1) - ymargin;
if( py > ht ) py = ht;
}
int BC_WindowBase::get_pop_cursor_x(int lock_window)
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;
int wx, wy, ww, wh;
int cins = info.xinerama_big_screen();
if( !info.xinerama_geometry(cins, wx, wy, ww, wh) ) {
+ int sh = ww * 9 / 16;
+ int sw = wh * 16 / 9;
+ if( sw < ww ) ww = sw;
+ if( sh < wh ) wh = sh;
if( (x_scale = ww/1920.) < 1 ) x_scale = 1;
if( (y_scale = wh/1080.) < 1 ) y_scale = 1;
}