👕 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/>.
//
namespace Gala
{
/**
* Implement this interface on your {@link Plugin} class if you want to
* replace a component like the window overview or the multitasking view.
* It allows gala to hook up functionality like hotcorners and dbus
* invocation of your component.
*/
public interface ActivatableComponent : Object
{
/**
* 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
* 'all-windows' hint to the windowoverview.
*/
public abstract void open (HashTable<string,Variant>? hints = null);
namespace Gala {
/**
* Implement this interface on your {@link Plugin} class if you want to
* replace a component like the window overview or the multitasking view.
* It allows gala to hook up functionality like hotcorners and dbus
* invocation of your component.
*/
public interface ActivatableComponent : Object {
/**
* 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
* 'all-windows' hint to the windowoverview.
*/
public abstract void open (HashTable<string,Variant>? hints = null);
/**
* The component was requested to be closed.
*/
public abstract void close ();
/**
* The component was requested to be closed.
*/
public abstract void close ();
/**
* Should return whether the component is currently opened. Used mainly for
* toggling by the window manager.
*
* @return Return true if the component is opened.
*/
public abstract bool is_opened ();
}
/**
* Should return whether the component is currently opened. Used mainly for
* toggling by the window manager.
*
* @return Return true if the component 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/>.
//
namespace Gala
{
[CCode (has_type_id = false)]
public enum AnimationDuration {
// Duration of the open animation
OPEN = 350,
// Duration of the close animation
CLOSE = 195,
// Duration of the minimize animation
MINIMIZE = 200,
// Duration of the menu mapping animation
MENU_MAP = 150,
// Duration of the snap animation as used by maximize/unmaximize
SNAP = 250,
// Duration of the workspace switch animation
WORKSPACE_SWITCH = 300,
}
namespace Gala {
[CCode (has_type_id = false)]
public enum AnimationDuration {
// Duration of the open animation
OPEN = 350,
// Duration of the close animation
CLOSE = 195,
// Duration of the minimize animation
MINIMIZE = 200,
// Duration of the menu mapping animation
MENU_MAP = 150,
// Duration of the snap animation as used by maximize/unmaximize
SNAP = 250,
// Duration of the workspace switch animation
WORKSPACE_SWITCH = 300,
}
}

View File

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

View File

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

View File

@ -15,162 +15,155 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
namespace Gala
{
public enum ActionType
{
NONE = 0,
SHOW_WORKSPACE_VIEW,
MAXIMIZE_CURRENT,
MINIMIZE_CURRENT,
OPEN_LAUNCHER,
CUSTOM_COMMAND,
WINDOW_OVERVIEW,
WINDOW_OVERVIEW_ALL,
SWITCH_TO_WORKSPACE_LAST,
START_MOVE_CURRENT,
START_RESIZE_CURRENT,
TOGGLE_ALWAYS_ON_TOP_CURRENT,
TOGGLE_ALWAYS_ON_VISIBLE_WORKSPACE_CURRENT,
MOVE_CURRENT_WORKSPACE_LEFT,
MOVE_CURRENT_WORKSPACE_RIGHT,
CLOSE_CURRENT
}
namespace Gala {
public enum ActionType {
NONE = 0,
SHOW_WORKSPACE_VIEW,
MAXIMIZE_CURRENT,
MINIMIZE_CURRENT,
OPEN_LAUNCHER,
CUSTOM_COMMAND,
WINDOW_OVERVIEW,
WINDOW_OVERVIEW_ALL,
SWITCH_TO_WORKSPACE_LAST,
START_MOVE_CURRENT,
START_RESIZE_CURRENT,
TOGGLE_ALWAYS_ON_TOP_CURRENT,
TOGGLE_ALWAYS_ON_VISIBLE_WORKSPACE_CURRENT,
MOVE_CURRENT_WORKSPACE_LEFT,
MOVE_CURRENT_WORKSPACE_RIGHT,
CLOSE_CURRENT
}
[Flags]
public enum WindowFlags
{
NONE = 0,
CAN_MINIMIZE,
CAN_MAXIMIZE,
IS_MAXIMIZED,
ALLOWS_MOVE,
ALLOWS_RESIZE,
ALWAYS_ON_TOP,
ON_ALL_WORKSPACES,
CAN_CLOSE
}
[Flags]
public enum WindowFlags {
NONE = 0,
CAN_MINIMIZE,
CAN_MAXIMIZE,
IS_MAXIMIZED,
ALLOWS_MOVE,
ALLOWS_RESIZE,
ALWAYS_ON_TOP,
ON_ALL_WORKSPACES,
CAN_CLOSE
}
/**
* Function that should return true if the given shortcut should be blocked.
*/
public delegate bool KeybindingFilter (Meta.KeyBinding binding);
/**
* Function that should return true if the given shortcut should be blocked.
*/
public delegate bool KeybindingFilter (Meta.KeyBinding binding);
/**
* 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}
*/
public class ModalProxy : Object
{
/**
* 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.
* Defaults to blocking all.
* @see KeybindingFilter
*/
public KeybindingFilter? keybinding_filter { get; owned set; default = () => true; }
/**
* 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}
*/
public class ModalProxy : Object {
/**
* 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.
* Defaults to blocking all.
* @see KeybindingFilter
*/
public KeybindingFilter? keybinding_filter { get; owned set; default = () => true; }
public ModalProxy ()
{
}
public ModalProxy () {
}
/**
* Small utility to allow all keybindings
*/
public void allow_all_keybindings ()
{
keybinding_filter = null;
}
}
/**
* Small utility to allow all keybindings
*/
public void allow_all_keybindings () {
keybinding_filter = null;
}
}
public interface WindowManager : Meta.Plugin
{
/**
* 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.
*/
public abstract Clutter.Actor ui_group { get; protected set; }
public interface WindowManager : Meta.Plugin {
/**
* 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.
*/
public abstract Clutter.Actor ui_group { get; protected set; }
/**
* The stage of the window manager
*/
public abstract Clutter.Stage stage { get; protected set; }
/**
* The stage of the window manager
*/
public abstract Clutter.Stage stage { get; protected set; }
/**
* A group containting all 'usual' windows
* @see top_window_group
*/
public abstract Clutter.Actor window_group { get; protected set; }
/**
* A group containting all 'usual' windows
* @see top_window_group
*/
public abstract Clutter.Actor window_group { get; protected set; }
/**
* The top window group contains special windows that are always placed on top
* like fullscreen windows.
*/
public abstract Clutter.Actor top_window_group { get; protected set; }
/**
* The top window group contains special windows that are always placed on top
* like fullscreen windows.
*/
public abstract Clutter.Actor top_window_group { get; protected set; }
/**
* The background group is a container for the background actors forming the wallpaper
*/
public abstract Meta.BackgroundGroup background_group { get; protected set; }
/**
* The background group is a container for the background actors forming the wallpaper
*/
public abstract Meta.BackgroundGroup background_group { get; protected set; }
/**
* Whether animations should be displayed.
*/
public abstract bool enable_animations { get; protected set; }
/**
* Whether animations should be displayed.
*/
public abstract bool enable_animations { get; protected set; }
/**
* 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.
*
* @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.
*/
public abstract ModalProxy push_modal ();
/**
* 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.
*
* @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.
*/
public abstract ModalProxy 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}
*/
public abstract void pop_modal (ModalProxy proxy);
/**
* May exit the modal mode again, unless another component has called {@link push_modal}
*
* @param proxy The {@link ModalProxy} received from {@link push_modal}
*/
public abstract void pop_modal (ModalProxy proxy);
/**
* Returns whether the window manager is currently in modal mode.
* @see push_modal
*/
public abstract bool is_modal ();
/**
* Returns whether the window manager is currently in modal mode.
* @see push_modal
*/
public abstract bool is_modal ();
/**
* 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
* invalid proxies as well and emits a warning in that case.
*
* @param proxy The {@link ModalProxy} to check
* @return Returns true if the prox is valid
*/
public abstract bool modal_proxy_valid (ModalProxy proxy);
/**
* 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
* invalid proxies as well and emits a warning in that case.
*
* @param proxy The {@link ModalProxy} to check
* @return Returns true if the prox is valid
*/
public abstract bool modal_proxy_valid (ModalProxy proxy);
/**
* Tells the window manager to perform the given action.
*
* @param type The type of action to perform
*/
public abstract void perform_action (ActionType type);
/**
* Tells the window manager to perform the given action.
*
* @param type The type of action to perform
*/
public abstract void perform_action (ActionType type);
/**
* Moves the window to the workspace next to its current workspace in the given direction.
* Gala currently only supports LEFT and RIGHT.
*
* @param window The window to be moved
* @param direction The direction in which to move the window
*/
public abstract void move_window (Meta.Window? window, Meta.MotionDirection direction);
/**
* Moves the window to the workspace next to its current workspace in the given direction.
* Gala currently only supports LEFT and RIGHT.
*
* @param window The window to be moved
* @param direction The direction in which to move the window
*/
public abstract void move_window (Meta.Window? window, Meta.MotionDirection direction);
/**
* Switches to the next workspace in the given direction.
*
* @param direction The direction in which to switch
*/
public abstract void switch_to_next_workspace (Meta.MotionDirection direction);
}
/**
* Switches to the next workspace in the given direction.
*
* @param direction The direction in which to switch
*/
public abstract void switch_to_next_workspace (Meta.MotionDirection direction);
}
}