mirror of
https://github.com/elementary/gala.git
synced 2024-09-11 07:05:30 +03:00
👕 Lint lib directory with vala-lint (#607)
This commit is contained in:
parent
50694796d4
commit
49d1d8ffab
@ -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 ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
342
lib/Plugin.vala
342
lib/Plugin.vala
@ -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 ();
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
665
lib/Utils.vala
665
lib/Utils.vala
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 ();
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user