Merge branch 'mousefocus'

This commit is contained in:
Jim Ramsay 2009-05-26 16:45:05 -04:00
commit 54b49c63a6
5 changed files with 55 additions and 3 deletions

View file

@ -81,7 +81,8 @@ FocusControl::FocusControl(BScreen &screen):
m_focused_win_list(screen), m_creation_order_win_list(screen), m_focused_win_list(screen), m_creation_order_win_list(screen),
m_cycling_list(0), m_cycling_list(0),
m_was_iconic(false), m_was_iconic(false),
m_cycling_last(0) { m_cycling_last(0),
m_ignore_mouse_x(-1), m_ignore_mouse_y(-1) {
m_cycling_window = m_focused_list.clientList().end(); m_cycling_window = m_focused_list.clientList().end();
@ -400,6 +401,28 @@ void FocusControl::dirFocus(FluxboxWindow &win, FocusDir dir) {
} }
void FocusControl::ignoreAtPointer()
{
int ignore_i;
unsigned int ignore_ui;
Window ignore_w;
XQueryPointer(m_screen.rootWindow().display(),
m_screen.rootWindow().window(), &ignore_w, &ignore_w,
&m_ignore_mouse_x, &m_ignore_mouse_y,
&ignore_i, &ignore_i, &ignore_ui);
}
void FocusControl::ignoreAt(int x, int y)
{
m_ignore_mouse_x = x; m_ignore_mouse_y = y;
}
bool FocusControl::isIgnored(int x, int y)
{
return x == m_ignore_mouse_x && y == m_ignore_mouse_y;
}
void FocusControl::removeClient(WinClient &client) { void FocusControl::removeClient(WinClient &client) {
if (client.screen().isShuttingdown()) if (client.screen().isShuttingdown())
return; return;

View file

@ -93,6 +93,15 @@ public:
bool isMouseFocus() const { return focusModel() == MOUSEFOCUS; } bool isMouseFocus() const { return focusModel() == MOUSEFOCUS; }
/// @return true if tab focus mode is mouse tab focus /// @return true if tab focus mode is mouse tab focus
bool isMouseTabFocus() const { return tabFocusModel() == MOUSETABFOCUS; } bool isMouseTabFocus() const { return tabFocusModel() == MOUSETABFOCUS; }
/// Set the "ignore" pointer location to the current pointer location
void ignoreAtPointer();
/// Set the "ignore" pointer location to the given coordinates
void ignoreAt(int x, int y);
/// @return true if events at the given X/Y coordinate should be ignored
/// (ie, they were previously cached via one of the ignoreAt calls)
bool isIgnored(int x, int y);
/// @return true if cycling is in progress /// @return true if cycling is in progress
bool isCycling() const { return m_cycling_list != 0; } bool isCycling() const { return m_cycling_list != 0; }
/// Appends a client to the front of the focus list /// Appends a client to the front of the focus list
@ -157,6 +166,7 @@ private:
const FocusableList *m_cycling_list; const FocusableList *m_cycling_list;
Focusable *m_was_iconic; Focusable *m_was_iconic;
WinClient *m_cycling_last; WinClient *m_cycling_last;
int m_ignore_mouse_x, m_ignore_mouse_y;
static WinClient *s_focused_window; static WinClient *s_focused_window;
static FluxboxWindow *s_focused_fbwindow; static FluxboxWindow *s_focused_fbwindow;

View file

@ -1098,6 +1098,9 @@ void BScreen::changeWorkspaceID(unsigned int id, bool revert) {
id == m_current_workspace->workspaceID()) id == m_current_workspace->workspaceID())
return; return;
/* Ignore all EnterNotify events until the pointer actually moves */
this->focusControl().ignoreAtPointer();
FbTk::App::instance()->sync(false); FbTk::App::instance()->sync(false);
FluxboxWindow *focused = FocusControl::focusedFbWindow(); FluxboxWindow *focused = FocusControl::focusedFbWindow();

View file

@ -1213,6 +1213,9 @@ void FluxboxWindow::moveResize(int new_x, int new_y,
if (!moving) { if (!moving) {
m_last_resize_x = new_x; m_last_resize_x = new_x;
m_last_resize_y = new_y; m_last_resize_y = new_y;
/* Ignore all EnterNotify events until the pointer actually moves */
screen().focusControl().ignoreAtPointer();
} }
} }
@ -1670,6 +1673,10 @@ void FluxboxWindow::lower() {
#ifdef DEBUG #ifdef DEBUG
cerr<<"FluxboxWindow("<<title()<<")::lower()"<<endl; cerr<<"FluxboxWindow("<<title()<<")::lower()"<<endl;
#endif // DEBUG #endif // DEBUG
/* Ignore all EnterNotify events until the pointer actually moves */
screen().focusControl().ignoreAtPointer();
// get root window // get root window
WinClient *client = getRootTransientFor(m_client); WinClient *client = getRootTransientFor(m_client);
@ -2684,13 +2691,17 @@ void FluxboxWindow::enterNotifyEvent(XCrossingEvent &ev) {
sa.enter = sa.leave = False; sa.enter = sa.leave = False;
XCheckIfEvent(display, &dummy, queueScanner, (char *) &sa); XCheckIfEvent(display, &dummy, queueScanner, (char *) &sa);
if ((!sa.leave || sa.inferior) && !screen().focusControl().isCycling() ) { if ((!sa.leave || sa.inferior) &&
!screen().focusControl().isCycling() &&
!screen().focusControl().isIgnored(ev.x_root, ev.y_root) ) {
focus(); focus();
} }
} }
} }
if (screen().focusControl().isMouseTabFocus() && client && client != m_client) { if (screen().focusControl().isMouseTabFocus() &&
client && client != m_client &&
!screen().focusControl().isIgnored(ev.x_root, ev.y_root) ) {
setCurrentClient(*client, isFocused()); setCurrentClient(*client, isFocused());
} }

View file

@ -899,6 +899,11 @@ void Fluxbox::handleUnmapNotify(XUnmapEvent &ue) {
BScreen *screen = searchScreen(ue.event); BScreen *screen = searchScreen(ue.event);
if (screen) {
/* Ignore all EnterNotify events until the pointer actually moves */
screen->focusControl().ignoreAtPointer();
}
if (ue.event != ue.window && (!screen || !ue.send_event)) { if (ue.event != ue.window && (!screen || !ue.send_event)) {
return; return;
} }