Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ src_tilda_SOURCES = \
src/tilda_terminal.h src/tilda_terminal.c \
src/tilda-url-spawner.h src/tilda-url-spawner.c \
src/tilda_window.h src/tilda_window.c \
src/window-position.h src/window-position.c \
src/tomboykeybinder.h src/tomboykeybinder.c \
src/wizard.h src/wizard.c \
$(NULL)
Expand Down Expand Up @@ -113,6 +114,29 @@ src_tilda_LDADD = \
-lm \
$(NULL)

check_PROGRAMS = tests/test-window-position
TESTS = $(check_PROGRAMS)

tests_test_window_position_SOURCES = \
tests/test-window-position.c \
src/window-position.c \
$(NULL)

tests_test_window_position_CPPFLAGS = \
$(AM_CPPFLAGS) \
-I$(top_srcdir)/src \
$(NULL)

tests_test_window_position_CFLAGS = \
$(AM_CFLAGS) \
$(GTK_CFLAGS) \
$(NULL)

tests_test_window_position_LDADD = \
$(AM_LDADD) \
$(GTK_LIBS) \
$(NULL)

EXTRA_DIST += \
src/glade-resources.gresource.xml \
src/tilda-dbus-actions.xml \
Expand Down
18 changes: 7 additions & 11 deletions src/key_grabber.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,13 @@ void generate_animation_positions (struct tilda_window_ *tw)
DEBUG_ASSERT (tw != NULL);

gint i;
gint last_pos_x = config_getint ("x_pos");
gint last_pos_y = config_getint ("y_pos");
GdkRectangle geometry;
tilda_window_get_effective_geometry (tw, 0, 0, &geometry);

GdkRectangle rectangle;
config_get_configured_window_size (&rectangle);

gint last_width = rectangle.width;
gint last_height = rectangle.height;
gint last_pos_x = geometry.x;
gint last_pos_y = geometry.y;
gint last_width = geometry.width;
gint last_height = geometry.height;
gint screen_width;
gint screen_height;
screen_size_get_dimensions (&screen_width, &screen_height);
Expand Down Expand Up @@ -160,7 +159,7 @@ void tilda_window_set_active (tilda_window *tw)

XEvent event;
long mask = SubstructureRedirectMask | SubstructureNotifyMask;
gtk_window_move (GTK_WINDOW(tw->window), config_getint ("x_pos"), config_getint ("y_pos"));
tilda_window_update_window_position (tw);
if (gdk_x11_screen_supports_net_wm_hint (screen,
gdk_atom_intern_static_string ("_NET_ACTIVE_WINDOW")))
{
Expand Down Expand Up @@ -392,8 +391,6 @@ static void pull_down (struct tilda_window_ *tw) {
(guchar *) &atom, 1);
gdk_x11_display_error_trap_pop_ignored(gdk_display_get_default());
}
} else {
gtk_window_move (GTK_WINDOW(tw->window), config_getint ("x_pos"), config_getint ("y_pos"));
}

/* Nasty code to make metacity behave. Starting at metacity-2.22 they "fixed" the
Expand Down Expand Up @@ -434,4 +431,3 @@ void tilda_keygrabber_unbind (const gchar *keystr)


/* vim: set ts=4 sts=4 sw=4 expandtab: */

152 changes: 84 additions & 68 deletions src/tilda_window.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "tilda_window.h"
#include "tilda_terminal.h"
#include "key_grabber.h"
#include "window-position.h"

#include <math.h>
#include <stdio.h>
Expand Down Expand Up @@ -1046,7 +1047,7 @@ gboolean tilda_window_init (const gchar *config_file, const gint instance, tilda
tw->current_state = STATE_UP;

GdkRectangle rectangle;
config_get_configured_window_size (&rectangle);
tilda_window_get_effective_geometry (tw, 0, 0, &rectangle);

gint width = rectangle.width;
gint height = rectangle.height;
Expand All @@ -1059,6 +1060,7 @@ gboolean tilda_window_init (const gchar *config_file, const gint instance, tilda

/* Create GDK resources now, to prevent crashes later on */
gtk_widget_realize (tw->window);
tilda_window_update_window_position (tw);
generate_animation_positions (tw);

/* Initialize wizard window reference to NULL */
Expand Down Expand Up @@ -1286,59 +1288,93 @@ gint tilda_window_find_centering_coordinate (tilda_window *tw,
{
DEBUG_FUNCTION ("tilda_window_find_centering_coordinate");

gdouble monitor_dimension = 0;
gdouble tilda_dimension = 0;
GdkMonitor *monitor = tilda_window_find_monitor_number (tw);
GdkRectangle rectangle;
gdk_monitor_get_workarea (monitor, &rectangle);
GdkRectangle geometry;
tilda_window_get_effective_geometry (tw, 0, 0, &geometry);

return dimension == HEIGHT ? geometry.y : geometry.x;
}

void
tilda_window_get_effective_geometry (tilda_window *tw,
gint width,
gint height,
GdkRectangle *geometry)
{
DEBUG_FUNCTION ("tilda_window_get_effective_geometry");
DEBUG_ASSERT (tw != NULL);
g_return_if_fail (geometry != NULL);

GdkRectangle tilda_rectangle;
config_get_configured_window_size (&tilda_rectangle);
GdkMonitor *monitor = tilda_window_find_monitor_number (tw);
GdkRectangle workarea;
gdk_monitor_get_workarea (monitor, &workarea);

if (dimension == HEIGHT) {
monitor_dimension = rectangle.height;
tilda_dimension = tilda_rectangle.height;
} else if (dimension == WIDTH) {
monitor_dimension = rectangle.width;
tilda_dimension = tilda_rectangle.width;
if (width <= 0) {
const gdouble relative_width =
GLONG_TO_DOUBLE (config_getint ("width_percentage"));
width = pixels_ratio_to_absolute (relative_width, workarea.width);
}
const gdouble screen_center = monitor_dimension / 2.0;
const gdouble tilda_center = tilda_dimension / 2.0;
gint center = (int) (screen_center - tilda_center);

if(dimension == HEIGHT) {
center += rectangle.y;
} else if (dimension == WIDTH) {
center += rectangle.x;

if (height <= 0) {
const gdouble relative_height =
GLONG_TO_DOUBLE (config_getint ("height_percentage"));
height = pixels_ratio_to_absolute (relative_height, workarea.height);
}
return center;

gint x = (gint) config_getint ("x_pos");
gint y = (gint) config_getint ("y_pos");

if (config_getbool ("centered_horizontally"))
x = workarea.x + (workarea.width - width) / 2;

if (config_getbool ("centered_vertically"))
y = workarea.y + (workarea.height - height) / 2;

tilda_window_constrain_position (&workarea, width, height, &x, &y);

geometry->x = x;
geometry->y = y;
geometry->width = width;
geometry->height = height;
}

static void
tilda_window_apply_position (tilda_window *tw,
const GdkRectangle *geometry)
{
if (config_getbool ("centered_horizontally"))
config_setint ("x_pos", geometry->x);

if (config_getbool ("centered_vertically"))
config_setint ("y_pos", geometry->y);

gtk_window_move (GTK_WINDOW (tw->window), geometry->x, geometry->y);
}

void
tilda_window_update_window_geometry (tilda_window *tw,
gint width,
gint height)
{
DEBUG_FUNCTION ("tilda_window_update_window_geometry");

GdkRectangle geometry;
tilda_window_get_effective_geometry (tw, width, height, &geometry);

gtk_window_resize (GTK_WINDOW (tw->window),
geometry.width,
geometry.height);
tilda_window_apply_position (tw, &geometry);
}

void
tilda_window_update_window_position (tilda_window *tw)
{
DEBUG_FUNCTION ("tilda_window_update_window_position");
/**
* If the screen size changed we might also need to recenter the
* tilda window.
*/
gint pos_x, pos_y;
gboolean centered_horizontally = config_getbool ("centered_horizontally");
gboolean centered_vertically = config_getbool ("centered_vertically");

if (centered_horizontally) {
pos_x = tilda_window_find_centering_coordinate (tw, WIDTH);
config_setint ("x_pos", pos_x);
pos_y = (gint) config_getint ("y_pos");
gtk_window_move (GTK_WINDOW (tw->window), pos_x, pos_y);
}

if (centered_vertically) {
pos_y = tilda_window_find_centering_coordinate (tw, HEIGHT);
config_setint ("y_pos", pos_y);
pos_x = (gint) config_getint ("x_pos");
gtk_window_move (GTK_WINDOW (tw->window), pos_x, pos_y);
}
GdkRectangle geometry;
tilda_window_get_effective_geometry (tw, 0, 0, &geometry);

tilda_window_apply_position (tw, &geometry);
}

static gboolean update_tilda_window_size (gpointer user_data)
Expand All @@ -1348,32 +1384,12 @@ static gboolean update_tilda_window_size (gpointer user_data)
g_debug ("Updating tilda window size in idle handler to "
"match new size of workarea.");

/* 1. Get current tilda window size */
int windowHeight = gtk_widget_get_allocated_height (GTK_WIDGET (tw->window));
int windowWidth = gtk_widget_get_allocated_width (GTK_WIDGET (tw->window));

gint newWidth = windowWidth;
gint newHeight = windowHeight;

/* 2. Get the desired size and update the tilda window size if necessary. */
GdkRectangle configured_geometry;
config_get_configured_window_size (&configured_geometry);

if (configured_geometry.width - windowWidth >= 1) {
newWidth = configured_geometry.width;
}

if (configured_geometry.height - windowHeight >= 1) {
newHeight = configured_geometry.height;
}

gtk_window_resize (GTK_WINDOW (tw->window),
newWidth,
newHeight);

tilda_window_update_window_position (tw);
/* Reapply both configured dimensions so the window also shrinks when the
* workarea becomes smaller. */
tilda_window_update_window_geometry (tw, 0, 0);
generate_animation_positions (tw);

/* 3. Returning G_SOURCE_REMOVE below will clear the event source in Gtk.
/* Returning G_SOURCE_REMOVE below will clear the event source in Gtk.
* Thus, we need to reset the ID such that a new event source can be
* registered if the workarea changes again. */
tw->size_update_event_source = 0;
Expand Down
19 changes: 19 additions & 0 deletions src/tilda_window.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,25 @@ GdkMonitor* tilda_window_find_monitor_number(tilda_window *tw);
*/
gint tilda_window_find_centering_coordinate (tilda_window *tw, enum dimensions dimension);

/**
* Gets the configured window geometry constrained to the selected monitor's
* workarea. A non-positive width or height is derived from the corresponding
* configured percentage.
*/
void tilda_window_get_effective_geometry (tilda_window *tw,
gint width,
gint height,
GdkRectangle *geometry);

/**
* Resizes the window and moves it to its effective configured position.
* A non-positive width or height is derived from the corresponding configured
* percentage.
*/
void tilda_window_update_window_geometry (tilda_window *tw,
gint width,
gint height);

void tilda_window_update_window_position (tilda_window *tw);

#define TILDA_WINDOW(data) ((tilda_window *)(data))
Expand Down
40 changes: 40 additions & 0 deletions src/window-position.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* This is free software; you can redistribute it and/or modify it under
* the terms of the GNU Library General Public License as published by
* the Free Software Foundation; either version 2 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 Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/

#include "window-position.h"

void
tilda_window_constrain_position (const GdkRectangle *workarea,
gint window_width,
gint window_height,
gint *x,
gint *y)
{
g_return_if_fail (workarea != NULL);
g_return_if_fail (x != NULL);
g_return_if_fail (y != NULL);

gint max_x = workarea->x;
gint max_y = workarea->y;

if (window_width < workarea->width)
max_x += workarea->width - window_width;

if (window_height < workarea->height)
max_y += workarea->height - window_height;

*x = CLAMP (*x, workarea->x, max_x);
*y = CLAMP (*y, workarea->y, max_y);
}
31 changes: 31 additions & 0 deletions src/window-position.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* This is free software; you can redistribute it and/or modify it under
* the terms of the GNU Library General Public License as published by
* the Free Software Foundation; either version 2 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 Library General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef TILDA_WINDOW_POSITION_H
#define TILDA_WINDOW_POSITION_H

#include <gdk/gdk.h>

G_BEGIN_DECLS

void tilda_window_constrain_position (const GdkRectangle *workarea,
gint window_width,
gint window_height,
gint *x,
gint *y);

G_END_DECLS

#endif
Loading