shortcuts.c 35.4 KB
Newer Older
1 2
/* See LICENSE file for license and copyright information */

3 4 5 6
#include <girara/session.h>
#include <girara/settings.h>
#include <girara/datastructures.h>
#include <girara/shortcuts.h>
7
#include <girara/utils.h>
Moritz Lipp's avatar
Moritz Lipp committed
8
#include <gtk/gtk.h>
9
#include <glib/gi18n.h>
Moritz Lipp's avatar
Moritz Lipp committed
10 11

#include "callbacks.h"
12
#include "shortcuts.h"
13
#include "document.h"
Moritz Lipp's avatar
Moritz Lipp committed
14
#include "zathura.h"
15
#include "render.h"
16
#include "utils.h"
Moritz Lipp's avatar
Moritz Lipp committed
17
#include "page.h"
Moritz Lipp's avatar
Moritz Lipp committed
18
#include "print.h"
19
#include "page-widget.h"
20

Moritz Lipp's avatar
Moritz Lipp committed
21
bool
22
sc_abort(girara_session_t* session, girara_argument_t* UNUSED(argument),
Moritz Lipp's avatar
Moritz Lipp committed
23
    girara_event_t* UNUSED(event), unsigned int UNUSED(t))
24
{
Moritz Lipp's avatar
Moritz Lipp committed
25
  g_return_val_if_fail(session != NULL, false);
26 27 28
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

29 30 31
  bool clear_search = true;
  girara_setting_get(session, "abort-clear-search", &clear_search);

Moritz Lipp's avatar
Moritz Lipp committed
32
  if (zathura->document != NULL) {
33
    unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
34 35
    for (unsigned int page_id = 0; page_id < number_of_pages; ++page_id) {
      zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
Moritz Lipp's avatar
Moritz Lipp committed
36 37 38 39
      if (page == NULL) {
        continue;
      }

40
      g_object_set(zathura_page_get_widget(zathura, page), "draw-links", FALSE, NULL);
41
      if (clear_search == true) {
42 43
        g_object_set(zathura_page_get_widget(zathura, page), "search-results", NULL, NULL);
      }
44 45
    }
  }
Moritz Lipp's avatar
Moritz Lipp committed
46

Moritz Lipp's avatar
Moritz Lipp committed
47
  girara_mode_set(session, session->modes.normal);
48
  girara_sc_abort(session, NULL, NULL, 0);
Moritz Lipp's avatar
Moritz Lipp committed
49

Moritz Lipp's avatar
Moritz Lipp committed
50
  return false;
51 52
}

53 54 55
bool
sc_adjust_window(girara_session_t* session, girara_argument_t* argument,
    girara_event_t* UNUSED(event), unsigned int UNUSED(t))
56
{
57 58 59 60
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
Moritz Lipp's avatar
Moritz Lipp committed
61

62 63
  unsigned int pages_per_row = 1;
  girara_setting_get(session, "pages-per-row", &pages_per_row);
Moritz Lipp's avatar
Moritz Lipp committed
64

65 66 67
  unsigned int first_page_column = 1;
  girara_setting_get(session, "first-page-column", &first_page_column);

68
  if (zathura->ui.page_widget == NULL || zathura->document == NULL) {
Moritz Lipp's avatar
Moritz Lipp committed
69 70 71
    goto error_ret;
  }

72
  float old_zoom = zathura_document_get_scale(zathura->document);
73 74
  zathura_document_set_adjust_mode(zathura->document, argument->n);
  if (argument->n == ZATHURA_ADJUST_NONE) {
75 76 77
    /* there is nothing todo */
    goto error_ret;
  }
78

Moritz Lipp's avatar
Moritz Lipp committed
79
  /* get window size */
80 81
  GtkAllocation allocation;
  gtk_widget_get_allocation(session->gtk.view, &allocation);
Moritz Lipp's avatar
Moritz Lipp committed
82 83
  double width  = allocation.width;
  double height = allocation.height;
Moritz Lipp's avatar
Moritz Lipp committed
84

85 86 87 88 89
  /* scrollbar spacing */
  gint spacing;
  gtk_widget_style_get(session->gtk.view, "scrollbar_spacing", &spacing, NULL);
  width -= spacing;

90 91 92 93 94 95
  /* correct view size */
  if (gtk_widget_get_visible(GTK_WIDGET(session->gtk.inputbar)) == true) {
    gtk_widget_get_allocation(session->gtk.inputbar, &allocation);
    height += allocation.height;
  }

Moritz Lipp's avatar
Moritz Lipp committed
96
  /* calculate total width and max-height */
97 98 99 100
  double total_width  = 0;
  double total_height = 0;
  double max_height   = 0;
  double max_width    = 0;
Moritz Lipp's avatar
Moritz Lipp committed
101

102
  unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
103
  for (unsigned int page_id = 0; page_id < pages_per_row; page_id++) {
104
    if (page_id == number_of_pages) {
Moritz Lipp's avatar
Moritz Lipp committed
105 106 107
      break;
    }

108
    zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
Moritz Lipp's avatar
Moritz Lipp committed
109
    if (page == NULL) {
110
      goto error_ret;
Moritz Lipp's avatar
Moritz Lipp committed
111 112
    }

113 114 115 116 117 118 119 120 121
    unsigned int page_height = zathura_page_get_height(page);
    unsigned int page_width  = zathura_page_get_width(page);

    if (page_height > max_height) {
      max_height = page_height;
    }

    if (page_width > max_width) {
      max_width = page_width;
Moritz Lipp's avatar
Moritz Lipp committed
122 123
    }

124 125
    total_width  += page_width;
    total_height += page_height;
Moritz Lipp's avatar
Moritz Lipp committed
126 127
  }

128
  unsigned int rotation = zathura_document_get_rotation(zathura->document);
129
  double page_ratio     = max_height / total_width;
Moritz Lipp's avatar
Moritz Lipp committed
130 131 132
  double window_ratio   = height / width;

  if (rotation == 90 || rotation == 270) {
133
    page_ratio = max_width / total_height;
Moritz Lipp's avatar
Moritz Lipp committed
134 135
  }

136 137 138 139 140 141 142 143 144
  switch (argument->n) {
    case ZATHURA_ADJUST_WIDTH:
      if (rotation == 0 || rotation == 180) {
        zathura_document_set_scale(zathura->document, width / total_width);
      } else {
        zathura_document_set_scale(zathura->document, width / total_height);
      }
      break;
    case ZATHURA_ADJUST_BESTFIT:
Moritz Lipp's avatar
Moritz Lipp committed
145
      if (rotation == 0 || rotation == 180) {
Moritz Lipp's avatar
Moritz Lipp committed
146
        if (page_ratio < window_ratio) {
Moritz Lipp's avatar
Moritz Lipp committed
147
          zathura_document_set_scale(zathura->document, width / total_width);
148
        } else {
149
          zathura_document_set_scale(zathura->document, height / max_height);
150 151
        }
      } else {
Moritz Lipp's avatar
Moritz Lipp committed
152
        if (page_ratio < window_ratio) {
Moritz Lipp's avatar
Moritz Lipp committed
153
          zathura_document_set_scale(zathura->document, width / total_height);
154
        } else {
155
          zathura_document_set_scale(zathura->document, height / max_width);
156 157 158 159 160
        }
      }
      break;
    default:
      goto error_ret;
Moritz Lipp's avatar
Moritz Lipp committed
161 162
  }

163
  /* keep position */
164
  readjust_view_after_zooming(zathura, old_zoom, false);
165

Moritz Lipp's avatar
Moritz Lipp committed
166 167 168 169
  /* re-render all pages */
  render_all(zathura);

error_ret:
Moritz Lipp's avatar
Moritz Lipp committed
170

171
  return false;
172 173
}

Moritz Lipp's avatar
Moritz Lipp committed
174
bool
Moritz Lipp's avatar
Moritz Lipp committed
175 176
sc_change_mode(girara_session_t* session, girara_argument_t* argument,
    girara_event_t* UNUSED(event), unsigned int UNUSED(t))
177
{
Moritz Lipp's avatar
Moritz Lipp committed
178 179 180 181
  g_return_val_if_fail(session != NULL, false);

  girara_mode_set(session, argument->n);

Moritz Lipp's avatar
Moritz Lipp committed
182
  return false;
183 184
}

185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
bool
sc_focus_inputbar(girara_session_t* session, girara_argument_t* argument, girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->gtk.inputbar_entry != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);

  if (gtk_widget_get_visible(GTK_WIDGET(session->gtk.inputbar)) == false) {
    gtk_widget_show(GTK_WIDGET(session->gtk.inputbar));
  }

  if (gtk_widget_get_visible(GTK_WIDGET(session->gtk.notification_area)) == true) {
    gtk_widget_hide(GTK_WIDGET(session->gtk.notification_area));
  }

  gtk_widget_grab_focus(GTK_WIDGET(session->gtk.inputbar_entry));

  if (argument->data != NULL) {
    gtk_entry_set_text(session->gtk.inputbar_entry, (char*) argument->data);

    /* append filepath */
    if (argument->n == APPEND_FILEPATH && zathura->document != NULL) {
209 210 211 212
      const char* file_path = zathura_document_get_path(zathura->document);
      if (file_path == NULL) {
        return false;
      }
213

214 215 216 217 218
      char* path = g_path_get_dirname(file_path);
      char* escaped = girara_escape_string(path);
      char* tmp  = g_strdup_printf("%s%s/", (char*) argument->data, (g_strcmp0(path, "/") == 0) ? "" : escaped);
      g_free(path);
      g_free(escaped);
219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238

      gtk_entry_set_text(session->gtk.inputbar_entry, tmp);
      g_free(tmp);
    }

    /* we save the X clipboard that will be clear by "grab_focus" */
    gchar* x_clipboard_text = gtk_clipboard_wait_for_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY));

    gtk_editable_set_position(GTK_EDITABLE(session->gtk.inputbar_entry), -1);

    if (x_clipboard_text != NULL) {
      /* we reset the X clipboard with saved text */
      gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), x_clipboard_text, -1);
      g_free(x_clipboard_text);
    }
  }

  return true;
}

Moritz Lipp's avatar
Moritz Lipp committed
239
bool
240
sc_follow(girara_session_t* session, girara_argument_t* UNUSED(argument),
Moritz Lipp's avatar
Moritz Lipp committed
241
    girara_event_t* UNUSED(event), unsigned int UNUSED(t))
242
{
Moritz Lipp's avatar
Moritz Lipp committed
243
  g_return_val_if_fail(session != NULL, false);
244 245 246
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

Moritz Lipp's avatar
Moritz Lipp committed
247
  if (zathura->document == NULL || zathura->ui.session == NULL) {
248 249 250
    return false;
  }

Moritz Lipp's avatar
Moritz Lipp committed
251
  /* set pages to draw links */
Moritz Lipp's avatar
Moritz Lipp committed
252
  bool show_links = false;
Moritz Lipp's avatar
Moritz Lipp committed
253
  unsigned int page_offset = 0;
254 255 256
  unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
  for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) {
    zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
257 258 259 260
    if (page == NULL) {
      continue;
    }

261
    GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
Moritz Lipp's avatar
Moritz Lipp committed
262 263 264
    g_object_set(page_widget, "search-results", NULL, NULL);
    if (zathura_page_get_visibility(page) == true) {
      g_object_set(page_widget, "draw-links", TRUE, NULL);
265

Moritz Lipp's avatar
Moritz Lipp committed
266
      int number_of_links = 0;
Moritz Lipp's avatar
Moritz Lipp committed
267
      g_object_get(page_widget, "number-of-links", &number_of_links, NULL);
Moritz Lipp's avatar
Moritz Lipp committed
268 269 270
      if (number_of_links != 0) {
        show_links = true;
      }
Moritz Lipp's avatar
Moritz Lipp committed
271
      g_object_set(page_widget, "offset-links", page_offset, NULL);
Moritz Lipp's avatar
Moritz Lipp committed
272
      page_offset += number_of_links;
Moritz Lipp's avatar
Moritz Lipp committed
273
    } else {
Moritz Lipp's avatar
Moritz Lipp committed
274
      g_object_set(page_widget, "draw-links", FALSE, NULL);
275 276 277
    }
  }

Moritz Lipp's avatar
Moritz Lipp committed
278
  /* ask for input */
Moritz Lipp's avatar
Moritz Lipp committed
279
  if (show_links == true) {
Moritz Lipp's avatar
Moritz Lipp committed
280
    girara_dialog(zathura->ui.session, "Follow link:", FALSE, NULL, (girara_callback_inputbar_activate_t) cb_sc_follow, zathura->ui.session);
Moritz Lipp's avatar
Moritz Lipp committed
281
  }
Moritz Lipp's avatar
Moritz Lipp committed
282

Moritz Lipp's avatar
Moritz Lipp committed
283 284
  return false;
}
285

Moritz Lipp's avatar
Moritz Lipp committed
286
bool
Moritz Lipp's avatar
Moritz Lipp committed
287
sc_goto(girara_session_t* session, girara_argument_t* argument, girara_event_t* UNUSED(event), unsigned int t)
Moritz Lipp's avatar
Moritz Lipp committed
288
{
Moritz Lipp's avatar
Moritz Lipp committed
289 290 291 292 293
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(zathura->document != NULL, false);
294

295
  zathura_jumplist_save(zathura);
Moritz Lipp's avatar
Moritz Lipp committed
296
  if (t != 0) {
297
    /* add offset */
298
    unsigned int page_offset = zathura_document_get_page_offset(zathura->document);
299 300
    if (page_offset > 0) {
      t += page_offset;
301 302
    }

303
    page_set(zathura, t-1);
Moritz Lipp's avatar
Moritz Lipp committed
304
  } else if (argument->n == TOP) {
Moritz Lipp's avatar
Moritz Lipp committed
305
    page_set(zathura, 0);
Moritz Lipp's avatar
Moritz Lipp committed
306
  } else if (argument->n == BOTTOM) {
307
    page_set(zathura, zathura_document_get_number_of_pages(zathura->document) - 1);
308 309
  }

310 311
  zathura_jumplist_add(zathura);

Moritz Lipp's avatar
Moritz Lipp committed
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327
  return false;
}

bool
sc_mouse_scroll(girara_session_t* session, girara_argument_t* argument, girara_event_t* event, unsigned int t)
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(event != NULL, false);

  if (zathura->document == NULL) {
    return false;
  }

Moritz Lipp's avatar
Moritz Lipp committed
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
  static int x = 0;
  static int y = 0;

  GtkAdjustment* x_adj = NULL;
  GtkAdjustment* y_adj = NULL;

  switch (event->type) {
    /* scroll */
    case GIRARA_EVENT_SCROLL_UP:
    case GIRARA_EVENT_SCROLL_DOWN:
    case GIRARA_EVENT_SCROLL_LEFT:
    case GIRARA_EVENT_SCROLL_RIGHT:
      return sc_scroll(session, argument, NULL, t);

    /* drag */
    case GIRARA_EVENT_BUTTON_PRESS:
      x = event->x;
      y = event->y;
      break;
    case GIRARA_EVENT_BUTTON_RELEASE:
      x = 0;
      y = 0;
      break;
    case GIRARA_EVENT_MOTION_NOTIFY:
      x_adj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
353
      y_adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
Moritz Lipp's avatar
Moritz Lipp committed
354 355 356 357

      if (x_adj == NULL || y_adj == NULL) {
        return false;
      }
Moritz Lipp's avatar
Moritz Lipp committed
358

Moritz Lipp's avatar
Moritz Lipp committed
359 360 361 362 363 364 365
      set_adjustment(x_adj, gtk_adjustment_get_value(x_adj) - (event->x - x));
      set_adjustment(y_adj, gtk_adjustment_get_value(y_adj) - (event->y - y));
      break;

    /* unhandled events */
    default:
      break;
Moritz Lipp's avatar
Moritz Lipp committed
366 367
  }

Moritz Lipp's avatar
Moritz Lipp committed
368
  return false;
369 370
}

Moritz Lipp's avatar
Moritz Lipp committed
371 372 373 374 375 376 377 378 379 380 381 382 383 384
bool
sc_mouse_zoom(girara_session_t* session, girara_argument_t* argument, girara_event_t* event, unsigned int t)
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(event != NULL, false);

  if (zathura->document == NULL) {
    return false;
  }

  /* scroll event */
385 386 387 388 389 390 391 392 393
  switch (event->type) {
    case GIRARA_EVENT_SCROLL_UP:
      argument->n = ZOOM_IN;
      break;
    case GIRARA_EVENT_SCROLL_DOWN:
      argument->n = ZOOM_OUT;
      break;
    default:
      return false;
Moritz Lipp's avatar
Moritz Lipp committed
394 395
  }

396
  return sc_zoom(session, argument, NULL, t);
397 398
}

Moritz Lipp's avatar
Moritz Lipp committed
399
bool
Moritz Lipp's avatar
Moritz Lipp committed
400 401
sc_navigate(girara_session_t* session, girara_argument_t* argument,
    girara_event_t* UNUSED(event), unsigned int t)
402
{
Moritz Lipp's avatar
Moritz Lipp committed
403 404 405 406 407
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(zathura->document != NULL, false);
Moritz Lipp's avatar
Moritz Lipp committed
408

409 410
  int number_of_pages = zathura_document_get_number_of_pages(zathura->document);
  int new_page        = zathura_document_get_current_page_number(zathura->document);
Moritz Lipp's avatar
Moritz Lipp committed
411

412 413 414
  bool scroll_wrap = false;
  girara_setting_get(session, "scroll-wrap", &scroll_wrap);

415 416 417 418 419 420 421 422
  bool columns_per_row_offset = false;
  girara_setting_get(session, "advance-pages-per-row", &columns_per_row_offset);

  int offset = 1;
  if (columns_per_row_offset == true) {
    girara_setting_get(session, "pages-per-row", &offset);
  }

Moritz Lipp's avatar
Moritz Lipp committed
423
  t = (t == 0) ? (unsigned int) offset : t;
Moritz Lipp's avatar
Moritz Lipp committed
424
  if (argument->n == NEXT) {
425 426 427 428 429
    if (scroll_wrap == true) {
      new_page = new_page + t;
    } else {
      new_page = (new_page + t) % number_of_pages;
    }
Moritz Lipp's avatar
Moritz Lipp committed
430
  } else if (argument->n == PREVIOUS) {
431 432 433 434 435 436 437 438 439
    if (scroll_wrap == true) {
      new_page = new_page - t;
    } else {
      new_page = (new_page + number_of_pages - t) % number_of_pages;
    }
  }

  if (scroll_wrap == true && (new_page < 0 || new_page >= number_of_pages)) {
    return false;
Moritz Lipp's avatar
Moritz Lipp committed
440 441
  }

442
  page_set(zathura, new_page);
Moritz Lipp's avatar
Moritz Lipp committed
443

Moritz Lipp's avatar
Moritz Lipp committed
444
  return false;
445 446
}

Moritz Lipp's avatar
Moritz Lipp committed
447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464
bool
sc_print(girara_session_t* session, girara_argument_t* UNUSED(argument),
    girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

  if (zathura->document == NULL) {
    girara_notify(session, GIRARA_ERROR, _("No document opened."));
    return false;
  }

  print(zathura);

  return true;
}

Moritz Lipp's avatar
Moritz Lipp committed
465
bool
466
sc_recolor(girara_session_t* session, girara_argument_t* UNUSED(argument),
Moritz Lipp's avatar
Moritz Lipp committed
467
    girara_event_t* UNUSED(event), unsigned int UNUSED(t))
468
{
Moritz Lipp's avatar
Moritz Lipp committed
469
  g_return_val_if_fail(session != NULL, false);
Moritz Lipp's avatar
Moritz Lipp committed
470

Moritz Lipp's avatar
Moritz Lipp committed
471 472 473 474
  bool value = false;
  girara_setting_get(session, "recolor", &value);
  value = !value;
  girara_setting_set(session, "recolor", &value);
Moritz Lipp's avatar
Moritz Lipp committed
475

Moritz Lipp's avatar
Moritz Lipp committed
476
  return false;
477 478
}

Moritz Lipp's avatar
Moritz Lipp committed
479
bool
480
sc_reload(girara_session_t* session, girara_argument_t* UNUSED(argument),
Moritz Lipp's avatar
Moritz Lipp committed
481
    girara_event_t* UNUSED(event), unsigned int UNUSED(t))
482
{
Moritz Lipp's avatar
Moritz Lipp committed
483
  g_return_val_if_fail(session != NULL, false);
Moritz Lipp's avatar
Moritz Lipp committed
484 485 486
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;

Moritz Lipp's avatar
Moritz Lipp committed
487
  if (zathura->file_monitor.file_path == NULL) {
Moritz Lipp's avatar
Moritz Lipp committed
488 489 490 491
    return false;
  }

  /* close current document */
Moritz Lipp's avatar
Moritz Lipp committed
492
  document_close(zathura, true);
Moritz Lipp's avatar
Moritz Lipp committed
493 494

  /* reopen document */
Moritz Lipp's avatar
Moritz Lipp committed
495
  document_open(zathura, zathura->file_monitor.file_path, zathura->file_monitor.password);
Moritz Lipp's avatar
Moritz Lipp committed
496

Moritz Lipp's avatar
Moritz Lipp committed
497
  return false;
498 499
}

Moritz Lipp's avatar
Moritz Lipp committed
500
bool
501
sc_rotate(girara_session_t* session, girara_argument_t* argument,
Moritz Lipp's avatar
Moritz Lipp committed
502
    girara_event_t* UNUSED(event), unsigned int t)
503
{
Moritz Lipp's avatar
Moritz Lipp committed
504 505 506 507
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(zathura->document != NULL, false);
Moritz Lipp's avatar
Moritz Lipp committed
508

509
  unsigned int page_number = zathura_document_get_current_page_number(zathura->document);
510

511 512 513 514 515
  int angle = 90;
  if (argument != NULL && argument->n == ROTATE_CCW) {
    angle = 270;
  }

Moritz Lipp's avatar
Moritz Lipp committed
516
  /* update rotate value */
Moritz Lipp's avatar
Moritz Lipp committed
517
  t = (t == 0) ? 1 : t;
518
  unsigned int rotation = zathura_document_get_rotation(zathura->document);
Moritz Lipp's avatar
Moritz Lipp committed
519
  zathura_document_set_rotation(zathura->document, (rotation + angle * t) % 360);
Moritz Lipp's avatar
Moritz Lipp committed
520

521 522 523 524
  /* update scale */
  girara_argument_t new_argument = { zathura_document_get_adjust_mode(zathura->document), NULL };
  sc_adjust_window(zathura->ui.session, &new_argument, NULL, 0);

Moritz Lipp's avatar
Moritz Lipp committed
525
  /* render all pages again */
526
  render_all(zathura);
Moritz Lipp's avatar
Moritz Lipp committed
527

528 529
  page_set_delayed(zathura, page_number);

Moritz Lipp's avatar
Moritz Lipp committed
530
  return false;
531 532
}

Moritz Lipp's avatar
Moritz Lipp committed
533
bool
Moritz Lipp's avatar
Moritz Lipp committed
534 535
sc_scroll(girara_session_t* session, girara_argument_t* argument,
    girara_event_t* UNUSED(event), unsigned int UNUSED(t))
536
{
Moritz Lipp's avatar
Moritz Lipp committed
537 538 539 540
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
541 542 543
  if (zathura->document == NULL) {
    return false;
  }
Moritz Lipp's avatar
Moritz Lipp committed
544

Moritz Lipp's avatar
Moritz Lipp committed
545
  GtkAdjustment* adjustment = NULL;
546
  if ( (argument->n == LEFT) || (argument->n == FULL_LEFT) || (argument->n == HALF_LEFT) ||
Moritz Lipp's avatar
Moritz Lipp committed
547
  (argument->n == RIGHT) || (argument->n == FULL_RIGHT) || (argument->n == HALF_RIGHT)) {
Moritz Lipp's avatar
Moritz Lipp committed
548
    adjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
Moritz Lipp's avatar
Moritz Lipp committed
549
  } else {
Moritz Lipp's avatar
Moritz Lipp committed
550
    adjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
Moritz Lipp's avatar
Moritz Lipp committed
551
  }
Moritz Lipp's avatar
Moritz Lipp committed
552

553 554 555
  gdouble view_size                  = gtk_adjustment_get_page_size(adjustment);
  gdouble value                      = gtk_adjustment_get_value(adjustment);
  gdouble max                        = gtk_adjustment_get_upper(adjustment) - view_size;
556
  zathura->global.update_page_number = true;
557

558 559
  float scroll_step = 40;
  girara_setting_get(session, "scroll-step", &scroll_step);
Julian Orth's avatar
Julian Orth committed
560 561 562 563 564
  float scroll_hstep = -1;
  girara_setting_get(session, "scroll-hstep", &scroll_hstep);
  if (scroll_hstep < 0) {
    scroll_hstep = scroll_step;
  }
565
  float scroll_full_overlap = 0.0;
566
  girara_setting_get(session, "scroll-full-overlap", &scroll_full_overlap);
567 568
  bool scroll_page_aware = false;
  girara_setting_get(session, "scroll-page-aware", &scroll_page_aware);
569

570 571 572
  int padding = 1;
  girara_setting_get(session, "page-padding", &padding);

573
  gdouble new_value;
Moritz Lipp's avatar
Moritz Lipp committed
574

Moritz Lipp's avatar
Moritz Lipp committed
575
  switch(argument->n) {
Moritz Lipp's avatar
Moritz Lipp committed
576
    case FULL_UP:
577
    case FULL_LEFT:
578
      new_value = value - (1.0 - scroll_full_overlap) * view_size - padding;
Moritz Lipp's avatar
Moritz Lipp committed
579 580
      break;
    case FULL_DOWN:
581
    case FULL_RIGHT:
582
      new_value = value + (1.0 - scroll_full_overlap) * view_size + padding;
Moritz Lipp's avatar
Moritz Lipp committed
583 584
      break;
    case HALF_UP:
585
    case HALF_LEFT:
586
      new_value = value - ((view_size + padding) / 2);
Moritz Lipp's avatar
Moritz Lipp committed
587 588
      break;
    case HALF_DOWN:
589
    case HALF_RIGHT:
590
      new_value = value + ((view_size + padding) / 2);
Moritz Lipp's avatar
Moritz Lipp committed
591 592
      break;
    case LEFT:
Julian Orth's avatar
Julian Orth committed
593 594
      new_value = value - scroll_hstep;
      break;
Moritz Lipp's avatar
Moritz Lipp committed
595
    case UP:
596
      new_value = value - scroll_step;
Moritz Lipp's avatar
Moritz Lipp committed
597 598
      break;
    case RIGHT:
Julian Orth's avatar
Julian Orth committed
599 600
      new_value = value + scroll_hstep;
      break;
Moritz Lipp's avatar
Moritz Lipp committed
601
    case DOWN:
602
      new_value = value + scroll_step;
Moritz Lipp's avatar
Moritz Lipp committed
603 604 605 606 607 608 609 610
      break;
    case TOP:
      new_value = 0;
      break;
    case BOTTOM:
      new_value = max;
      break;
    default:
Moritz Lipp's avatar
Moritz Lipp committed
611
      new_value = value;
Moritz Lipp's avatar
Moritz Lipp committed
612 613
  }

Sebastian Ramacher's avatar
CS  
Sebastian Ramacher committed
614
  if (scroll_page_aware == true) {
615 616 617 618 619 620 621 622 623 624 625
    int page_offset;
    double page_size;

    {
      unsigned int page_id = zathura_document_get_current_page_number(zathura->document);
      zathura_page_t* page = zathura_document_get_page(zathura->document, page_id);
      page_offset_t offset;
      page_calculate_offset(zathura, page, &offset);

      double scale = zathura_document_get_scale(zathura->document);

Sebastian Ramacher's avatar
CS  
Sebastian Ramacher committed
626 627
      if ((argument->n == LEFT) || (argument->n == FULL_LEFT) || (argument->n == HALF_LEFT) ||
          (argument->n == RIGHT) || (argument->n == FULL_RIGHT) || (argument->n == HALF_RIGHT)) {
628 629 630 631 632 633 634 635 636 637
        page_offset = offset.x;
        page_size = zathura_page_get_width(page) * scale;
      } else {
        page_offset = offset.y;
        page_size = zathura_page_get_height(page) * scale;
      }

      page_offset -= padding / 2;
      page_size   += padding;
    }
Sebastian Ramacher's avatar
CS  
Sebastian Ramacher committed
638 639 640 641 642

    if ((argument->n == FULL_DOWN) || (argument->n == HALF_DOWN) ||
        (argument->n == FULL_RIGHT) || (argument->n == HALF_RIGHT)) {
      if ((page_offset > value) &&
          (page_offset < value + view_size)) {
643
        new_value = page_offset;
Sebastian Ramacher's avatar
CS  
Sebastian Ramacher committed
644 645
      } else if ((page_offset <= value) &&
                 (page_offset + page_size < value + view_size)) {
646
        new_value = page_offset + page_size + 1;
Sebastian Ramacher's avatar
CS  
Sebastian Ramacher committed
647 648
      } else if ((page_offset <= value) &&
                 (page_offset + page_size < new_value + view_size)) {
649 650
        new_value = page_offset + page_size - view_size + 1;
      }
Sebastian Ramacher's avatar
CS  
Sebastian Ramacher committed
651 652 653 654
    } else if ((argument->n == FULL_UP) || (argument->n == HALF_UP) ||
               (argument->n == FULL_LEFT) || (argument->n == HALF_LEFT)) {
      if ((page_offset + 1 >= value) &&
          (page_offset < value + view_size)) {
655
        new_value = page_offset - view_size;
Sebastian Ramacher's avatar
CS  
Sebastian Ramacher committed
656 657
      } else if ((page_offset <= value) &&
                 (page_offset + page_size + 1 < value + view_size)) {
658
        new_value = page_offset + page_size - view_size;
Sebastian Ramacher's avatar
CS  
Sebastian Ramacher committed
659 660
      } else if ((page_offset <= value) &&
                 (page_offset > new_value)) {
661 662
        new_value = page_offset;
      }
Sebastian Ramacher's avatar
CS  
Sebastian Ramacher committed
663
    }
664 665
  }

666
  set_adjustment(adjustment, new_value);
Moritz Lipp's avatar
Moritz Lipp committed
667

Moritz Lipp's avatar
Moritz Lipp committed
668
  return false;
669 670
}

671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695

bool
sc_jumplist(girara_session_t* session, girara_argument_t* argument, girara_event_t* UNUSED(event), unsigned int UNUSED(t))
{
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(zathura->document != NULL, false);

  zathura_jump_t* jump = NULL;
  switch(argument->n) {
    case FORWARD:
      zathura_jumplist_save(zathura);
      zathura_jumplist_forward(zathura);
      jump = zathura_jumplist_current(zathura);
      break;

    case BACKWARD:
      zathura_jumplist_save(zathura);
      zathura_jumplist_backward(zathura);
      jump = zathura_jumplist_current(zathura);
      break;
  }

696 697 698 699 700
  if (jump != NULL) {
    page_set(zathura, jump->page);
    const double s = zathura_document_get_scale(zathura->document);
    position_set_delayed(zathura, jump->x * s, jump->y * s);
  }
701 702 703 704

  return false;
}

Moritz Lipp's avatar
Moritz Lipp committed
705
bool
Moritz Lipp's avatar
Moritz Lipp committed
706 707
sc_search(girara_session_t* session, girara_argument_t* argument,
    girara_event_t* UNUSED(event), unsigned int UNUSED(t))
708
{
Moritz Lipp's avatar
Moritz Lipp committed
709 710 711 712 713
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(zathura->document != NULL, false);
Moritz Lipp's avatar
Moritz Lipp committed
714

715 716
  const int num_pages = zathura_document_get_number_of_pages(zathura->document);
  const int cur_page  = zathura_document_get_current_page_number(zathura->document);
717 718
  int diff = argument->n == FORWARD ? 1 : -1;

Sebastian Ramacher's avatar
Sebastian Ramacher committed
719 720 721
  zathura_page_t* target_page = NULL;
  int target_idx = 0;

722 723
  for (int page_id = 0; page_id < num_pages; ++page_id) {
    int tmp = cur_page + diff * page_id;
724
    zathura_page_t* page = zathura_document_get_page(zathura->document, (tmp + num_pages) % num_pages);
725 726 727 728
    if (page == NULL) {
      continue;
    }

729
    GtkWidget* page_widget = zathura_page_get_widget(zathura, page);
Moritz Lipp's avatar
Moritz Lipp committed
730

731
    int num_search_results = 0, current = -1;
Moritz Lipp's avatar
Moritz Lipp committed
732
    g_object_get(page_widget, "search-current", &current,
733 734 735 736 737 738 739
        "search-length", &num_search_results, NULL);
    if (num_search_results == 0 || current == -1) {
      continue;
    }

    if (diff == 1 && current < num_search_results - 1) {
      /* the next result is on the same page */
Sebastian Ramacher's avatar
Sebastian Ramacher committed
740 741
      target_page = page;
      target_idx = current + 1;
742
    } else if (diff == -1 && current > 0) {
Sebastian Ramacher's avatar
Sebastian Ramacher committed
743 744
      target_page = page;
      target_idx = current - 1;
745 746
    } else {
      /* the next result is on a different page */
747 748
      zathura_jumplist_save(zathura);

Moritz Lipp's avatar
Moritz Lipp committed
749
      g_object_set(page_widget, "search-current", -1, NULL);
750 751 752

      for (int npage_id = 1; page_id < num_pages; ++npage_id) {
        int ntmp = cur_page + diff * (page_id + npage_id);
753 754
        zathura_page_t* npage = zathura_document_get_page(zathura->document, (ntmp + 2*num_pages) % num_pages);
        zathura_document_set_current_page_number(zathura->document, zathura_page_get_index(npage));
755
        GtkWidget* npage_page_widget = zathura_page_get_widget(zathura, npage);
Moritz Lipp's avatar
Moritz Lipp committed
756
        g_object_get(npage_page_widget, "search-length", &num_search_results, NULL);
757
        if (num_search_results != 0) {
Sebastian Ramacher's avatar
Sebastian Ramacher committed
758 759
          target_page = npage;
          target_idx = diff == 1 ? 0 : num_search_results - 1;
760 761 762
          break;
        }
      }
763 764

      zathura_jumplist_add(zathura);
765
    }
766

767 768
    break;
  }
Moritz Lipp's avatar
Moritz Lipp committed
769

Sebastian Ramacher's avatar
Sebastian Ramacher committed
770 771
  if (target_page != NULL) {
    girara_list_t* results = NULL;
772
    GtkWidget* page_widget = zathura_page_get_widget(zathura, target_page);
Moritz Lipp's avatar
Moritz Lipp committed
773 774
    g_object_set(page_widget, "search-current", target_idx, NULL);
    g_object_get(page_widget, "search-results", &results, NULL);
Sebastian Ramacher's avatar
Sebastian Ramacher committed
775 776 777 778

    zathura_rectangle_t* rect = girara_list_nth(results, target_idx);
    zathura_rectangle_t rectangle = recalc_rectangle(target_page, *rect);
    page_offset_t offset;
779
    page_calculate_offset(zathura, target_page, &offset);
Sebastian Ramacher's avatar
Sebastian Ramacher committed
780 781 782

    GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
    int y = offset.y - gtk_adjustment_get_page_size(view_vadjustment) / 2 + rectangle.y1;
783
    set_adjustment(view_vadjustment, y);
Julian Orth's avatar
Julian Orth committed
784 785 786 787 788 789 790 791

    bool search_hadjust = true;
    girara_setting_get(session, "search-hadjust", &search_hadjust);
    if (search_hadjust == true) {
      GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
      int x = offset.x - gtk_adjustment_get_page_size(view_hadjustment) / 2 + rectangle.x1;
      set_adjustment(view_hadjustment, x);
    }
Sebastian Ramacher's avatar
Sebastian Ramacher committed
792 793
  }

Moritz Lipp's avatar
Moritz Lipp committed
794
  return false;
795 796
}

Moritz Lipp's avatar
Moritz Lipp committed
797
bool
798
sc_navigate_index(girara_session_t* session, girara_argument_t* argument,
Moritz Lipp's avatar
Moritz Lipp committed
799
    girara_event_t* UNUSED(event), unsigned int UNUSED(t))
800
{
Moritz Lipp's avatar
Moritz Lipp committed
801 802 803 804 805 806
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
  g_return_val_if_fail(argument != NULL, false);
  g_return_val_if_fail(zathura->document != NULL, false);

Moritz Lipp's avatar
Moritz Lipp committed
807 808 809 810 811 812 813 814
  if(zathura->ui.index == NULL) {
    return false;
  }

  GtkTreeView *tree_view = gtk_container_get_children(GTK_CONTAINER(zathura->ui.index))->data;
  GtkTreePath *path;

  gtk_tree_view_get_cursor(tree_view, &path, NULL);
Moritz Lipp's avatar
Moritz Lipp committed
815
  if (path == NULL) {
Moritz Lipp's avatar
Moritz Lipp committed
816 817 818 819 820 821 822 823 824 825 826
    return false;
  }

  GtkTreeModel *model = gtk_tree_view_get_model(tree_view);
  GtkTreeIter   iter;
  GtkTreeIter   child_iter;

  gboolean is_valid_path = TRUE;

  switch(argument->n) {
    case UP:
827
      if (gtk_tree_path_prev(path) == FALSE) {
828 829 830
        /* For some reason gtk_tree_path_up returns TRUE although we're not
         * moving anywhere. */
        is_valid_path = gtk_tree_path_up(path) && (gtk_tree_path_get_depth(path) > 0);
Moritz Lipp's avatar
Moritz Lipp committed
831 832 833 834 835 836 837 838 839 840 841 842
      } else { /* row above */
        while(gtk_tree_view_row_expanded(tree_view, path)) {
          gtk_tree_model_get_iter(model, &iter, path);
          /* select last child */
          gtk_tree_model_iter_nth_child(model, &child_iter, &iter,
            gtk_tree_model_iter_n_children(model, &iter)-1);
          gtk_tree_path_free(path);
          path = gtk_tree_model_get_path(model, &child_iter);
        }
      }
      break;
    case COLLAPSE:
843
      if (gtk_tree_view_collapse_row(tree_view, path) == FALSE
Moritz Lipp's avatar
Moritz Lipp committed
844 845 846 847 848 849
        && gtk_tree_path_get_depth(path) > 1) {
        gtk_tree_path_up(path);
        gtk_tree_view_collapse_row(tree_view, path);
      }
      break;
    case DOWN:
850
      if (gtk_tree_view_row_expanded(tree_view, path) == TRUE) {
Moritz Lipp's avatar
Moritz Lipp committed
851 852 853 854 855 856 857 858 859 860 861 862 863
        gtk_tree_path_down(path);
      } else {
        do {
          gtk_tree_model_get_iter(model, &iter, path);
          if (gtk_tree_model_iter_next(model, &iter)) {
            path = gtk_tree_model_get_path(model, &iter);
            break;
          }
        } while((is_valid_path = (gtk_tree_path_get_depth(path) > 1))
          && gtk_tree_path_up(path));
      }
      break;
    case EXPAND:
864
      if (gtk_tree_view_expand_row(tree_view, path, FALSE)) {
Moritz Lipp's avatar
Moritz Lipp committed
865 866 867
        gtk_tree_path_down(path);
      }
      break;
868 869 870 871 872 873 874 875 876
    case EXPAND_ALL:
      gtk_tree_view_expand_all(tree_view);
      break;
    case COLLAPSE_ALL:
      gtk_tree_view_collapse_all(tree_view);
      gtk_tree_path_free(path);
      path = gtk_tree_path_new_first();
      gtk_tree_view_set_cursor(tree_view, path, NULL, FALSE);
      break;
Moritz Lipp's avatar
Moritz Lipp committed
877 878
    case SELECT:
      cb_index_row_activated(tree_view, path, NULL, zathura);
879

Moritz Lipp's avatar
Moritz Lipp committed
880 881 882 883 884 885 886 887 888
      return false;
  }

  if (is_valid_path) {
    gtk_tree_view_set_cursor(tree_view, path, NULL, FALSE);
  }

  gtk_tree_path_free(path);

Moritz Lipp's avatar
Moritz Lipp committed
889
  return false;
890 891
}

Moritz Lipp's avatar
Moritz Lipp committed
892
bool
893
sc_toggle_index(girara_session_t* session, girara_argument_t* UNUSED(argument),
Moritz Lipp's avatar
Moritz Lipp committed
894
    girara_event_t* UNUSED(event), unsigned int UNUSED(t))
895
{
Moritz Lipp's avatar
Moritz Lipp committed
896 897 898
  g_return_val_if_fail(session != NULL, false);
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
899 900 901
  if (zathura->document == NULL) {
    return false;
  }
902 903 904 905 906

  girara_tree_node_t* document_index = NULL;
  GtkWidget* treeview                = NULL;
  GtkTreeModel* model                = NULL;
  GtkCellRenderer* renderer          = NULL;
907
  GtkCellRenderer* renderer2         = NULL;
908

909
  if (zathura->ui.index == NULL) {
910
    /* create new index widget */
911
    zathura->ui.index = gtk_scrolled_window_new(NULL, NULL);
912

913
    if (zathura->ui.index == NULL) {
914 915 916
      goto error_ret;
    }

917
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(zathura->ui.index),
918 919 920
      GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

    /* create index */
921
    document_index = zathura_document_index_generate(zathura->document, NULL);
922
    if (document_index == NULL) {
923
      girara_notify(session, GIRARA_WARNING, _("This document does not contain any index"));
924 925 926
      goto error_free;
    }

Sebastian Ramacher's avatar
Sebastian Ramacher committed
927
    model = GTK_TREE_MODEL(gtk_tree_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER));
928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943
    if (model == NULL) {
      goto error_free;
    }

    treeview = gtk_tree_view_new_with_model(model);
    if (treeview == NULL) {
      goto error_free;
    }

    g_object_unref(model);

    renderer = gtk_cell_renderer_text_new();
    if (renderer == NULL) {
      goto error_free;
    }

944 945 946 947 948
    renderer2 = gtk_cell_renderer_text_new();
    if (renderer2 == NULL) {
      goto error_free;
    }

949 950 951 952 953
    document_index_build(model, NULL, document_index);
    girara_node_free(document_index);

    /* setup widget */
    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (treeview), 0, "Title", renderer, "markup", 0, NULL);
954
    gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (treeview), 1, "Target", renderer2, "text", 1, NULL);
Sebastian Ramacher's avatar
Sebastian Ramacher committed
955

956 957 958
    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
    g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
    g_object_set(G_OBJECT(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 0)), "expand", TRUE, NULL);
959
    gtk_tree_view_column_set_alignment(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 1), 1.0f);
960
    gtk_tree_view_set_cursor(GTK_TREE_VIEW(treeview), gtk_tree_path_new_first(), NULL, FALSE);
961
    g_signal_connect(G_OBJECT(treeview), "row-activated", G_CALLBACK(cb_index_row_activated), zathura);
962

963
    gtk_container_add(GTK_CONTAINER(zathura->ui.index), treeview);
964 965 966
    gtk_widget_show(treeview);
  }

Moritz Lipp's avatar
Moritz Lipp committed
967 968 969
  static double vvalue = 0;
  static double hvalue = 0;

970
  if (gtk_widget_get_visible(GTK_WIDGET(zathura->ui.index))) {
971
    girara_set_view(session, zathura->ui.page_widget_alignment);
972
    gtk_widget_hide(GTK_WIDGET(zathura->ui.index));
973
    girara_mode_set(zathura->ui.session, zathura->modes.normal);
Moritz Lipp's avatar
Moritz Lipp committed
974 975

    /* reset adjustment */
976
    position_set_delayed(zathura, hvalue, vvalue);
977
  } else {
Moritz Lipp's avatar
Moritz Lipp committed
978
    /* save adjustment */
979 980 981
    GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));
    GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view));

Moritz Lipp's avatar
Moritz Lipp committed
982 983 984
    vvalue = gtk_adjustment_get_value(vadjustment);
    hvalue = gtk_adjustment_get_value(hadjustment);

985 986 987
    /* save current position to the jumplist */
    zathura_jumplist_save(zathura);

988 989
    girara_set_view(session, zathura->ui.index);
    gtk_widget_show(GTK_WIDGET(zathura->ui.index));
990
    girara_mode_set(zathura->ui.session, zathura->modes.index);
991 992 993 994 995 996
  }

  return false;

error_free:

997 998 999
  if (zathura->ui.index != NULL) {
    g_object_ref_sink(zathura->ui.index);
    zathura->ui.index = NULL;
1000 1001 1002 1003 1004
  }

  if (document_index != NULL) {
    girara_node_free(document_index);
  }
Moritz Lipp's avatar
Moritz Lipp committed
1005

1006 1007
error_ret:

Moritz Lipp's avatar
Moritz Lipp committed
1008
  return false;
1009 1010
}

Moritz Lipp's avatar
Moritz Lipp committed
1011
bool
1012
sc_toggle_fullscreen(girara_session_t* session, girara_argument_t*
Moritz Lipp's avatar
Moritz Lipp committed
1013
    UNUSED(argument), girara_event_t* UNUSED(event), unsigned int UNUSED(t))
1014
{
Moritz Lipp's avatar
Moritz Lipp committed
1015
  g_return_val_if_fail(session != NULL, false);
1016 1017
  g_return_val_if_fail(session->global.data != NULL, false);
  zathura_t* zathura = session->global.data;
1018

1019 1020 1021 1022 1023
  if (zathura->document == NULL) {
    girara_notify(session, GIRARA_WARNING, _("No document opened."));
    return false;
  }

1024
  static bool fullscreen = false;
Moritz Lipp's avatar
Moritz Lipp committed
1025
  static int pages_per_row = 1;
1026
  static int first_page_column = 1;
1027
  static double zoom = 1.0;
Moritz Lipp's avatar
Moritz Lipp committed
1028 1029 1030 1031 1032

  if (fullscreen == true) {
    /* reset pages per row */
    girara_setting_set(session, "pages-per-row", &pages_per_row);

1033 1034 1035
    /* reset first page column */
    girara_setting_set(session, "first-page-column", &first_page_column);

Moritz Lipp's avatar
Moritz Lipp committed
1036 1037 1038 1039
    /* show status bar */
    gtk_widget_show(GTK_WIDGET(session->gtk.statusbar));

    /* set full screen */
1040
    gtk_window_unfullscreen(GTK_WINDOW(session->gtk.window));
1041 1042

    /* reset scale */
1043
    zathura_document_set_scale(zathura->document, zoom);
1044
    render_all(zathura);
1045
    page_set_delayed(zathura, zathura_document_get_current_page_number(zathura->document));
1046
  } else {
Moritz Lipp's avatar
Moritz Lipp committed
1047
    /* backup pages per row */
1048
    girara_setting_get(session, "pages-per-row", &pages_per_row);
Moritz Lipp's avatar
Moritz Lipp committed
1049

1050 1051 1052
    /* backup first page column */
    girara_setting_get(session, "first-page-column", &first_page_column);

Moritz Lipp's avatar
Moritz Lipp committed
1053 1054 1055 1056
    /* set single view */
    int int_value = 1;
    girara_setting_set(session, "pages-per-row", &int_value);

1057
    /* back up zoom */
1058
    zoom = zathura_document_get_scale(zathura->document);
1059

Moritz Lipp's avatar
Moritz Lipp committed
1060
    /* adjust window */