Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wingpanel-interface: implement FocusManager #706

Merged
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions compositor/WingpanelManager/DBusWingpanelManager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class GreeterCompositor.DBusWingpanelManager : GLib.Object {
private static WindowManager wm;

private WingpanelManager background_manager;
private FocusManager focus_manager;

[DBus (visible = false)]
public static void init (WindowManager _wm) {
Expand Down Expand Up @@ -51,12 +52,19 @@ public class GreeterCompositor.DBusWingpanelManager : GLib.Object {
background_manager.state_changed.connect ((state, animation_duration) => {
state_changed (state, animation_duration);
});

focus_manager = new FocusManager (wm.get_display ());
}

public bool begin_grab_focused_window (int x, int y, int button, uint time, uint state) throws GLib.Error {
return false;
return focus_manager.begin_grab_focused_window (x, y, button, time, state);
}

public void remember_focused_window () throws GLib.Error {
focus_manager.remember_focused_window ();
}

public void remember_focused_window () throws GLib.Error {}
public void restore_focused_window () throws GLib.Error {}
public void restore_focused_window () throws GLib.Error {
focus_manager.restore_focused_window ();
}
}
142 changes: 142 additions & 0 deletions compositor/WingpanelManager/FocusManager.vala
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
/*
* Copyright (c) 2011-2015 Wingpanel Developers (http://launchpad.net/wingpanel)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*/
lenemter marked this conversation as resolved.
Show resolved Hide resolved

public class GreeterCompositor.FocusManager : GLib.Object {
private unowned Meta.Display display;
private unowned Meta.Workspace? current_workspace = null;
private unowned Meta.Window? last_focused_window = null;
private unowned Meta.Window? last_focused_dialog_window = null;

public FocusManager (Meta.Display _display) {
display = _display;

unowned Meta.WorkspaceManager manager = display.get_workspace_manager ();
manager.workspace_switched.connect (() => {
update_current_workspace ();
});

update_current_workspace ();
}

public void remember_focused_window () {
var windows = current_workspace.list_windows ();
foreach (unowned Meta.Window window in windows) {
window_created (window);
if (window.has_focus ()) {
last_focused_window = window;
}
}

display.window_created.connect (window_created);
}

public void restore_focused_window () {
// when a dialog was opened give it focus
if (last_focused_dialog_window != null) {
last_focused_dialog_window.focus (display.get_current_time ());
// if dialog is closed pass focus to last focussed window
last_focused_dialog_window.unmanaged.connect (() => {
last_focused_dialog_window = null;
restore_focused_window ();
});
} else if (last_focused_window != null) {
last_focused_window.focus (display.get_current_time ());
}

var windows = current_workspace.list_windows ();
foreach (unowned Meta.Window window in windows) {
window.focused.disconnect (window_focused);
window.unmanaged.disconnect (window_unmanaged);
}

display.window_created.disconnect (window_created);
}

void window_created (Meta.Window window) {
window.focused.connect (window_focused);
window.unmanaged.connect (window_unmanaged);
}

void window_focused (Meta.Window window) {
// make sure we keep the last_focused_window when a dialog is started from wingpanel
if (window.window_type == Meta.WindowType.DIALOG) {
last_focused_dialog_window = window;
} else if (window.window_type != Meta.WindowType.DOCK) { // ignore focus to wingpanel
last_focused_window = window;
}
}

void window_unmanaged (Meta.Window window) {
window.focused.disconnect (window_focused);
window.unmanaged.disconnect (window_unmanaged);
}

public bool begin_grab_focused_window (int x, int y, int button, uint time, uint state) {
unowned var window = display.get_focus_window ();
if (window == null || !get_can_grab_window (window, x, y)) {
unowned Meta.Workspace workspace = display.get_workspace_manager ().get_active_workspace ();
List<unowned Meta.Window>? windows = workspace.list_windows ();
if (windows == null) {
return false;
}

window = null;
List<unowned Meta.Window> copy = windows.copy ();
copy.reverse ();
copy.@foreach ((win) => {
if (window != null) {
return;
}

if (get_can_grab_window (win, x, y)) {
window = win;
}
});
}

if (window != null) {
#if HAS_MUTTER44
window.begin_grab_op (Meta.GrabOp.MOVING, null, null, time);
#else
display.begin_grab_op (window, Meta.GrabOp.MOVING, false, true, button, state, time, x, y);
#endif
return true;
}

return false;
}

private static bool get_can_grab_window (Meta.Window window, int x, int y) {
var frame = window.get_frame_rect ();
return !window.minimized && window.maximized_vertically && x >= frame.x && x <= frame.x + frame.width;
}

private void update_current_workspace () {
unowned Meta.WorkspaceManager manager = display.get_workspace_manager ();
unowned var workspace = manager.get_workspace_by_index (manager.get_active_workspace_index ());

if (workspace == null) {
warning ("Cannot get active workspace");

return;
}

current_workspace = workspace;
}
}
1 change: 1 addition & 0 deletions compositor/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ compositor_files = files(
'Background/SystemBackground.vala',
'WingpanelManager/WingpanelManager.vala',
'WingpanelManager/DBusWingpanelManager.vala',
'WingpanelManager/FocusManager.vala',
'WingpanelManager/BackgroundUtils.vala',
'DBus.vala',
'DBusAccelerator.vala',
Expand Down