mirror of
https://github.com/elementary/gala.git
synced 2024-11-27 15:45:31 +03:00
228 lines
7.6 KiB
Vala
228 lines
7.6 KiB
Vala
//
|
|
// Copyright (C) 2014 Tom Beckmann
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
//
|
|
|
|
namespace Gala {
|
|
public enum PluginFunction {
|
|
ADDITION,
|
|
WINDOW_SWITCHER,
|
|
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 struct PluginInfo {
|
|
string name;
|
|
string author;
|
|
|
|
/**
|
|
* 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;
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
/**
|
|
* 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.
|
|
*/
|
|
#if HAS_MUTTER45
|
|
private Mtk.Rectangle[] region;
|
|
public unowned Mtk.Rectangle[] get_region () {
|
|
#else
|
|
private Meta.Rectangle[] region;
|
|
public unowned Meta.Rectangle[] get_region () {
|
|
#endif
|
|
return 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.
|
|
*/
|
|
#if HAS_MUTTER45
|
|
private Mtk.Rectangle[]? _custom_region = null;
|
|
protected unowned Mtk.Rectangle[]? get_custom_region () {
|
|
#else
|
|
private Meta.Rectangle[]? _custom_region = null;
|
|
protected unowned Meta.Rectangle[]? get_custom_region () {
|
|
#endif
|
|
return _custom_region;
|
|
}
|
|
#if HAS_MUTTER45
|
|
protected void set_custom_region (Mtk.Rectangle[]? custom_region) {
|
|
#else
|
|
protected void set_custom_region (Meta.Rectangle[]? custom_region) {
|
|
#endif
|
|
_custom_region = custom_region;
|
|
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;
|
|
|
|
if (!_freeze_track)
|
|
update_region ();
|
|
}
|
|
}
|
|
|
|
private bool _freeze_track = false;
|
|
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);
|
|
|
|
/**
|
|
* 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.notify["allocation"].connect (on_actor_allocation_changed);
|
|
|
|
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.notify["allocation"].disconnect (on_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 () {
|
|
unowned var custom_region = get_custom_region ();
|
|
var has_custom = custom_region != null;
|
|
var len = tracked_actors.length () + (has_custom ? custom_region.length : 0);
|
|
|
|
#if HAS_MUTTER45
|
|
var regions = new Mtk.Rectangle[len];
|
|
#else
|
|
var regions = new Meta.Rectangle[len];
|
|
#endif
|
|
var i = 0;
|
|
|
|
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);
|
|
|
|
if (w == 0 || h == 0)
|
|
continue;
|
|
|
|
regions[i++] = { (int) x, (int) y, (int) w, (int) h };
|
|
}
|
|
|
|
region = regions;
|
|
|
|
region_changed ();
|
|
}
|
|
|
|
private void on_actor_allocation_changed (GLib.Object actor_object, GLib.ParamSpec pspec) {
|
|
if (!freeze_track)
|
|
update_region ();
|
|
}
|
|
}
|
|
}
|