👕 Lint lib directory with vala-lint (#607)

This commit is contained in:
Keli Grubb 2019-09-05 16:18:43 -04:00 committed by Adam Bieńkowski
parent 50694796d4
commit 49d1d8ffab
6 changed files with 766 additions and 791 deletions

View File

@ -15,37 +15,34 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
namespace Gala namespace Gala {
{ /**
/** * Implement this interface on your {@link Plugin} class if you want to
* Implement this interface on your {@link Plugin} class if you want to * replace a component like the window overview or the multitasking view.
* replace a component like the window overview or the multitasking view. * It allows gala to hook up functionality like hotcorners and dbus
* It allows gala to hook up functionality like hotcorners and dbus * invocation of your component.
* invocation of your component. */
*/ public interface ActivatableComponent : Object {
public interface ActivatableComponent : Object /**
{ * The component was requested to be opened.
/** *
* The component was requested to be opened. * @param hints The hashmap may contain special parameters that are useful
* * to the component. Currently, the only one implemented is the
* @param hints The hashmap may contain special parameters that are useful * 'all-windows' hint to the windowoverview.
* to the component. Currently, the only one implemented is the */
* 'all-windows' hint to the windowoverview. public abstract void open (HashTable<string,Variant>? hints = null);
*/
public abstract void open (HashTable<string,Variant>? hints = null);
/** /**
* The component was requested to be closed. * The component was requested to be closed.
*/ */
public abstract void close (); public abstract void close ();
/** /**
* Should return whether the component is currently opened. Used mainly for * Should return whether the component is currently opened. Used mainly for
* toggling by the window manager. * toggling by the window manager.
* *
* @return Return true if the component is opened. * @return Return true if the component is opened.
*/ */
public abstract bool is_opened (); public abstract bool is_opened ();
} }
} }

View File

@ -15,21 +15,20 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
namespace Gala namespace Gala {
{ [CCode (has_type_id = false)]
[CCode (has_type_id = false)] public enum AnimationDuration {
public enum AnimationDuration { // Duration of the open animation
// Duration of the open animation OPEN = 350,
OPEN = 350, // Duration of the close animation
// Duration of the close animation CLOSE = 195,
CLOSE = 195, // Duration of the minimize animation
// Duration of the minimize animation MINIMIZE = 200,
MINIMIZE = 200, // Duration of the menu mapping animation
// Duration of the menu mapping animation MENU_MAP = 150,
MENU_MAP = 150, // Duration of the snap animation as used by maximize/unmaximize
// Duration of the snap animation as used by maximize/unmaximize SNAP = 250,
SNAP = 250, // Duration of the workspace switch animation
// Duration of the workspace switch animation WORKSPACE_SWITCH = 300,
WORKSPACE_SWITCH = 300, }
}
} }

View File

@ -15,206 +15,196 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
namespace Gala namespace Gala {
{ public enum PluginFunction {
public enum PluginFunction ADDITION,
{ WINDOW_SWITCHER,
ADDITION, DESKTOP,
WINDOW_SWITCHER, WORKSPACE_VIEW,
DESKTOP, WINDOW_OVERVIEW
WORKSPACE_VIEW, }
WINDOW_OVERVIEW
}
public enum LoadPriority public enum LoadPriority {
{ /**
/** * Have your plugin loaded immediately once gala has started
* Have your plugin loaded immediately once gala has started */
*/ IMMEDIATE,
IMMEDIATE, /**
/** * Allow gala to defer loading your plugin once it got the
* Allow gala to defer loading your plugin once it got the * major part of the initialization done
* major part of the initialization done */
*/ DEFERRED
DEFERRED }
}
public struct PluginInfo public struct PluginInfo {
{ string name;
string name; string author;
string author;
/** /**
* Type of your plugin class, has to be derived from the Plugin class. * Type of your plugin class, has to be derived from the Plugin class.
*/ */
Type plugin_type; Type plugin_type;
/** /**
* This property allows you to override default functionality of gala * This property allows you to override default functionality of gala
* so systems won't be instantiated next to each other. Use * so systems won't be instantiated next to each other. Use
* PluginFunction.ADDITION if no special component is overridden. * PluginFunction.ADDITION if no special component is overridden.
*/ */
PluginFunction provides; PluginFunction provides;
/** /**
* Give gala a hint for when to load your plugin. Especially use DEFERRED * Give gala a hint for when to load your plugin. Especially use DEFERRED
* if you're adding a completely new ui component that's not directly * if you're adding a completely new ui component that's not directly
* related to the wm. * related to the wm.
*/ */
LoadPriority load_priority; LoadPriority load_priority;
/** /**
* You don't have to fill this field, it will be filled by gala with * You don't have to fill this field, it will be filled by gala with
* the filename in which your module was found. * the filename in which your module was found.
*/ */
string module_name; string module_name;
} }
/** /**
* This class has to be implemented by every plugin. * This class has to be implemented by every plugin.
* Additionally, the plugin module is required to have a register_plugin * Additionally, the plugin module is required to have a register_plugin
* function which returns a PluginInfo struct. * function which returns a PluginInfo struct.
* The plugin_type field has to be the type of your plugin class derived * The plugin_type field has to be the type of your plugin class derived
* from this class. * from this class.
*/ */
public abstract class Plugin : Object public abstract class Plugin : Object {
{ /**
/** * Emitted when update_region is called. Mainly for internal purposes.
* Emitted when update_region is called. Mainly for internal purposes. */
*/ public signal void region_changed ();
public signal void region_changed ();
/** /**
* The region indicates an area where mouse events should be sent to * The region indicates an area where mouse events should be sent to
* the stage, which means your actors, instead of the windows. * the stage, which means your actors, instead of the windows.
* *
* It is calculated by the system whenever update_region is called. * It is calculated by the system whenever update_region is called.
* You can influce it with the custom_region and the track_actor function. * You can influce it with the custom_region and the track_actor function.
*/ */
public Meta.Rectangle[] region { get; private set; } public Meta.Rectangle[] region { get; private set; }
/** /**
* This list will be merged with the region property. See region for * This list will be merged with the region property. See region for
* more details. Changing this property will cause update_region to be * more details. Changing this property will cause update_region to be
* called. Default to null. * called. Default to null.
*/ */
protected Meta.Rectangle[]? custom_region { protected Meta.Rectangle[]? custom_region {
get { get {
return _custom_region; return _custom_region;
} }
protected set { protected set {
_custom_region = value; _custom_region = value;
update_region (); update_region ();
} }
} }
/** /**
* Set this property to true while animating an actor if you have tracked * Set this property to true while animating an actor if you have tracked
* actors to prevent constant recalculations of the regions during an * actors to prevent constant recalculations of the regions during an
* animation. * animation.
*/ */
protected bool freeze_track { protected bool freeze_track {
get { get {
return _freeze_track; return _freeze_track;
} }
set { set {
_freeze_track = value; _freeze_track = value;
if (!_freeze_track) if (!_freeze_track)
update_region (); update_region ();
} }
} }
private bool _freeze_track = false; private bool _freeze_track = false;
private Meta.Rectangle[]? _custom_region = null; private Meta.Rectangle[]? _custom_region = null;
private List<Clutter.Actor> tracked_actors = new List<Clutter.Actor> (); private List<Clutter.Actor> tracked_actors = new List<Clutter.Actor> ();
/** /**
* Once this method is called you can start adding actors to the stage * Once this method is called you can start adding actors to the stage
* via the windowmanager instance that is given to you. * via the windowmanager instance that is given to you.
* *
* @param wm The window manager. * @param wm The window manager.
*/ */
public abstract void initialize (WindowManager wm); public abstract void initialize (WindowManager wm);
/** /**
* This method is currently not called in the code, however you should * This method is currently not called in the code, however you should
* still implement it to be compatible whenever we decide to use it. * still implement it to be compatible whenever we decide to use it.
* It should make sure that everything your plugin added to the stage * It should make sure that everything your plugin added to the stage
* is cleaned up. * is cleaned up.
*/ */
public abstract void destroy (); public abstract void destroy ();
/** /**
* Listen to changes to the allocation of actor and update the region * Listen to changes to the allocation of actor and update the region
* accordingly. You may add multiple actors, their shapes will be * accordingly. You may add multiple actors, their shapes will be
* combined when one of them changes. * combined when one of them changes.
* *
* @param actor The actor to be tracked * @param actor The actor to be tracked
*/ */
public void track_actor (Clutter.Actor actor) public void track_actor (Clutter.Actor actor) {
{ tracked_actors.prepend (actor);
tracked_actors.prepend (actor); actor.allocation_changed.connect (actor_allocation_changed);
actor.allocation_changed.connect (actor_allocation_changed);
update_region (); update_region ();
} }
/** /**
* Stop listening to allocation changes and remove the actor's * Stop listening to allocation changes and remove the actor's
* allocation from the region array. * allocation from the region array.
* *
* @param actor The actor to stop listening the changes on * @param actor The actor to stop listening the changes on
*/ */
public void untrack_actor (Clutter.Actor actor) public void untrack_actor (Clutter.Actor actor) {
{ tracked_actors.remove (actor);
tracked_actors.remove (actor); actor.allocation_changed.disconnect (actor_allocation_changed);
actor.allocation_changed.disconnect (actor_allocation_changed); }
}
/** /**
* You can call this method to force the system to update the region that * You can call this method to force the system to update the region that
* is used by the window manager. It will automatically upon changes to * is used by the window manager. It will automatically upon changes to
* the custom_region property and when a tracked actor's allocation changes * the custom_region property and when a tracked actor's allocation changes
* unless freeze_track is set to true. You may need to call this function * unless freeze_track is set to true. You may need to call this function
* after setting freeze_track back to false after an animation to make the * after setting freeze_track back to false after an animation to make the
* wm aware of the new position of the actor in question. * wm aware of the new position of the actor in question.
*/ */
public void update_region () public void update_region () {
{ var has_custom = custom_region != null;
var has_custom = custom_region != null; var len = tracked_actors.length () + (has_custom ? custom_region.length : 0);
var len = tracked_actors.length () + (has_custom ? custom_region.length : 0);
Meta.Rectangle[] regions = new Meta.Rectangle[len]; Meta.Rectangle[] regions = new Meta.Rectangle[len];
var i = 0; var i = 0;
if (has_custom) { if (has_custom) {
for (var j = 0; j < custom_region.length; j++) { for (var j = 0; j < custom_region.length; j++) {
regions[i++] = custom_region[j]; regions[i++] = custom_region[j];
} }
} }
foreach (var actor in tracked_actors) { foreach (var actor in tracked_actors) {
float x, y, w, h; float x, y, w, h;
actor.get_transformed_position (out x, out y); actor.get_transformed_position (out x, out y);
actor.get_transformed_size (out w, out h); actor.get_transformed_size (out w, out h);
if (w == 0 || h == 0) if (w == 0 || h == 0)
continue; continue;
regions[i++] = { (int) x, (int) y, (int) w, (int) h }; regions[i++] = { (int) x, (int) y, (int) w, (int) h };
} }
region = regions; region = regions;
region_changed (); region_changed ();
} }
private void actor_allocation_changed (Clutter.ActorBox box, Clutter.AllocationFlags f) private void actor_allocation_changed (Clutter.ActorBox box, Clutter.AllocationFlags f) {
{ if (!freeze_track)
if (!freeze_track) update_region ();
update_region (); }
} }
}
} }

View File

@ -15,387 +15,392 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
namespace Gala namespace Gala {
{ public class Utils {
public class Utils // Cache xid:pixbuf and icon:pixbuf pairs to provide a faster way aquiring icons
{ static HashTable<string, Gdk.Pixbuf> xid_pixbuf_cache;
// Cache xid:pixbuf and icon:pixbuf pairs to provide a faster way aquiring icons static HashTable<string, Gdk.Pixbuf> icon_pixbuf_cache;
static HashTable<string, Gdk.Pixbuf> xid_pixbuf_cache; static uint cache_clear_timeout = 0;
static HashTable<string, Gdk.Pixbuf> icon_pixbuf_cache;
static uint cache_clear_timeout = 0;
static Gdk.Pixbuf? close_pixbuf = null; static Gdk.Pixbuf? close_pixbuf = null;
static Gdk.Pixbuf? resize_pixbuf = null; static Gdk.Pixbuf? resize_pixbuf = null;
static construct static construct {
{ xid_pixbuf_cache = new HashTable<string, Gdk.Pixbuf> (str_hash, str_equal);
xid_pixbuf_cache = new HashTable<string, Gdk.Pixbuf> (str_hash, str_equal); icon_pixbuf_cache = new HashTable<string, Gdk.Pixbuf> (str_hash, str_equal);
icon_pixbuf_cache = new HashTable<string, Gdk.Pixbuf> (str_hash, str_equal); }
}
Utils () Utils () {
{ }
}
/** /**
* Clean icon caches * Clean icon caches
*/ */
static void clean_icon_cache (uint32[] xids) static void clean_icon_cache (uint32[] xids) {
{ var list = xid_pixbuf_cache.get_keys ();
var list = xid_pixbuf_cache.get_keys (); var pixbuf_list = icon_pixbuf_cache.get_values ();
var pixbuf_list = icon_pixbuf_cache.get_values (); var icon_list = icon_pixbuf_cache.get_keys ();
var icon_list = icon_pixbuf_cache.get_keys ();
foreach (var xid_key in list) { foreach (var xid_key in list) {
var xid = (uint32)uint64.parse (xid_key.split ("::")[0]); var xid = (uint32)uint64.parse (xid_key.split ("::")[0]);
if (!(xid in xids)) { if (!(xid in xids)) {
var pixbuf = xid_pixbuf_cache.get (xid_key); var pixbuf = xid_pixbuf_cache.get (xid_key);
for (var j = 0; j < pixbuf_list.length (); j++) { for (var j = 0; j < pixbuf_list.length (); j++) {
if (pixbuf_list.nth_data (j) == pixbuf) { if (pixbuf_list.nth_data (j) == pixbuf) {
xid_pixbuf_cache.remove (icon_list.nth_data (j)); xid_pixbuf_cache.remove (icon_list.nth_data (j));
} }
} }
xid_pixbuf_cache.remove (xid_key); xid_pixbuf_cache.remove (xid_key);
} }
} }
} }
/** /**
* Marks the given xids as no longer needed, the corresponding icons * Marks the given xids as no longer needed, the corresponding icons
* may be freed now. Mainly for internal purposes. * may be freed now. Mainly for internal purposes.
* *
* @param xids The xids of the window that no longer need icons * @param xids The xids of the window that no longer need icons
*/ */
public static void request_clean_icon_cache (uint32[] xids) public static void request_clean_icon_cache (uint32[] xids) {
{ if (cache_clear_timeout > 0)
if (cache_clear_timeout > 0) GLib.Source.remove (cache_clear_timeout);
GLib.Source.remove (cache_clear_timeout);
cache_clear_timeout = Timeout.add_seconds (30, () => { cache_clear_timeout = Timeout.add_seconds (30, () => {
cache_clear_timeout = 0; cache_clear_timeout = 0;
Idle.add (() => { Idle.add (() => {
clean_icon_cache (xids); clean_icon_cache (xids);
return false; return false;
}); });
return false; return false;
}); });
} }
/** /**
* Returns a pixbuf for the application of this window or a default icon * Returns a pixbuf for the application of this window or a default icon
* *
* @param window The window to get an icon for * @param window The window to get an icon for
* @param size The size of the icon * @param size The size of the icon
* @param scale The desired scale of the icon * @param scale The desired scale of the icon
* @param ignore_cache Should not be necessary in most cases, if you care about the icon * @param ignore_cache Should not be necessary in most cases, if you care about the icon
* being loaded correctly, you should consider using the WindowIcon class * being loaded correctly, you should consider using the WindowIcon class
*/ */
public static Gdk.Pixbuf get_icon_for_window (Meta.Window window, int size, int scale = 1, bool ignore_cache = false) public static Gdk.Pixbuf get_icon_for_window (
{ Meta.Window window,
return get_icon_for_xid ((uint32)window.get_xwindow (), size, scale, ignore_cache); int size,
} int scale = 1,
bool ignore_cache = false
) {
return get_icon_for_xid ((uint32)window.get_xwindow (), size, scale, ignore_cache);
}
/** /**
* Returns a pixbuf for a given xid or a default icon * Returns a pixbuf for a given xid or a default icon
* *
* @see get_icon_for_window * @see get_icon_for_window
*/ */
public static Gdk.Pixbuf get_icon_for_xid (uint32 xid, int size, int scale = 1, bool ignore_cache = false) public static Gdk.Pixbuf get_icon_for_xid (uint32 xid, int size, int scale = 1, bool ignore_cache = false) {
{ Gdk.Pixbuf? result = null;
Gdk.Pixbuf? result = null; var xid_key = "%u::%i".printf (xid, size);
var xid_key = "%u::%i".printf (xid, size);
if (!ignore_cache && (result = xid_pixbuf_cache.get (xid_key)) != null) if (!ignore_cache && (result = xid_pixbuf_cache.get (xid_key)) != null)
return result; return result;
var app = Bamf.Matcher.get_default ().get_application_for_xid (xid); var app = Bamf.Matcher.get_default ().get_application_for_xid (xid);
result = get_icon_for_application (app, size, scale, ignore_cache); result = get_icon_for_application (app, size, scale, ignore_cache);
xid_pixbuf_cache.set (xid_key, result); xid_pixbuf_cache.set (xid_key, result);
return result; return result;
} }
/** /**
* Returns a pixbuf for this application or a default icon * Returns a pixbuf for this application or a default icon
* *
* @see get_icon_for_window * @see get_icon_for_window
*/ */
static Gdk.Pixbuf get_icon_for_application (Bamf.Application? app, int size, int scale = 1, static Gdk.Pixbuf get_icon_for_application (
bool ignore_cache = false) Bamf.Application? app,
{ int size,
Gdk.Pixbuf? image = null; int scale = 1,
bool not_cached = false; bool ignore_cache = false
) {
Gdk.Pixbuf? image = null;
bool not_cached = false;
string? icon = null; string? icon = null;
string? icon_key = null; string? icon_key = null;
if (app != null && app.get_desktop_file () != null) { if (app != null && app.get_desktop_file () != null) {
var appinfo = new DesktopAppInfo.from_filename (app.get_desktop_file ()); var appinfo = new DesktopAppInfo.from_filename (app.get_desktop_file ());
if (appinfo != null) { if (appinfo != null) {
icon = Plank.DrawingService.get_icon_from_gicon (appinfo.get_icon ()); icon = Plank.DrawingService.get_icon_from_gicon (appinfo.get_icon ());
icon_key = "%s::%i::%i".printf (icon, size, scale); icon_key = "%s::%i::%i".printf (icon, size, scale);
if (ignore_cache || (image = icon_pixbuf_cache.get (icon_key)) == null) { if (ignore_cache || (image = icon_pixbuf_cache.get (icon_key)) == null) {
var scaled_size = size * scale; var scaled_size = size * scale;
var surface = Plank.DrawingService.load_icon_for_scale (icon, scaled_size, scaled_size, scale); var surface = Plank.DrawingService.load_icon_for_scale (icon, scaled_size, scaled_size, scale);
image = Gdk.pixbuf_get_from_surface (surface, 0, 0, scaled_size, scaled_size); image = Gdk.pixbuf_get_from_surface (surface, 0, 0, scaled_size, scaled_size);
not_cached = true; not_cached = true;
} }
} }
} }
if (image == null) { if (image == null) {
try { try {
unowned Gtk.IconTheme icon_theme = Gtk.IconTheme.get_default (); unowned Gtk.IconTheme icon_theme = Gtk.IconTheme.get_default ();
icon = "application-default-icon"; icon = "application-default-icon";
icon_key = "%s::%i::%i".printf (icon, size, scale); icon_key = "%s::%i::%i".printf (icon, size, scale);
if ((image = icon_pixbuf_cache.get (icon_key)) == null) { if ((image = icon_pixbuf_cache.get (icon_key)) == null) {
image = icon_theme.load_icon_for_scale (icon, size, scale, 0); image = icon_theme.load_icon_for_scale (icon, size, scale, 0);
not_cached = true; not_cached = true;
} }
} catch (Error e) { } catch (Error e) {
warning (e.message); warning (e.message);
} }
} }
if (image == null) { if (image == null) {
icon = ""; icon = "";
icon_key = "::%i".printf (size); icon_key = "::%i".printf (size);
if ((image = icon_pixbuf_cache.get (icon_key)) == null) { if ((image = icon_pixbuf_cache.get (icon_key)) == null) {
image = new Gdk.Pixbuf (Gdk.Colorspace.RGB, true, 8, size, size); image = new Gdk.Pixbuf (Gdk.Colorspace.RGB, true, 8, size, size);
image.fill (0x00000000); image.fill (0x00000000);
not_cached = true; not_cached = true;
} }
} }
if (size * scale != image.width || size * scale != image.height) if (size * scale != image.width || size * scale != image.height)
image = Plank.DrawingService.ar_scale (image, size * scale, size * scale); image = Plank.DrawingService.ar_scale (image, size * scale, size * scale);
if (not_cached) if (not_cached)
icon_pixbuf_cache.set (icon_key, image); icon_pixbuf_cache.set (icon_key, image);
return image; return image;
} }
/** /**
* Get the next window that should be active on a workspace right now. Based on * Get the next window that should be active on a workspace right now. Based on
* stacking order * stacking order
* *
* @param workspace The workspace on which to find the window * @param workspace The workspace on which to find the window
* @param backward Whether to get the previous one instead * @param backward Whether to get the previous one instead
*/ */
public static Meta.Window get_next_window (Meta.Workspace workspace, bool backward = false) public static Meta.Window get_next_window (Meta.Workspace workspace, bool backward = false) {
{ var screen = workspace.get_screen ();
var screen = workspace.get_screen (); var display = screen.get_display ();
var display = screen.get_display ();
var window = display.get_tab_next (Meta.TabList.NORMAL, var window = display.get_tab_next (Meta.TabList.NORMAL,
workspace, null, backward); workspace, null, backward);
if (window == null) if (window == null)
window = display.get_tab_current (Meta.TabList.NORMAL, workspace); window = display.get_tab_current (Meta.TabList.NORMAL, workspace);
return window; return window;
} }
/** /**
* Get the number of toplevel windows on a workspace excluding those that are * Get the number of toplevel windows on a workspace excluding those that are
* on all workspaces * on all workspaces
* *
* @param workspace The workspace on which to count the windows * @param workspace The workspace on which to count the windows
*/ */
public static uint get_n_windows (Meta.Workspace workspace) public static uint get_n_windows (Meta.Workspace workspace) {
{ var n = 0;
var n = 0; foreach (weak Meta.Window window in workspace.list_windows ()) {
foreach (weak Meta.Window window in workspace.list_windows ()) { if (window.on_all_workspaces)
if (window.on_all_workspaces) continue;
continue; if (
if (window.window_type == Meta.WindowType.NORMAL || window.window_type == Meta.WindowType.NORMAL ||
window.window_type == Meta.WindowType.DIALOG || window.window_type == Meta.WindowType.DIALOG ||
window.window_type == Meta.WindowType.MODAL_DIALOG) window.window_type == Meta.WindowType.MODAL_DIALOG)
n ++; n ++;
} }
return n; return n;
} }
/** /**
* Creates an actor showing the current contents of the given WindowActor. * Creates an actor showing the current contents of the given WindowActor.
* *
* @param actor The actor from which to create a shnapshot * @param actor The actor from which to create a shnapshot
* @param inner_rect The inner (actually visible) rectangle of the window * @param inner_rect The inner (actually visible) rectangle of the window
* @param outer_rect The outer (input region) rectangle of the window * @param outer_rect The outer (input region) rectangle of the window
* *
* @return A copy of the actor at that time or %NULL * @return A copy of the actor at that time or %NULL
*/ */
public static Clutter.Actor? get_window_actor_snapshot (Meta.WindowActor actor, Meta.Rectangle inner_rect, Meta.Rectangle outer_rect) public static Clutter.Actor? get_window_actor_snapshot (
{ Meta.WindowActor actor,
var texture = actor.get_texture () as Meta.ShapedTexture; Meta.Rectangle inner_rect,
Meta.Rectangle outer_rect
) {
var texture = actor.get_texture () as Meta.ShapedTexture;
if (texture == null) if (texture == null)
return null; return null;
var surface = texture.get_image ({ var surface = texture.get_image ({
inner_rect.x - outer_rect.x, inner_rect.x - outer_rect.x,
inner_rect.y - outer_rect.y, inner_rect.y - outer_rect.y,
inner_rect.width, inner_rect.width,
inner_rect.height inner_rect.height
}); });
if (surface == null) if (surface == null)
return null; return null;
var canvas = new Clutter.Canvas (); var canvas = new Clutter.Canvas ();
var handler = canvas.draw.connect ((cr) => { var handler = canvas.draw.connect ((cr) => {
cr.set_source_surface (surface, 0, 0); cr.set_source_surface (surface, 0, 0);
cr.paint (); cr.paint ();
return false; return false;
}); });
canvas.set_size (inner_rect.width, inner_rect.height); canvas.set_size (inner_rect.width, inner_rect.height);
SignalHandler.disconnect (canvas, handler); SignalHandler.disconnect (canvas, handler);
var container = new Clutter.Actor (); var container = new Clutter.Actor ();
container.set_size (inner_rect.width, inner_rect.height); container.set_size (inner_rect.width, inner_rect.height);
container.content = canvas; container.content = canvas;
return container; return container;
} }
/** /**
* Ring the system bell, will most likely emit a <beep> error sound or, if the * Ring the system bell, will most likely emit a <beep> error sound or, if the
* audible bell is disabled, flash the screen * audible bell is disabled, flash the screen
* *
* @param screen The screen to flash, if necessary * @param screen The screen to flash, if necessary
*/ */
public static void bell (Meta.Screen screen) public static void bell (Meta.Screen screen) {
{ if (Meta.Prefs.bell_is_audible ())
if (Meta.Prefs.bell_is_audible ()) Gdk.beep ();
Gdk.beep (); else
else screen.get_display ().get_compositor ().flash_screen (screen);
screen.get_display ().get_compositor ().flash_screen (screen); }
}
public static int get_ui_scaling_factor () public static int get_ui_scaling_factor () {
{
#if HAS_MUTTER326 #if HAS_MUTTER326
return Meta.Backend.get_backend ().get_settings ().get_ui_scaling_factor (); return Meta.Backend.get_backend ().get_settings ().get_ui_scaling_factor ();
#else #else
return 1; return 1;
#endif #endif
} }
/** /**
* Returns the pixbuf that is used for close buttons throughout gala at a * Returns the pixbuf that is used for close buttons throughout gala at a
* size of 36px * size of 36px
* *
* @return the close button pixbuf or null if it failed to load * @return the close button pixbuf or null if it failed to load
*/ */
public static Gdk.Pixbuf? get_close_button_pixbuf () public static Gdk.Pixbuf? get_close_button_pixbuf () {
{ var height = 36 * Utils.get_ui_scaling_factor ();
var height = 36 * Utils.get_ui_scaling_factor (); if (close_pixbuf == null || close_pixbuf.height != height) {
if (close_pixbuf == null || close_pixbuf.height != height) { try {
try { close_pixbuf = new Gdk.Pixbuf.from_resource_at_scale (
close_pixbuf = new Gdk.Pixbuf.from_resource_at_scale (Config.RESOURCEPATH + "/buttons/close.svg", -1, height, true); Config.RESOURCEPATH + "/buttons/close.svg",
} catch (Error e) { -1,
warning (e.message); height,
return null; true
} );
} } catch (Error e) {
warning (e.message);
return null;
}
}
return close_pixbuf; return close_pixbuf;
} }
/** /**
* Creates a new reactive ClutterActor at 36px with the close pixbuf * Creates a new reactive ClutterActor at 36px with the close pixbuf
* *
* @return The close button actor * @return The close button actor
*/ */
public static Clutter.Actor create_close_button () public static Clutter.Actor create_close_button () {
{ var texture = new Clutter.Texture ();
var texture = new Clutter.Texture (); var pixbuf = get_close_button_pixbuf ();
var pixbuf = get_close_button_pixbuf ();
texture.reactive = true; texture.reactive = true;
if (pixbuf != null) { if (pixbuf != null) {
try { try {
texture.set_from_rgb_data (pixbuf.get_pixels (), pixbuf.get_has_alpha (), texture.set_from_rgb_data (pixbuf.get_pixels (), pixbuf.get_has_alpha (),
pixbuf.get_width (), pixbuf.get_height (), pixbuf.get_width (), pixbuf.get_height (),
pixbuf.get_rowstride (), (pixbuf.get_has_alpha () ? 4 : 3), 0); pixbuf.get_rowstride (), (pixbuf.get_has_alpha () ? 4 : 3), 0);
} catch (Error e) {} } catch (Error e) {}
} else { } else {
// we'll just make this red so there's at least something as an // we'll just make this red so there's at least something as an
// indicator that loading failed. Should never happen and this // indicator that loading failed. Should never happen and this
// works as good as some weird fallback-image-failed-to-load pixbuf // works as good as some weird fallback-image-failed-to-load pixbuf
var scale = Utils.get_ui_scaling_factor (); var scale = Utils.get_ui_scaling_factor ();
texture.set_size (36 * scale, 36 * scale); texture.set_size (36 * scale, 36 * scale);
texture.background_color = { 255, 0, 0, 255 }; texture.background_color = { 255, 0, 0, 255 };
} }
return texture; return texture;
} }
/** /**
* Returns the pixbuf that is used for resize buttons throughout gala at a * Returns the pixbuf that is used for resize buttons throughout gala at a
* size of 36px * size of 36px
* *
* @return the close button pixbuf or null if it failed to load * @return the close button pixbuf or null if it failed to load
*/ */
public static Gdk.Pixbuf? get_resize_button_pixbuf () public static Gdk.Pixbuf? get_resize_button_pixbuf () {
{ var height = 36 * Utils.get_ui_scaling_factor ();
var height = 36 * Utils.get_ui_scaling_factor (); if (resize_pixbuf == null || resize_pixbuf.height != height) {
if (resize_pixbuf == null || resize_pixbuf.height != height) { var scale = Utils.get_ui_scaling_factor ();
var scale = Utils.get_ui_scaling_factor (); try {
try { resize_pixbuf = new Gdk.Pixbuf.from_resource_at_scale (
resize_pixbuf = new Gdk.Pixbuf.from_resource_at_scale (Config.RESOURCEPATH + "/buttons/resize.svg", -1, height, true); Config.RESOURCEPATH + "/buttons/resize.svg",
} catch (Error e) { -1,
warning (e.message); height,
return null; true
} );
} } catch (Error e) {
warning (e.message);
return null;
}
}
return resize_pixbuf; return resize_pixbuf;
} }
/** /**
* Creates a new reactive ClutterActor at 36px with the resize pixbuf * Creates a new reactive ClutterActor at 36px with the resize pixbuf
* *
* @return The resize button actor * @return The resize button actor
*/ */
public static Clutter.Actor create_resize_button () public static Clutter.Actor create_resize_button () {
{ var texture = new Clutter.Texture ();
var texture = new Clutter.Texture (); var pixbuf = get_resize_button_pixbuf ();
var pixbuf = get_resize_button_pixbuf ();
texture.reactive = true; texture.reactive = true;
if (pixbuf != null) { if (pixbuf != null) {
try { try {
texture.set_from_rgb_data (pixbuf.get_pixels (), pixbuf.get_has_alpha (), texture.set_from_rgb_data (pixbuf.get_pixels (), pixbuf.get_has_alpha (),
pixbuf.get_width (), pixbuf.get_height (), pixbuf.get_width (), pixbuf.get_height (),
pixbuf.get_rowstride (), (pixbuf.get_has_alpha () ? 4 : 3), 0); pixbuf.get_rowstride (), (pixbuf.get_has_alpha () ? 4 : 3), 0);
} catch (Error e) {} } catch (Error e) {}
} else { } else {
// we'll just make this red so there's at least something as an // we'll just make this red so there's at least something as an
// indicator that loading failed. Should never happen and this // indicator that loading failed. Should never happen and this
// works as good as some weird fallback-image-failed-to-load pixbuf // works as good as some weird fallback-image-failed-to-load pixbuf
var scale = Utils.get_ui_scaling_factor (); var scale = Utils.get_ui_scaling_factor ();
texture.set_size (36 * scale, 36 * scale); texture.set_size (36 * scale, 36 * scale);
texture.background_color = { 255, 0, 0, 255 }; texture.background_color = { 255, 0, 0, 255 };
} }
return texture; return texture;
} }
static Gtk.CssProvider gala_css = null; static Gtk.CssProvider gala_css = null;
public static unowned Gtk.CssProvider? get_gala_css () public static unowned Gtk.CssProvider? get_gala_css () {
{ if (gala_css == null) {
if (gala_css == null) { gala_css = new Gtk.CssProvider ();
gala_css = new Gtk.CssProvider (); gala_css.load_from_resource ("/io/elementary/desktop/gala/gala.css");
gala_css.load_from_resource ("/io/elementary/desktop/gala/gala.css"); }
}
return gala_css; return gala_css;
} }
} }
} }

View File

@ -15,118 +15,109 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
namespace Gala namespace Gala {
{ /**
/** * Creates a new ClutterTexture with an icon for the window at the given size.
* Creates a new ClutterTexture with an icon for the window at the given size. * This is recommended way to grab an icon for a window as this method will make
* This is recommended way to grab an icon for a window as this method will make * sure the icon is updated if it becomes available at a later point.
* sure the icon is updated if it becomes available at a later point. */
*/ public class WindowIcon : Clutter.Texture {
public class WindowIcon : Clutter.Texture static Bamf.Matcher matcher;
{
static Bamf.Matcher matcher;
static construct static construct {
{ matcher = Bamf.Matcher.get_default ();
matcher = Bamf.Matcher.get_default (); }
}
public Meta.Window window { get; construct; } public Meta.Window window { get; construct; }
public int icon_size { get; construct; } public int icon_size { get; construct; }
public int scale { get; construct; } public int scale { get; construct; }
/** /**
* If set to true, the SafeWindowClone will destroy itself when the connected * If set to true, the SafeWindowClone will destroy itself when the connected
* window is unmanaged * window is unmanaged
*/ */
public bool destroy_on_unmanaged { public bool destroy_on_unmanaged {
get { get {
return _destroy_on_unmanaged; return _destroy_on_unmanaged;
} }
construct set { construct set {
if (_destroy_on_unmanaged == value) if (_destroy_on_unmanaged == value)
return; return;
_destroy_on_unmanaged = value; _destroy_on_unmanaged = value;
if (_destroy_on_unmanaged) if (_destroy_on_unmanaged)
window.unmanaged.connect (unmanaged); window.unmanaged.connect (unmanaged);
else else
window.unmanaged.disconnect (unmanaged); window.unmanaged.disconnect (unmanaged);
} }
} }
bool _destroy_on_unmanaged = false; bool _destroy_on_unmanaged = false;
bool loaded = false; bool loaded = false;
uint32 xid; uint32 xid;
/** /**
* Creates a new WindowIcon * Creates a new WindowIcon
* *
* @param window The window for which to create the icon * @param window The window for which to create the icon
* @param icon_size The size of the icon in pixels * @param icon_size The size of the icon in pixels
* @param scale The desired scale of the icon * @param scale The desired scale of the icon
* @param destroy_on_unmanaged see destroy_on_unmanaged property * @param destroy_on_unmanaged see destroy_on_unmanaged property
*/ */
public WindowIcon (Meta.Window window, int icon_size, int scale = 1, bool destroy_on_unmanaged = false) public WindowIcon (Meta.Window window, int icon_size, int scale = 1, bool destroy_on_unmanaged = false) {
{ Object (window: window,
Object (window: window, icon_size: icon_size,
icon_size: icon_size, destroy_on_unmanaged: destroy_on_unmanaged,
destroy_on_unmanaged: destroy_on_unmanaged, scale: scale);
scale: scale); }
}
construct construct {
{ width = icon_size * scale;
width = icon_size * scale; height = icon_size * scale;
height = icon_size * scale; xid = (uint32) window.get_xwindow ();
xid = (uint32) window.get_xwindow ();
// new windows often reach mutter earlier than bamf, that's why // new windows often reach mutter earlier than bamf, that's why
// we have to wait until the next window opens and hope that it's // we have to wait until the next window opens and hope that it's
// ours so we can get a proper icon instead of the default fallback. // ours so we can get a proper icon instead of the default fallback.
var app = matcher.get_application_for_xid (xid); var app = matcher.get_application_for_xid (xid);
if (app == null) if (app == null)
matcher.view_opened.connect (retry_load); matcher.view_opened.connect (retry_load);
else else
loaded = true; loaded = true;
update_texture (true); update_texture (true);
} }
~WindowIcon () ~WindowIcon () {
{ if (!loaded)
if (!loaded) matcher.view_opened.disconnect (retry_load);
matcher.view_opened.disconnect (retry_load); }
}
void retry_load (Bamf.View view) void retry_load (Bamf.View view) {
{ var app = matcher.get_application_for_xid (xid);
var app = matcher.get_application_for_xid (xid);
// retry only once // retry only once
loaded = true; loaded = true;
matcher.view_opened.disconnect (retry_load); matcher.view_opened.disconnect (retry_load);
if (app == null) if (app == null)
return; return;
update_texture (false); update_texture (false);
} }
void update_texture (bool initial) void update_texture (bool initial) {
{ var pixbuf = Gala.Utils.get_icon_for_xid (xid, icon_size, scale, !initial);
var pixbuf = Gala.Utils.get_icon_for_xid (xid, icon_size, scale, !initial);
try { try {
set_from_rgb_data (pixbuf.get_pixels (), pixbuf.get_has_alpha (), set_from_rgb_data (pixbuf.get_pixels (), pixbuf.get_has_alpha (),
pixbuf.get_width (), pixbuf.get_height (), pixbuf.get_width (), pixbuf.get_height (),
pixbuf.get_rowstride (), (pixbuf.get_has_alpha () ? 4 : 3), 0); pixbuf.get_rowstride (), (pixbuf.get_has_alpha () ? 4 : 3), 0);
} catch (Error e) {} } catch (Error e) {}
} }
void unmanaged (Meta.Window window) void unmanaged (Meta.Window window) {
{ destroy ();
destroy (); }
} }
}
} }

View File

@ -15,162 +15,155 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
namespace Gala namespace Gala {
{ public enum ActionType {
public enum ActionType NONE = 0,
{ SHOW_WORKSPACE_VIEW,
NONE = 0, MAXIMIZE_CURRENT,
SHOW_WORKSPACE_VIEW, MINIMIZE_CURRENT,
MAXIMIZE_CURRENT, OPEN_LAUNCHER,
MINIMIZE_CURRENT, CUSTOM_COMMAND,
OPEN_LAUNCHER, WINDOW_OVERVIEW,
CUSTOM_COMMAND, WINDOW_OVERVIEW_ALL,
WINDOW_OVERVIEW, SWITCH_TO_WORKSPACE_LAST,
WINDOW_OVERVIEW_ALL, START_MOVE_CURRENT,
SWITCH_TO_WORKSPACE_LAST, START_RESIZE_CURRENT,
START_MOVE_CURRENT, TOGGLE_ALWAYS_ON_TOP_CURRENT,
START_RESIZE_CURRENT, TOGGLE_ALWAYS_ON_VISIBLE_WORKSPACE_CURRENT,
TOGGLE_ALWAYS_ON_TOP_CURRENT, MOVE_CURRENT_WORKSPACE_LEFT,
TOGGLE_ALWAYS_ON_VISIBLE_WORKSPACE_CURRENT, MOVE_CURRENT_WORKSPACE_RIGHT,
MOVE_CURRENT_WORKSPACE_LEFT, CLOSE_CURRENT
MOVE_CURRENT_WORKSPACE_RIGHT, }
CLOSE_CURRENT
}
[Flags] [Flags]
public enum WindowFlags public enum WindowFlags {
{ NONE = 0,
NONE = 0, CAN_MINIMIZE,
CAN_MINIMIZE, CAN_MAXIMIZE,
CAN_MAXIMIZE, IS_MAXIMIZED,
IS_MAXIMIZED, ALLOWS_MOVE,
ALLOWS_MOVE, ALLOWS_RESIZE,
ALLOWS_RESIZE, ALWAYS_ON_TOP,
ALWAYS_ON_TOP, ON_ALL_WORKSPACES,
ON_ALL_WORKSPACES, CAN_CLOSE
CAN_CLOSE }
}
/** /**
* Function that should return true if the given shortcut should be blocked. * Function that should return true if the given shortcut should be blocked.
*/ */
public delegate bool KeybindingFilter (Meta.KeyBinding binding); public delegate bool KeybindingFilter (Meta.KeyBinding binding);
/** /**
* A minimal class mostly used to identify your call to {@link WindowManager.push_modal} and used * A minimal class mostly used to identify your call to {@link WindowManager.push_modal} and used
* to end your modal mode again with {@link WindowManager.pop_modal} * to end your modal mode again with {@link WindowManager.pop_modal}
*/ */
public class ModalProxy : Object public class ModalProxy : Object {
{ /**
/** * A function which is called whenever a keybinding is pressed. If you supply a custom
* A function which is called whenever a keybinding is pressed. If you supply a custom * one you can filter out those that'd you like to be passed through and block all others.
* one you can filter out those that'd you like to be passed through and block all others. * Defaults to blocking all.
* Defaults to blocking all. * @see KeybindingFilter
* @see KeybindingFilter */
*/ public KeybindingFilter? keybinding_filter { get; owned set; default = () => true; }
public KeybindingFilter? keybinding_filter { get; owned set; default = () => true; }
public ModalProxy () public ModalProxy () {
{ }
}
/** /**
* Small utility to allow all keybindings * Small utility to allow all keybindings
*/ */
public void allow_all_keybindings () public void allow_all_keybindings () {
{ keybinding_filter = null;
keybinding_filter = null; }
} }
}
public interface WindowManager : Meta.Plugin public interface WindowManager : Meta.Plugin {
{ /**
/** * This is the container you'll most likely want to add your component to. It wraps
* This is the container you'll most likely want to add your component to. It wraps * every other container listed in this interface and is a direct child of the stage.
* every other container listed in this interface and is a direct child of the stage. */
*/ public abstract Clutter.Actor ui_group { get; protected set; }
public abstract Clutter.Actor ui_group { get; protected set; }
/** /**
* The stage of the window manager * The stage of the window manager
*/ */
public abstract Clutter.Stage stage { get; protected set; } public abstract Clutter.Stage stage { get; protected set; }
/** /**
* A group containting all 'usual' windows * A group containting all 'usual' windows
* @see top_window_group * @see top_window_group
*/ */
public abstract Clutter.Actor window_group { get; protected set; } public abstract Clutter.Actor window_group { get; protected set; }
/** /**
* The top window group contains special windows that are always placed on top * The top window group contains special windows that are always placed on top
* like fullscreen windows. * like fullscreen windows.
*/ */
public abstract Clutter.Actor top_window_group { get; protected set; } public abstract Clutter.Actor top_window_group { get; protected set; }
/** /**
* The background group is a container for the background actors forming the wallpaper * The background group is a container for the background actors forming the wallpaper
*/ */
public abstract Meta.BackgroundGroup background_group { get; protected set; } public abstract Meta.BackgroundGroup background_group { get; protected set; }
/** /**
* Whether animations should be displayed. * Whether animations should be displayed.
*/ */
public abstract bool enable_animations { get; protected set; } public abstract bool enable_animations { get; protected set; }
/** /**
* Enters the modal mode, which means that all events are directed to the stage instead * Enters the modal mode, which means that all events are directed to the stage instead
* of the windows. This is the only way to receive keyboard events besides shortcut listeners. * of the windows. This is the only way to receive keyboard events besides shortcut listeners.
* *
* @return a {@link ModalProxy} which is needed to end the modal mode again and provides some * @return a {@link ModalProxy} which is needed to end the modal mode again and provides some
* some basic control on the behavior of the window manager while it is in modal mode. * some basic control on the behavior of the window manager while it is in modal mode.
*/ */
public abstract ModalProxy push_modal (); public abstract ModalProxy push_modal ();
/** /**
* May exit the modal mode again, unless another component has called {@link push_modal} * May exit the modal mode again, unless another component has called {@link push_modal}
* *
* @param proxy The {@link ModalProxy} received from {@link push_modal} * @param proxy The {@link ModalProxy} received from {@link push_modal}
*/ */
public abstract void pop_modal (ModalProxy proxy); public abstract void pop_modal (ModalProxy proxy);
/** /**
* Returns whether the window manager is currently in modal mode. * Returns whether the window manager is currently in modal mode.
* @see push_modal * @see push_modal
*/ */
public abstract bool is_modal (); public abstract bool is_modal ();
/** /**
* Tests if a given {@link ModalProxy} is valid and may be popped. Should not be necessary * Tests if a given {@link ModalProxy} is valid and may be popped. Should not be necessary
* to use this function in most cases, but it may be helpful for debugging. Gala catches * to use this function in most cases, but it may be helpful for debugging. Gala catches
* invalid proxies as well and emits a warning in that case. * invalid proxies as well and emits a warning in that case.
* *
* @param proxy The {@link ModalProxy} to check * @param proxy The {@link ModalProxy} to check
* @return Returns true if the prox is valid * @return Returns true if the prox is valid
*/ */
public abstract bool modal_proxy_valid (ModalProxy proxy); public abstract bool modal_proxy_valid (ModalProxy proxy);
/** /**
* Tells the window manager to perform the given action. * Tells the window manager to perform the given action.
* *
* @param type The type of action to perform * @param type The type of action to perform
*/ */
public abstract void perform_action (ActionType type); public abstract void perform_action (ActionType type);
/** /**
* Moves the window to the workspace next to its current workspace in the given direction. * Moves the window to the workspace next to its current workspace in the given direction.
* Gala currently only supports LEFT and RIGHT. * Gala currently only supports LEFT and RIGHT.
* *
* @param window The window to be moved * @param window The window to be moved
* @param direction The direction in which to move the window * @param direction The direction in which to move the window
*/ */
public abstract void move_window (Meta.Window? window, Meta.MotionDirection direction); public abstract void move_window (Meta.Window? window, Meta.MotionDirection direction);
/** /**
* Switches to the next workspace in the given direction. * Switches to the next workspace in the given direction.
* *
* @param direction The direction in which to switch * @param direction The direction in which to switch
*/ */
public abstract void switch_to_next_workspace (Meta.MotionDirection direction); public abstract void switch_to_next_workspace (Meta.MotionDirection direction);
} }
} }