2019-11-07 11:50:44 +01:00
/* vim: set tabstop=2:softtabstop=2:shiftwidth=2:noexpandtab */
// modules: Gtk Gdk X Posix
2011-10-13 19:15:00 +02:00
using Gtk ;
using Gdk ;
using X ; //keysym.h
2019-11-07 11:50:44 +01:00
using Posix ; //system-calls
using Cairo ;
2011-10-13 19:15:00 +02:00
2013-09-18 20:32:40 +02:00
namespace NeoLayoutViewer {
2011-10-13 19:15:00 +02:00
2019-11-06 21:04:59 +01:00
errordomain PositionArrayParsingError {
CODE_1A
}
2013-09-18 20:32:40 +02:00
public class Modkey {
2011-10-17 20:38:29 +02:00
public Gtk . Image modKeyImage ;
public int modifier_index ;
public int active ;
2019-11-07 11:50:44 +01:00
public Modkey ( Gtk . Image i , int m ) {
2011-10-17 20:38:29 +02:00
this . modKeyImage = i ;
this . modifier_index = m ;
this . active = 0 ;
}
2013-09-18 20:32:40 +02:00
public void change ( int new_state ) {
if ( new_state = = this . active ) return ;
2011-10-17 20:38:29 +02:00
this . active = new_state ;
2013-09-18 20:32:40 +02:00
if ( this . active = = 0 ) {
2011-10-17 20:38:29 +02:00
modKeyImage . hide ( ) ;
2019-11-12 16:10:04 +01:00
} else {
2011-10-17 20:38:29 +02:00
modKeyImage . show ( ) ;
}
}
}
2019-01-25 03:22:18 +01:00
public class NeoWindow : Gtk . ApplicationWindow {
2011-10-13 19:15:00 +02:00
2019-11-07 11:50:44 +01:00
private ScalingImage image ;
# if _NO_WIN
private KeyOverlay key_overlay ;
# endif
2020-06-08 20:49:48 +02:00
public string layoutType ; // = "NEO2";
2020-06-07 23:34:22 +02:00
2019-11-07 11:50:44 +01:00
public Gee . Map < string , Gdk . Pixbuf > image_buffer ;
private Gdk . Pixbuf [ ] layer_pixbufs ;
2019-11-12 15:32:35 +01:00
private int monitor_id = - 1 ;
private Gee . Map < int , Size > size_for_monitor ;
2019-11-07 11:50:44 +01:00
2011-10-17 20:38:29 +02:00
public Gee . List < Modkey > modifier_key_images ; // for modifier which didn't toggle a layout layer. I.e. ctrl, alt.
2011-10-21 00:45:41 +02:00
public Gee . Map < string , string > config ;
2011-10-13 19:15:00 +02:00
2020-06-14 00:00:04 +02:00
public int fixed_layer { get ; set ; }
2019-01-25 03:22:18 +01:00
private int _layer = 1 ;
public int layer {
get { return _layer ; }
2020-06-14 00:00:04 +02:00
set {
if ( value < 1 | | value > 6 ) { _layer = 1 ; } else { _layer = value ; }
}
2019-01-25 03:22:18 +01:00
}
2011-10-16 19:09:33 +02:00
public int [ ] active_modifier_by_keyboard ;
public int [ ] active_modifier_by_mouse ;
2011-10-17 15:17:34 +02:00
public int numpad_width ;
2011-10-17 20:38:29 +02:00
public int function_keys_height ;
2020-06-14 00:00:04 +02:00
private bool _minimized ;
public bool minimized { get { return _minimized ; } }
2011-10-13 19:15:00 +02:00
private int position_num ;
private int [ ] position_cycle ;
2011-10-18 09:46:19 +02:00
private int position_on_hide_x ;
private int position_on_hide_y ;
2011-10-21 00:37:43 +02:00
private int screen_dim [ 2 ] ;
private bool screen_dim_auto [ 2 ] ; //if true, x/y screen dimension will detect on every show event.
2019-11-12 15:32:35 +01:00
private bool already_shown_on_monitor1 ; // flag to prevent first hide()-call during monitor cycle in some cases.
2011-10-13 19:15:00 +02:00
2011-10-17 20:38:29 +02:00
/* Die Neo-Modifier unterscheiden sich zum Teil von den Normalen, für die Konstanten definiert sind. Bei der Initialisierung werden aus den Standardkonstanen die Konstanten für die Ebenen 1-6 berechnet.*/
2011-10-13 19:15:00 +02:00
public int [ ] NEO_MODIFIER_MASK ;
public int [ ] MODIFIER_MASK ;
2011-10-14 22:10:11 +02:00
/* Falls ein Modifier (oder eine andere Taste) gedrückt wird und schon Modifier gedrückt sind, gibt die Map an, welche Ebene dann aktiviert ist. */
2011-10-13 19:15:00 +02:00
private short [ , ] MODIFIER_MAP = {
2019-01-25 03:22:18 +01:00
{ 0 , 1 , 2 , 3 , 4 , 5 } ,
{ 1 , 1 , 4 , 3 , 4 , 5 } ,
{ 2 , 4 , 2 , 5 , 4 , 5 } ,
{ 3 , 3 , 5 , 3 , 4 , 5 } } ;
2011-10-13 19:15:00 +02:00
2019-01-25 03:22:18 +01:00
/ * [ 0 , 1 ] ^ 3 - > { 0 , 5 } , Bildet aktive Modifier auf angezeigte Ebene ab .
Interpretationsreihenfolge der Dimensionen : Shift , Neo - Mod3 , Neo - Mod4 . * /
2011-10-13 19:15:00 +02:00
private short [ , , ] MODIFIER_MAP2 = {
2011-10-14 22:10:11 +02:00
{ { 0 , 3 } , { 2 , 5 } } , // 000, 001; 010, 011
2020-06-10 09:06:19 +02:00
{ { 1 , 3 } , { 4 , 5 } } // 100, 101; 110, 111
2011-10-13 19:15:00 +02:00
} ;
2019-01-25 03:22:18 +01:00
/* {0, 5} -> [0, 1]^3 */
private short [ , ] LAYER_TO_MODIFIERS = {
{ 0 , 0 , 0 } , // 0
{ 1 , 0 , 0 } , // 1
{ 0 , 1 , 0 } , // 2
{ 0 , 0 , 1 } , // 3
{ 1 , 1 , 0 } , // 4
{ 1 , 1 , 1 } // 5
} ;
2011-10-14 22:10:11 +02:00
/ * Analog zu oben für den Fall , dass eine Taste losgelassen wird . Funktioniert nicht immer .
2011-10-17 20:38:29 +02:00
Ist beispielsweise ShiftL und ShiftR gedrückt und eine wird losgelassen , so wechselt die Anzeige zur ersten Ebene .
2011-10-14 22:10:11 +02:00
Die Fehler sind imo zu vernachlässigen .
* /
2011-10-13 19:15:00 +02:00
private short [ , ] MODIFIER_MAP_RELEASE = {
2019-01-25 03:22:18 +01:00
{ 0 , 0 , 0 , 0 , 0 , 0 } ,
{ 0 , 0 , 2 , 3 , 2 , 5 } ,
{ 0 , 1 , 0 , 3 , 1 , 3 } ,
{ 0 , 1 , 2 , 0 , 4 , 2 } } ;
2011-10-13 19:15:00 +02:00
2017-11-12 12:59:17 +01:00
/ *
Modifier können per Tastatur und Maus aktiviert werden . Diese Abbildung entscheidet ,
wie bei einer Zustandsänderung verfahren werden soll .
2019-01-25 03:22:18 +01:00
k , m , K , M ∈ { 0 , 1 } .
2017-11-12 12:59:17 +01:00
k - Taste wurde gedrückt gehalten
m - Taste wurde per Mausklick selektiert .
K - Taste wird gedrückt
M - Taste wird per Mausklick selektiert .
2019-01-25 03:22:18 +01:00
k ' = f ( k , m , K , M ) . Und wegen der Symmetrie ( ! )
m ' = f ( m , k , M , K )
2017-11-12 12:59:17 +01:00
Siehe auch change_active_modifier ( … ) .
* /
2011-10-16 19:09:33 +02:00
private short [ , , , ] MODIFIER_KEYBOARD_MOUSE_MAP = {
2019-01-25 03:22:18 +01:00
// k = f(k, m, K, M, ) and m = f(m, k, M, K)
{ { { 0 , 0 } , { 1 , 0 } } , // 0000, 0001; 0010, 0011;
{ { 0 , 0 } , { 1 , 1 } } } , // 0100, 0101; 0110, 0111(=swap);
2011-10-16 19:09:33 +02:00
{ { { 0 , 0 } , { 1 , 0 } } , //1000, 1001; 1010, 1011(=swap);
{ { 0 , 0 } , { 1 , 1 } } } //1100, 1101; 1110, 1111; //k=m=1 should be impossible
} ;
2011-10-16 19:14:47 +02:00
2020-06-14 00:00:04 +02:00
public NeoWindow ( ConfigManager configm , NeoLayoutViewerApp app ) {
//this.config = app.configm.getConfig();
this . config = configm . getConfig ( ) ;
this . _minimized = true ;
2011-10-14 22:10:11 +02:00
2020-06-14 00:00:04 +02:00
this . layoutType = this . config . get ( " layout_type " ) ;
2020-06-07 23:34:22 +02:00
2019-11-07 11:50:44 +01:00
/ * Set window type to let tiling window manager , i . e . i3 - wm ,
* the chance to float the window automatically .
2014-06-09 22:44:45 +02:00
* /
this . type_hint = Gdk . WindowTypeHint . UTILITY ;
2011-10-13 19:15:00 +02:00
this . NEO_MODIFIER_MASK = {
0 ,
Gdk . ModifierType . SHIFT_MASK , //1
Gdk . ModifierType . MOD5_MASK + Gdk . ModifierType . LOCK_MASK , //128+2
Gdk . ModifierType . MOD3_MASK , //32
Gdk . ModifierType . MOD5_MASK + Gdk . ModifierType . LOCK_MASK + Gdk . ModifierType . SHIFT_MASK , //128+2+1
Gdk . ModifierType . MOD5_MASK + Gdk . ModifierType . LOCK_MASK + Gdk . ModifierType . MOD3_MASK //128+2+32
} ;
this . MODIFIER_MASK = {
2011-10-14 22:10:11 +02:00
0 ,
Gdk . ModifierType . SHIFT_MASK , //1
2019-01-25 03:22:18 +01:00
Gdk . ModifierType . MOD5_MASK , //128
2011-10-14 22:10:11 +02:00
Gdk . ModifierType . MOD3_MASK , //32
Gdk . ModifierType . CONTROL_MASK ,
Gdk . ModifierType . MOD1_MASK // Alt-Mask do not work :-(
2011-10-13 19:15:00 +02:00
} ;
2019-01-25 03:22:18 +01:00
this . active_modifier_by_keyboard = { 0 , 0 , 0 , 0 , 0 , 0 } ;
this . active_modifier_by_mouse = { 0 , 0 , 0 , 0 , 0 , 0 } ;
2011-10-13 19:15:00 +02:00
2019-11-06 21:04:59 +01:00
this . modifier_key_images = new Gee . ArrayList < Modkey > ( ) ;
this . position_num = int . min ( 200 , int . max ( int . parse ( this . config . get ( " position " ) ) , 1 ) ) ;
2019-11-12 15:32:35 +01:00
this . already_shown_on_monitor1 = ( this . position_num < 10
& & this . config . get ( " show_on_startup " ) ! = " 0 " ) ;
this . size_for_monitor = new Gee . HashMap < int , Size > ( ) ;
this . check_resize . connect ( main_resized ) ;
2013-09-13 20:22:53 +02:00
2011-10-13 19:15:00 +02:00
//Anlegen des Arrays, welches den Positionsdurchlauf beschreibt.
2013-09-18 20:32:40 +02:00
try {
2019-11-06 21:04:59 +01:00
//var space = new Regex(" ");
//string[] split = space.split(this.config.get("position_cycle"));
var non_numeral = new Regex ( " [^0-9]+ " ) ;
string [ ] split = non_numeral . split ( this . config . get ( " position_cycle " ) ) ;
/ * Create array which can hold the parsed integers , but also some
2019-11-07 11:50:44 +01:00
unused indizes ( 0 th . entry , 10 th entry , … )
* /
2019-11-06 21:04:59 +01:00
var min_len = ( ( position_num - 1 ) / 10 + 1 ) * 10 ;
position_cycle = new int [ int . max ( min_len , ( ( split . length - 1 ) / 10 + 1 ) * 10 ) ] ; // multiple of 10 and > 0
GLib . assert ( position_cycle . length / 10 > = split . length / 9 ) ;
// Prefill with default values. Call is not redundant!
debug ( @" Cycle array length: $(position_cycle.length) " ) ;
fill_position_cycle_default ( ref position_cycle ) ;
// Read positions from config string
int j = 1 ;
//position_cycle[0] = -1; // already set in fill_position_cycle_default(...)
2013-09-18 20:32:40 +02:00
for ( int i = 0 ; i < split . length ; i + + ) {
2019-11-06 21:04:59 +01:00
// Valid range: [1, 10*number_of_monitors - 1]
position_cycle [ j ] = int . max ( int . min ( int . parse ( split [ i ] ) , position_cycle . length - 1 ) , 1 ) ;
2019-11-12 16:10:04 +01:00
if ( position_cycle [ j ] = = 0 ) {
2019-11-06 21:04:59 +01:00
// Invalid number parsed (or parsing failed). Print error message and use predefined array
GLib . stdout . printf ( " Position cycle reading failed. Problematic value: $(split[i]) \n " ) ;
throw new PositionArrayParsingError . CODE_1A ( " Unexpected Integer " ) ;
}
GLib . assert ( position_cycle [ j ] > 0 ) ;
j + + ;
2019-11-12 16:10:04 +01:00
if ( j % 10 = = 0 ) { j + + ; }
2011-10-14 22:10:11 +02:00
}
2019-11-06 21:04:59 +01:00
} catch ( PositionArrayParsingError e ) {
fill_position_cycle_default ( ref position_cycle ) ;
2011-10-13 19:15:00 +02:00
} catch ( RegexError e ) {
2019-11-06 21:04:59 +01:00
fill_position_cycle_default ( ref position_cycle ) ;
2011-10-13 19:15:00 +02:00
}
2019-11-12 16:10:04 +01:00
debug ( " Position cycle map: " ) ;
2019-11-07 11:50:44 +01:00
for ( int i = 0 ; i < position_cycle . length ; i + + ) {
2019-11-12 16:10:04 +01:00
debug ( @" $(i)=> $(position_cycle[i]) " ) ;
2019-11-07 11:50:44 +01:00
}
2011-10-13 19:15:00 +02:00
2020-06-14 00:00:04 +02:00
if ( this . fixed_layer > 0 & & this . fixed_layer < = 6 ) {
for ( int i = 0 ; i < 3 ; i + + ) {
this . active_modifier_by_mouse [ i + 1 ] = this . LAYER_TO_MODIFIERS [ this . layer - 1 , i ] ;
}
2019-01-25 03:22:18 +01:00
}
2017-11-17 16:56:34 +01:00
// Crawl dimensions of screen/display/monitor
2019-11-07 11:50:44 +01:00
// Should be done before load_images() is called.
2019-01-25 03:22:18 +01:00
screen_dim_auto [ 0 ] = ( this . config . get ( " screen_width " ) = = " auto " ) ;
screen_dim_auto [ 1 ] = ( this . config . get ( " screen_height " ) = = " auto " ) ;
2017-11-17 16:56:34 +01:00
if ( screen_dim_auto [ 0 ] ) {
this . screen_dim [ 0 ] = this . get_screen_width ( ) ;
this . screen_dim_auto [ 0 ] = false ; // Disables further re-evaluations
} else {
2019-01-25 03:22:18 +01:00
this . screen_dim [ 0 ] = int . max ( 1 , int . parse ( this . config . get ( " screen_width " ) ) ) ;
2017-11-17 16:56:34 +01:00
}
2019-11-12 16:10:04 +01:00
if ( screen_dim_auto [ 1 ] ) {
2017-11-17 16:56:34 +01:00
this . screen_dim [ 1 ] = this . get_screen_height ( ) ;
this . screen_dim_auto [ 1 ] = false ; // Disables further re-evaluations
} else {
2019-01-25 03:22:18 +01:00
this . screen_dim [ 1 ] = int . max ( 1 , int . parse ( this . config . get ( " screen_height " ) ) ) ;
2017-11-17 16:56:34 +01:00
}
2019-11-07 11:50:44 +01:00
// Load pngs of all six layers, etc
this . image_buffer = new Gee . HashMap < string , Gdk . Pixbuf > ( ) ;
this . load_images ( ) ;
this . layer_pixbufs = {
this . image_buffer [ " unscaled_1 " ] ,
this . image_buffer [ " unscaled_2 " ] ,
this . image_buffer [ " unscaled_3 " ] ,
this . image_buffer [ " unscaled_4 " ] ,
this . image_buffer [ " unscaled_5 " ] ,
this . image_buffer [ " unscaled_6 " ] ,
} ;
// Setup background image.
int backgroundW_unscaled = this . get_unscaled_width ( ) ;
int backgroundH_unscaled = this . get_unscaled_height ( ) ;
this . image = new ScalingImage (
backgroundW_unscaled , backgroundH_unscaled ,
this , backgroundW_unscaled , backgroundH_unscaled ,
layer_pixbufs , 0 ) ;
2017-11-17 16:56:34 +01:00
2019-11-12 15:32:35 +01:00
this . monitor_id = this . position_num / 10 ;
2011-10-17 20:38:29 +02:00
2019-11-07 11:50:44 +01:00
// Setup startup size of window
2019-11-12 15:32:35 +01:00
int win_width = get_image_width_for_monitor ( this . screen_dim [ 0 ] ) ;
2019-11-07 11:50:44 +01:00
int win_height = ( backgroundH_unscaled * win_width ) / backgroundW_unscaled ;
2019-11-12 12:45:16 +01:00
//this.set_size_request(1, 1);
2019-11-07 11:50:44 +01:00
this . resize ( win_width , win_height ) ;
2019-11-12 12:45:16 +01:00
this . set_default_size ( win_width , win_height ) ;
2017-11-17 16:56:34 +01:00
2011-10-17 20:38:29 +02:00
image . show ( ) ;
2019-11-12 12:45:16 +01:00
var layout = new Layout ( ) ;
layout . put ( this . image , 0 , 0 ) ;
2017-11-17 16:56:34 +01:00
# if _NO_WIN
2019-11-07 11:50:44 +01:00
this . key_overlay = new KeyOverlay ( this ) ;
this . key_overlay . show ( ) ;
2019-11-12 12:45:16 +01:00
layout . put ( this . key_overlay , 0 , 0 ) ;
2017-11-17 16:56:34 +01:00
# endif
2011-10-13 19:15:00 +02:00
2019-11-12 12:45:16 +01:00
add ( layout ) ;
layout . show ( ) ;
2011-10-17 20:38:29 +02:00
2011-10-13 19:15:00 +02:00
//Fenstereigenschaften setzen
2013-09-18 20:32:40 +02:00
this . key_press_event . connect ( on_key_pressed ) ;
this . button_press_event . connect ( on_button_pressed ) ;
2019-01-25 03:22:18 +01:00
this . destroy . connect ( NeoLayoutViewer . quit ) ;
2011-10-13 19:15:00 +02:00
2017-11-17 16:56:34 +01:00
//this.set_gravity(Gdk.Gravity.SOUTH);
2019-01-25 03:22:18 +01:00
this . decorated = ( this . config . get ( " window_decoration " ) ! = " 0 " ) ;
2011-10-13 19:15:00 +02:00
this . skip_taskbar_hint = true ;
//Icon des Fensters
2019-11-07 11:50:44 +01:00
this . icon = this . image_buffer [ " icon " ] ;
2011-10-13 19:15:00 +02:00
//Nicht selektierbar (für virtuelle Tastatur)
2019-01-25 03:22:18 +01:00
this . set_accept_focus ( ( this . config . get ( " window_selectable " ) ! = " 0 " ) ) ;
2011-10-16 19:14:47 +02:00
2019-11-12 16:10:04 +01:00
if ( this . config . get ( " show_on_startup " ) ! = " 0 " ) {
2013-12-08 01:09:00 +01:00
//Move ist erst nach show() erfolgreich
2019-11-12 15:32:35 +01:00
//this.numkeypad_move(int.parse(this.config.get("position")));
this . numkeypad_move ( this . position_num ) ;
2014-06-08 17:36:56 +02:00
this . show ( ) ;
2019-11-12 16:10:04 +01:00
} else {
2017-11-12 12:59:17 +01:00
this . hide ( ) ;
2019-11-12 15:32:35 +01:00
//this.numkeypad_move(int.parse(this.config.get("position")));
this . numkeypad_move ( this . position_num ) ;
2013-12-08 01:09:00 +01:00
}
2011-10-18 09:46:19 +02:00
2011-10-13 19:15:00 +02:00
}
2013-09-18 20:32:40 +02:00
public override void show ( ) {
2020-06-14 00:00:04 +02:00
this . _minimized = false ;
2019-01-25 03:22:18 +01:00
this . move ( this . position_on_hide_x , this . position_on_hide_y ) ;
2017-11-12 12:59:17 +01:00
debug ( @" Show window on $(this.position_on_hide_x), $(this.position_on_hide_y) \n " ) ;
2013-09-13 20:22:53 +02:00
base . show ( ) ;
2019-01-25 03:22:18 +01:00
this . move ( this . position_on_hide_x , this . position_on_hide_y ) ;
2017-11-12 12:59:17 +01:00
/ * Second move fixes issue for i3 - wm ( ? ) . The move ( ) before show ( )
moves the current window as expected , but somehow does not propagate this values
correcty to the wm . = > The next hide ( ) call will fetch wrong values
and a second show ( ) call plaes the window in the middle of the screen .
* /
2011-10-14 22:10:11 +02:00
2019-01-25 03:22:18 +01:00
if ( this . config . get ( " on_top " ) = = " 1 " ) {
2011-10-14 22:10:11 +02:00
this . set_keep_above ( true ) ;
2013-09-18 20:32:40 +02:00
} else {
2011-10-14 22:10:11 +02:00
this . present ( ) ;
2013-09-18 20:32:40 +02:00
}
2011-10-14 22:10:11 +02:00
}
2011-10-13 19:15:00 +02:00
2019-11-12 16:10:04 +01:00
public override void hide ( ) {
2011-10-18 09:46:19 +02:00
//store current coordinates
int tmpx ;
int tmpy ;
this . get_position ( out tmpx , out tmpy ) ;
this . position_on_hide_x = tmpx ;
this . position_on_hide_y = tmpy ;
2017-11-12 12:59:17 +01:00
debug ( @" Hide window on $(this.position_on_hide_x), $(this.position_on_hide_y) \n " ) ;
2011-10-18 09:46:19 +02:00
2020-06-14 00:00:04 +02:00
this . _minimized = true ;
2011-10-17 20:38:29 +02:00
base . hide ( ) ;
2011-10-14 22:10:11 +02:00
}
2011-10-13 19:15:00 +02:00
2019-11-12 16:10:04 +01:00
public bool toggle ( ) {
if ( this . minimized ) show ( ) ;
2011-10-17 20:38:29 +02:00
else hide ( ) ;
2011-10-14 22:10:11 +02:00
return this . minimized ;
}
2011-10-13 19:15:00 +02:00
2019-11-12 16:10:04 +01:00
public void numkeypad_move ( int pos ) {
2019-11-06 21:04:59 +01:00
var display = Gdk . Display . get_default ( ) ;
//var screen = Gdk.Screen.get_default();
var screen = display . get_default_screen ( ) ;
//var screen = this.get_screen();
//var monitor = display.get_monitor_at_window(screen.get_active_window());
# if GTK_MAJOR_VERSION = = 2 | | GTK_MINOR_VERSION = = 18 | | GTK_MINOR_VERSION = = 19 | | GTK_MINOR_VERSION = = 20 | | GTK_MINOR_VERSION = = 21
2019-11-07 11:50:44 +01:00
// Old variant for ubuntu 16.04 (Glib version < 3.22)
2019-11-06 21:04:59 +01:00
var n_monitors = screen . get_n_monitors ( ) ;
# else
var n_monitors = display . get_n_monitors ( ) ; // Könnte n_1+n_2+…n_k sein mit k Screens?!
# endif
debug ( @" Number of monitors: $(n_monitors) " ) ;
GLib . assert ( n_monitors > 0 ) ;
2019-11-07 11:50:44 +01:00
2020-06-14 00:00:04 +02:00
if ( pos < 0 ) { pos = 0 ; }
2019-11-07 11:50:44 +01:00
// Automatic set of next position
2019-11-12 16:10:04 +01:00
if ( ( pos % 10 ) = = 0 ) {
2019-11-07 11:50:44 +01:00
/* Resolve next position */
pos = this . position_cycle [ this . position_num ] ;
}
GLib . assert ( ( pos % 10 ) > 0 ) ;
// Validate input for manual set of position.
// Note that 'extra monitors', which are not respected in position_cycle, will be ignored.
2019-11-12 16:10:04 +01:00
if ( pos > = this . position_cycle . length ) {
2019-11-07 11:50:44 +01:00
pos % = 10 ; // go back to first monitor
}
2019-11-12 16:10:04 +01:00
if ( pos < 1 ) {
2019-11-07 11:50:44 +01:00
GLib . stdout . printf ( @" Positioning error! Can not handle $(pos). Fall back on pos=5. \n " ) ;
pos = 5 ;
}
2019-11-06 21:04:59 +01:00
GLib . assert ( pos > = 0 ) ;
/ * Positions supports multiple screens , now .
2019-11-07 11:50:44 +01:00
1 - 9 on monitor 0 , 11 - 19 on monitor 1 , …
2019-11-06 21:04:59 +01:00
2019-11-07 11:50:44 +01:00
This line shift indicies of non connected monitors to a available one .
* /
2019-11-06 21:04:59 +01:00
pos % = 10 * n_monitors ;
// Get monitor for this position
int monitor_index = pos / 10 ;
GLib . assert ( monitor_index > = 0 ) ;
2019-11-12 16:10:04 +01:00
if ( monitor_index > = n_monitors ) {
2019-11-06 21:04:59 +01:00
monitor_index % = n_monitors ;
}
// Get the position within the monitor
int pos_on_screen = pos % 10 ;
Gdk . Rectangle monitor_rect_dest ;
screen . get_monitor_geometry ( monitor_index , out monitor_rect_dest ) ;
2019-11-07 11:50:44 +01:00
debug ( @" Monitor($(monitor_index)) values: x=$(monitor_rect_dest.x), " +
@" y=$(monitor_rect_dest.y), w=$(monitor_rect_dest.width), h=$(monitor_rect_dest.height) \n " ) ;
2019-11-12 15:32:35 +01:00
this . monitor_id = monitor_index ;
/* Get the desired size for the current monitor. */
int width ;
int height ;
Size user_size = this . size_for_monitor [ this . monitor_id ] ;
if ( user_size ! = null & &
monitor_rect_dest . width = = user_size . monitor_width /* catch resolution changes */
2019-11-12 16:10:04 +01:00
) {
2019-11-12 15:32:35 +01:00
// Use stored values
width = user_size . width ;
height = user_size . height ;
2019-11-12 16:10:04 +01:00
} else {
2019-11-12 15:32:35 +01:00
// Default values
width = get_image_width_for_monitor ( monitor_rect_dest . width ) ;
2019-11-07 11:50:44 +01:00
height = get_unscaled_height ( ) * width / get_unscaled_width ( ) ;
2019-11-12 15:32:35 +01:00
// Store values
Size tmp = new Size ( ) ;
tmp . width = width ;
tmp . height = height ;
tmp . monitor_width = monitor_rect_dest . width ;
this . size_for_monitor . set ( this . monitor_id , tmp ) ;
2019-11-07 11:50:44 +01:00
}
2011-10-21 00:37:43 +02:00
2019-11-12 15:32:35 +01:00
/* Compare current window size with desired new value and resize if required.*/
2019-01-25 03:22:18 +01:00
int x , y , w , h ;
2019-11-07 11:50:44 +01:00
this . get_size ( out w , out h ) ; // wrong if resolution changed?! TODO: Edit comment
//this.get_size2(out w, out h); // this reflect resolution changes
2011-10-13 19:15:00 +02:00
2019-11-12 16:10:04 +01:00
if ( w ! = width | | h ! = height ) {
2019-11-12 15:32:35 +01:00
// Window should move on monitor where the window needs an other width.
this . resize ( width , height ) ;
this . set_default_size ( width , height ) ;
w = width ;
h = height ;
}
/* Positioning window */
2019-11-06 21:04:59 +01:00
switch ( pos_on_screen ) {
2019-11-12 15:32:35 +01:00
case 0 : // Jump to next position
GLib . assert ( false ) ; // Deprecated case. It should be already handled.
2011-10-13 19:15:00 +02:00
return ;
case 7 :
x = 0 ;
y = 0 ;
break ;
case 8 :
2019-11-06 21:04:59 +01:00
x = ( monitor_rect_dest . width - w ) / 2 ;
2011-10-13 19:15:00 +02:00
y = 0 ;
break ;
case 9 :
2019-11-06 21:04:59 +01:00
x = monitor_rect_dest . width - w ;
2011-10-13 19:15:00 +02:00
y = 0 ;
break ;
case 4 :
x = 0 ;
2019-11-06 21:04:59 +01:00
y = ( monitor_rect_dest . height - h ) / 2 ;
2011-10-13 19:15:00 +02:00
break ;
case 5 :
2019-11-06 21:04:59 +01:00
x = ( monitor_rect_dest . width - w ) / 2 ;
y = ( monitor_rect_dest . height - h ) / 2 ;
2011-10-13 19:15:00 +02:00
break ;
case 6 :
2019-11-06 21:04:59 +01:00
x = monitor_rect_dest . width - w ;
y = ( monitor_rect_dest . height - h ) / 2 ;
2011-10-13 19:15:00 +02:00
break ;
case 1 :
x = 0 ;
2019-11-06 21:04:59 +01:00
y = monitor_rect_dest . height - h ;
2011-10-13 19:15:00 +02:00
break ;
case 2 :
2019-11-06 21:04:59 +01:00
x = ( monitor_rect_dest . width - w ) / 2 ;
y = monitor_rect_dest . height - h ;
2011-10-13 19:15:00 +02:00
break ;
default :
2019-11-06 21:04:59 +01:00
x = monitor_rect_dest . width - w ;
y = monitor_rect_dest . height - h ;
2011-10-13 19:15:00 +02:00
break ;
2011-10-14 22:10:11 +02:00
}
2019-11-12 15:32:35 +01:00
// Multi monitor support: Add offset of current monitor
2019-11-06 21:04:59 +01:00
x + = monitor_rect_dest . x ;
y + = monitor_rect_dest . y ;
2011-10-13 19:15:00 +02:00
this . position_num = pos ;
2013-12-08 01:09:00 +01:00
2014-06-09 22:44:45 +02:00
//store current coordinates
2013-12-08 01:09:00 +01:00
this . position_on_hide_x = x ;
this . position_on_hide_y = y ;
2019-01-25 03:22:18 +01:00
this . move ( x , y ) ;
2011-10-13 19:15:00 +02:00
}
2019-11-12 16:10:04 +01:00
public void monitor_move ( int i_monitor = - 1 , bool hide_after_latest = false ) {
2019-11-06 21:04:59 +01:00
2019-11-12 16:10:04 +01:00
if ( hide_after_latest ) {
if ( this . minimized ) {
2019-11-06 21:04:59 +01:00
debug ( @" Show minimized window again. $(this.position_num) " ) ;
show ( ) ;
return ;
}
}
2019-11-12 16:10:04 +01:00
if ( i_monitor < 0 ) {
2019-11-06 21:04:59 +01:00
numkeypad_move ( this . position_num + 10 ) ;
2019-11-12 16:10:04 +01:00
} else {
2019-11-07 11:50:44 +01:00
numkeypad_move ( 10 * i_monitor + ( this . position_num % 10 ) ) ;
2019-11-06 21:04:59 +01:00
}
debug ( @" New position: $(this.position_num) " ) ;
2019-11-12 16:10:04 +01:00
if ( hide_after_latest & & this . position_num < 10 & & this . already_shown_on_monitor1 ) {
2019-11-07 11:50:44 +01:00
// First monitor reached again
2019-11-06 21:04:59 +01:00
debug ( @" Hide window. $(this.position_num) " ) ;
2019-11-12 15:32:35 +01:00
// Workaround: get_positon() call in hide still returns old position.
// reset new value after call.
int tmpx = this . position_on_hide_x ;
int tmpy = this . position_on_hide_y ;
2019-11-06 21:04:59 +01:00
this . hide ( ) ;
2019-11-12 15:32:35 +01:00
//debug(@"AAAA $(this.position_on_hide_x), $(tmpx)");
this . position_on_hide_x = tmpx ;
this . position_on_hide_y = tmpy ;
}
2019-11-12 16:10:04 +01:00
if ( this . position_num < 10 ) {
2019-11-12 15:32:35 +01:00
this . already_shown_on_monitor1 = true ;
2019-11-06 21:04:59 +01:00
}
}
2020-06-07 23:34:22 +02:00
public Gdk . Pixbuf open_image ( int layer ) {
2020-06-08 20:49:48 +02:00
string bildpfad = " " ;
switch ( this . layoutType ) {
case " ADNW " :
{
bildpfad = @" $(config.get( " asset_folder " ))/adnw/tastatur_adnw_Ebene$(layer).png " ;
break ;
}
2021-02-03 00:21:08 +01:00
case " Bone " :
{
bildpfad = @" $(config.get( " asset_folder " ))/bone/tastatur_bone_Ebene$(layer).png " ;
break ;
}
2020-06-08 20:49:48 +02:00
case " KOY " :
{
bildpfad = @" $(config.get( " asset_folder " ))/koy/tastatur_koy_Ebene$(layer).png " ;
break ;
}
case " NEO2 " :
default :
{
bildpfad = @" $(config.get( " asset_folder " ))/neo2.0/tastatur_neo_Ebene$(layer).png " ;
break ;
}
}
2020-06-14 00:00:04 +02:00
return open_image_str ( bildpfad ) ;
2011-10-13 19:15:00 +02:00
}
public Gdk . Pixbuf open_image_str ( string bildpfad ) {
try {
return new Gdk . Pixbuf . from_file ( bildpfad ) ;
} catch ( Error e ) {
error ( " %s " , e . message ) ;
}
}
2020-06-10 09:06:19 +02:00
public string get_layout_icon_name ( ) {
// Name without extenion returned for indicator.vala
2020-06-08 20:49:48 +02:00
switch ( this . layoutType ) {
case " ADNW " :
{
2020-06-10 09:06:19 +02:00
return " ADNW-Icon " ;
2020-06-08 20:49:48 +02:00
}
2021-02-03 00:21:08 +01:00
case " Bone " :
{
return " Bone-Icon " ;
}
2020-06-08 20:49:48 +02:00
case " KOY " :
{
2020-06-10 09:06:19 +02:00
return " KOY-Icon " ;
2020-06-08 20:49:48 +02:00
}
case " NEO2 " :
default :
{
2020-06-10 09:06:19 +02:00
return " Neo-Icon " ;
2020-06-08 20:49:48 +02:00
}
}
}
2020-06-10 09:06:19 +02:00
private void load_program_icon ( ) {
2019-11-07 11:50:44 +01:00
this . image_buffer [ " icon " ] = open_image_str (
2020-06-10 09:06:19 +02:00
@" $(config.get( " asset_folder " ))/icons/$(get_layout_icon_name()).png " ) ;
}
2019-11-07 11:50:44 +01:00
public void load_images ( ) {
2020-06-08 20:49:48 +02:00
this . load_program_icon ( ) ;
2011-10-13 19:15:00 +02:00
2019-01-25 03:22:18 +01:00
this . numpad_width = int . parse ( this . config . get ( " numpad_width " ) ) ;
this . function_keys_height = int . parse ( this . config . get ( " function_keys_height " ) ) ;
2011-10-17 20:38:29 +02:00
2013-09-18 20:32:40 +02:00
for ( int i = 1 ; i < 7 ; i + + ) {
2019-11-07 11:50:44 +01:00
Gdk . Pixbuf layer = open_image ( i ) ;
2011-10-13 19:15:00 +02:00
2019-11-07 11:50:44 +01:00
//Funktionstasten ausblenden, falls gefordert.
2019-01-25 03:22:18 +01:00
if ( this . config . get ( " display_function_keys " ) = = " 0 " ) {
2019-11-07 11:50:44 +01:00
var tmp = new Gdk . Pixbuf ( layer . colorspace , layer . has_alpha , layer . bits_per_sample , layer . width , layer . height - function_keys_height ) ;
layer . copy_area ( 0 , function_keys_height , tmp . width , tmp . height , tmp , 0 , 0 ) ;
layer = tmp ;
2011-10-17 20:38:29 +02:00
}
//Numpad-Teil abschneiden, falls gefordert.
2019-01-25 03:22:18 +01:00
if ( this . config . get ( " display_numpad " ) = = " 0 " ) {
2019-11-07 11:50:44 +01:00
var tmp = new Gdk . Pixbuf ( layer . colorspace , layer . has_alpha , layer . bits_per_sample , layer . width - numpad_width , layer . height ) ;
layer . copy_area ( 0 , 0 , tmp . width , tmp . height , tmp , 0 , 0 ) ;
layer = tmp ;
2011-10-13 19:15:00 +02:00
}
2019-11-07 11:50:44 +01:00
string id = @" unscaled_$(i) " ;
this . image_buffer . set ( id , layer ) ;
2011-10-13 19:15:00 +02:00
}
2014-06-09 22:44:45 +02:00
2011-10-13 19:15:00 +02:00
}
2019-11-12 15:32:35 +01:00
private int get_image_width_for_monitor ( int monitor_width ) {
2019-11-07 11:50:44 +01:00
//int screen_width = this.get_screen_width(); //Gdk.Screen.width();
2019-11-12 15:32:35 +01:00
int max_width = ( int ) ( double . parse ( this . config . get ( " max_width " ) ) * monitor_width ) ;
int min_width = ( int ) ( double . parse ( this . config . get ( " min_width " ) ) * monitor_width ) ;
2019-11-07 11:50:44 +01:00
int width = int . min ( int . max ( int . parse ( this . config . get ( " width " ) ) , min_width ) , max_width ) ;
return width ;
}
2011-10-13 19:15:00 +02:00
private bool on_key_pressed ( Widget source , Gdk . EventKey key ) {
// If the key pressed was q, quit, else show the next page
if ( key . str = = " q " ) {
2019-01-25 03:22:18 +01:00
NeoLayoutViewer . quit ( ) ;
2011-10-13 19:15:00 +02:00
}
if ( key . str = = " h " ) {
2011-10-17 20:38:29 +02:00
this . hide ( ) ;
2011-10-13 19:15:00 +02:00
}
return false ;
}
2011-10-23 03:48:20 +02:00
private bool on_button_pressed ( Widget source , Gdk . EventButton event ) {
2013-09-18 20:32:40 +02:00
if ( event . button = = 3 ) {
2011-10-23 03:48:20 +02:00
this . hide ( ) ;
}
return false ;
}
2011-10-16 19:09:33 +02:00
/ *
2014-06-09 22:44:45 +02:00
Use the for values
2011-10-16 19:14:47 +02:00
- “ modifier was pressed ”
- “ modifier is pressed ”
- “ modifier was seleted by mouseclick ” and
- “ modifier is seleted by mouseclick ”
2011-10-17 20:38:29 +02:00
as array indizes to eval an new state . See comment of MODIFIER_KEYBOARD_MOUSE_MAP , too .
2011-10-16 19:14:47 +02:00
* /
2013-09-18 20:32:40 +02:00
public void change_active_modifier ( int mod_index , bool keyboard , int new_mod_state ) {
2011-10-16 19:09:33 +02:00
int old_mod_state ;
2013-09-18 20:32:40 +02:00
if ( keyboard ) {
2011-10-16 19:09:33 +02:00
//Keypress or Release of shift etc.
2020-06-10 09:06:19 +02:00
old_mod_state = this . active_modifier_by_keyboard [ mod_index ] ;
2011-10-16 19:09:33 +02:00
this . active_modifier_by_keyboard [ mod_index ] = MODIFIER_KEYBOARD_MOUSE_MAP [
old_mod_state ,
this . active_modifier_by_mouse [ mod_index ] ,
new_mod_state ,
this . active_modifier_by_mouse [ mod_index ]
2019-11-07 11:50:44 +01:00
] ;
this . active_modifier_by_mouse [ mod_index ] = MODIFIER_KEYBOARD_MOUSE_MAP [
this . active_modifier_by_mouse [ mod_index ] ,
old_mod_state ,
this . active_modifier_by_mouse [ mod_index ] ,
new_mod_state
2013-09-18 20:32:40 +02:00
] ;
} else {
2011-10-16 19:09:33 +02:00
//Mouseclick on shift button etc.
2019-11-07 11:50:44 +01:00
old_mod_state = this . active_modifier_by_mouse [ mod_index ] ;
2011-10-16 19:09:33 +02:00
this . active_modifier_by_mouse [ mod_index ] = MODIFIER_KEYBOARD_MOUSE_MAP [
old_mod_state ,
this . active_modifier_by_keyboard [ mod_index ] ,
new_mod_state ,
this . active_modifier_by_keyboard [ mod_index ]
2019-11-07 11:50:44 +01:00
] ;
this . active_modifier_by_keyboard [ mod_index ] = MODIFIER_KEYBOARD_MOUSE_MAP [
this . active_modifier_by_keyboard [ mod_index ] ,
old_mod_state ,
this . active_modifier_by_keyboard [ mod_index ] ,
new_mod_state
2013-09-18 20:32:40 +02:00
] ;
2011-10-16 19:09:33 +02:00
}
}
2013-09-18 20:32:40 +02:00
public int getActiveModifierMask ( int [ ] modifier ) {
2011-10-16 19:09:33 +02:00
int modMask = 0 ;
2013-09-18 20:32:40 +02:00
foreach ( int i in modifier ) {
modMask + = ( this . active_modifier_by_keyboard [ i ] | this . active_modifier_by_mouse [ i ] ) * this . MODIFIER_MASK [ i ] ;
2011-10-16 19:09:33 +02:00
}
return modMask ;
}
2013-09-18 20:32:40 +02:00
private void check_modifier ( int iet1 ) {
2011-10-13 19:15:00 +02:00
2013-09-18 20:32:40 +02:00
if ( iet1 ! = this . layer ) {
2011-10-17 20:38:29 +02:00
this . layer = iet1 ;
2013-09-18 20:32:40 +02:00
render_page ( ) ;
2011-10-14 22:10:11 +02:00
}
2011-10-13 19:15:00 +02:00
}
2013-09-18 20:32:40 +02:00
public void redraw ( ) {
2011-10-17 20:38:29 +02:00
var tlayer = this . layer ;
2011-10-13 19:15:00 +02:00
2020-06-14 00:00:04 +02:00
if ( this . fixed_layer > 0 ) { // Ignore key events
for ( int i = 0 ; i < 3 ; i + + ) {
this . active_modifier_by_mouse [ i + 1 ] = this . LAYER_TO_MODIFIERS [ this . fixed_layer - 1 , i ] ;
}
this . layer = this . fixed_layer ;
2019-11-12 16:10:04 +01:00
} else {
2019-01-25 03:22:18 +01:00
this . layer = this . MODIFIER_MAP2 [
this . active_modifier_by_keyboard [ 1 ] | this . active_modifier_by_mouse [ 1 ] , //shift
this . active_modifier_by_keyboard [ 2 ] | this . active_modifier_by_mouse [ 2 ] , //neo-mod3
this . active_modifier_by_keyboard [ 3 ] | this . active_modifier_by_mouse [ 3 ] //neo-mod4
] + 1 ;
}
2011-10-17 20:38:29 +02:00
// check, which extra modifier is pressed and update.
2013-09-18 20:32:40 +02:00
foreach ( var modkey in modifier_key_images ) {
2011-10-17 20:38:29 +02:00
modkey . change (
this . active_modifier_by_keyboard [ modkey . modifier_index ] |
this . active_modifier_by_mouse [ modkey . modifier_index ]
) ;
}
2013-09-18 20:32:40 +02:00
if ( tlayer ! = this . layer ) {
2020-06-14 00:00:04 +02:00
debug ( @" Redraw with layer $(this.layer) " ) ;
2011-10-16 19:09:33 +02:00
render_page ( ) ;
2013-09-18 20:32:40 +02:00
}
2011-10-17 20:38:29 +02:00
2011-10-13 19:15:00 +02:00
}
private void render_page ( ) {
2019-11-07 11:50:44 +01:00
this . image . select_pixbuf ( this . layer - 1 ) ;
2011-10-13 19:15:00 +02:00
}
2013-09-18 20:32:40 +02:00
public Gdk . Pixbuf getIcon ( ) {
2019-11-07 11:50:44 +01:00
return this . image_buffer [ " icon " ] ;
2011-10-13 19:15:00 +02:00
}
2013-09-18 20:32:40 +02:00
public void external_key_press ( int iet1 , int modifier_mask ) {
for ( int iet2 = 0 ; iet2 < 4 ; iet2 + + ) {
if ( this . NEO_MODIFIER_MASK [ iet2 ] = = modifier_mask ) {
iet1 = this . MODIFIER_MAP [ iet1 , iet2 ] + 1 ;
2011-10-14 22:10:11 +02:00
this . check_modifier ( iet1 ) ;
return ;
2011-10-13 19:15:00 +02:00
}
2011-10-14 22:10:11 +02:00
}
2013-09-18 20:32:40 +02:00
iet1 = this . MODIFIER_MAP [ iet1 , 0 ] + 1 ;
2011-10-14 22:10:11 +02:00
this . check_modifier ( iet1 ) ;
2011-10-13 19:15:00 +02:00
}
2013-09-18 20:32:40 +02:00
public void external_key_release ( int iet1 , int modifier_mask ) {
for ( int iet2 = 0 ; iet2 < 4 ; iet2 + + ) {
if ( this . NEO_MODIFIER_MASK [ iet2 ] = = modifier_mask ) {
iet1 = this . MODIFIER_MAP_RELEASE [ iet1 , iet2 ] + 1 ;
2011-10-14 22:10:11 +02:00
this . check_modifier ( iet1 ) ;
return ;
2011-10-13 19:15:00 +02:00
}
2011-10-14 22:10:11 +02:00
}
2011-10-13 19:15:00 +02:00
2013-09-18 20:32:40 +02:00
iet1 = this . MODIFIER_MAP_RELEASE [ iet1 , 0 ] + 1 ;
2011-10-14 22:10:11 +02:00
this . check_modifier ( iet1 ) ;
2011-10-13 19:15:00 +02:00
}
2019-11-12 16:10:04 +01:00
public int get_screen_width ( ) {
2019-01-25 03:22:18 +01:00
// Return value derived from config.get("screen_width")) or Gdk.Screen.width()
2017-11-17 16:56:34 +01:00
2019-11-12 16:10:04 +01:00
if ( this . screen_dim_auto [ 0 ] ) {
2017-11-17 16:56:34 +01:00
//Re-evaluate
# if GTK_MINOR_VERSION = = 18 | | GTK_MINOR_VERSION = = 19 | | GTK_MINOR_VERSION = = 20 | | GTK_MINOR_VERSION = = 21
// Old variant for ubuntu 16.04 ( '<' check not defined in vala preprozessor :-()
var display = Gdk . Display . get_default ( ) ;
var screen = display . get_default_screen ( ) ;
//Gdk.Rectangle geometry = {0, 0, screen.get_width(), screen.get_height()};
screen_dim [ 0 ] = screen . get_width ( ) ;
# else
var display = Gdk . Display . get_default ( ) ;
var screen = this . get_screen ( ) ;
var monitor = display . get_monitor_at_window ( screen . get_active_window ( ) ) ;
//Note that type of this is Gtk.Window, but get_active_window() return Gdk.Window
2019-11-12 16:10:04 +01:00
if ( monitor = = null ) {
2017-11-17 16:56:34 +01:00
monitor = display . get_primary_monitor ( ) ;
}
Gdk . Rectangle geometry = monitor . get_geometry ( ) ;
screen_dim [ 0 ] = geometry . width ;
# endif
}
2019-01-25 03:22:18 +01:00
return screen_dim [ 0 ] ;
}
2017-11-12 17:18:57 +01:00
2019-11-07 11:50:44 +01:00
public int get_unscaled_height ( ) {
int backgroundH_unscaled = 250 ;
if ( this . config . get ( " display_function_keys " ) = = " 0 " ) {
backgroundH_unscaled - = this . function_keys_height ;
}
return backgroundH_unscaled ;
}
public int get_unscaled_width ( ) {
int backgroundW_unscaled = 1000 ;
if ( this . config . get ( " display_numpad " ) = = " 0 " ) {
backgroundW_unscaled - = this . numpad_width ;
}
return backgroundW_unscaled ;
}
2019-11-12 16:10:04 +01:00
public int get_screen_height ( ) {
2019-01-25 03:22:18 +01:00
// Return value derived from config.get("screen_height")) or Gdk.Screen.height()
2017-11-17 16:56:34 +01:00
2019-11-12 16:10:04 +01:00
if ( this . screen_dim_auto [ 1 ] ) {
2017-11-17 16:56:34 +01:00
//Re-evaluate
# if GTK_MINOR_VERSION = = 18 | | GTK_MINOR_VERSION = = 19 | | GTK_MINOR_VERSION = = 20 | | GTK_MINOR_VERSION = = 21
// Old variant for ubuntu 16.04 ( '<' check not defined in vala preprozessor :-()
var display = Gdk . Display . get_default ( ) ;
var screen = display . get_default_screen ( ) ;
//Gdk.Rectangle geometry = {0, 0, screen.get_width(), screen.get_height()};
screen_dim [ 1 ] = screen . get_height ( ) ;
# else
var display = Gdk . Display . get_default ( ) ;
var screen = this . get_screen ( ) ;
var monitor = display . get_monitor_at_window ( screen . get_active_window ( ) ) ;
//Note that type of this is Gtk.Window, but get_active_window() return Gdk.Window
2019-11-12 16:10:04 +01:00
if ( monitor = = null ) {
2017-11-17 16:56:34 +01:00
monitor = display . get_primary_monitor ( ) ;
}
Gdk . Rectangle geometry = monitor . get_geometry ( ) ;
screen_dim [ 1 ] = geometry . height ;
# endif
}
2019-01-25 03:22:18 +01:00
return screen_dim [ 1 ] ;
}
2017-11-12 17:18:57 +01:00
2019-11-12 16:10:04 +01:00
private void fill_position_cycle_default ( ref int [ ] positions ) {
2019-11-06 21:04:59 +01:00
/ * Position Next position o ← o ← o
2019-11-07 11:50:44 +01:00
9 8 9 4 7 8 ↓ ↑
6 5 6 = = = = > 1 3 9 o o o
3 2 3 2 3 6 ↓ ↘ ↑
o → o → o
2019-11-12 16:10:04 +01:00
Values for monitor 4 are 11 , … , 19 and so on .
2019-11-07 11:50:44 +01:00
Example output :
positions = {
- 1 , 3 , 3 , 9 , 1 , 3 , 9 , 1 , 7 , 7 ,
- 11 , 13 , 13 , 19 , 11 , 13 , 19 , 11 , 17 , 17 ,
- 21 , 23 , 23 , 29 , 21 , 23 , 29 , 21 , 27 , 27 ,
- 31 , 33 , 33 , 39 , 31 , 33 , 39 , 31 , 37 , 37 ,
} ;
* /
2019-11-06 21:04:59 +01:00
GLib . assert ( positions . length % 10 = = 0 & & positions . length > 0 ) ;
int n_monitors = positions . length / 10 ;
2019-11-12 16:10:04 +01:00
for ( int i_monitor = 0 ; i_monitor < n_monitors ; i_monitor + + ) {
2019-11-06 21:04:59 +01:00
int s = i_monitor * 10 ;
positions [ s ] = - 1 ;
positions [ s + 1 ] = s + 2 ;
positions [ s + 2 ] = s + 3 ;
positions [ s + 3 ] = s + 6 ;
positions [ s + 4 ] = s + 1 ;
positions [ s + 5 ] = s + 3 ;
positions [ s + 6 ] = s + 9 ;
positions [ s + 7 ] = s + 4 ;
positions [ s + 8 ] = s + 7 ;
positions [ s + 9 ] = s + 8 ;
}
}
2019-11-12 16:10:04 +01:00
private void main_resized ( ) {
2019-11-12 15:32:35 +01:00
// Overwrite stored size for current monitor
int width ;
int height ;
this . get_size ( out width , out height ) ;
Size user_size = this . size_for_monitor [ this . monitor_id ] ;
GLib . assert ( user_size ! = null ) ;
2019-11-12 16:10:04 +01:00
if ( user_size ! = null ) {
2019-11-12 15:32:35 +01:00
user_size . width = width ;
user_size . height = height ;
}
}
2011-10-14 22:10:11 +02:00
} //End class NeoWindow
2019-11-12 15:32:35 +01:00
private class Size {
private int _width ;
private int _height ;
private int _monitor_width ;
public int width {
get { return _width ; }
2019-11-12 16:10:04 +01:00
set { if ( value < 1 ) { _width = 1 ; } else { _width = value ; } }
2019-11-12 15:32:35 +01:00
}
public int height {
get { return _height ; }
2019-11-12 16:10:04 +01:00
set { if ( value < 1 ) { _height = 1 ; } else { _height = value ; } }
2019-11-12 15:32:35 +01:00
}
public int monitor_width {
get { return _monitor_width ; }
2019-11-12 16:10:04 +01:00
set { if ( value < 1 ) { _monitor_width = 1 ; } else { _monitor_width = value ; } }
2019-11-12 15:32:35 +01:00
}
}
2011-10-13 19:15:00 +02:00
}